Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

Construct and manage graphical, event-driven user interfaces for iOS or tvOS apps using UIKit.

UIKit Documentation

Posts under UIKit subtopic

Post

Replies

Boosts

Views

Activity

How to get UIFont to respect preferredContentSizeCategory in a Mac Catalyst app?
I have an iOS app that relies on dynamic text size such that all fonts in the app respect the user's setting of Text Size in the iOS Settings app. This app also runs on macOS via Mac Catalyst. But until macOS 14 Sonoma, there was no Text Size setting in the macOS Settings app. But even as of Sonoma, the Text Size setting isn't usable by 3rd party apps. And Sequoia doesn't seem to change that. As a work around, my Mac Catalyst app provides its own Text Size setting. I was able to make it work by providing my own UIApplication subclass and overriding preferredContentSizeCategory. Under macOS 12 to macOS 14, this workaround works just fine and all fonts in the app created with code such as UIFont.preferredFont(forTextStyle:) gives appropriately sized fonts based on the overridden content size category. However, this workaround stopped working with macOS 15 Sequoia. I've also tried code such as: self.window.traitOverrides.preferredContentSizeCategory = myCustomSizeCategoryValue and self.window.maximumContentSizeCategory = myCustomSizeCategoryValue self.window.minimumContentSizeCategory = myCustomSizeCategoryValue in the scene delegate but that made no difference. Is there any way to get code such as UIFont.preferredFont(forTextStyle:) to return an appropriately sized font based on some app provided content size category in a Mac Catalyst app running under macOS 15? It sure would be nice if Mac Catalyst apps automatically responded to the macOS Text Size setting under Settings -> Accessibility -> Display -> Text Size just like a native iOS app.
3
1
620
Apr ’25
Xcode UIKit Document App template crashes under Swift 6
I'm trying to switch to UIKit's document lifecycle due to serious bugs with SwiftUI's version. However I'm noticing the template project from Xcode isn't compatible with Swift 6 (I already migrated my app to Swift 6.). To reproduce: File -> New -> Project Select "Document App" under iOS Set "Interface: UIKit" In Build Settings, change Swift Language Version to Swift 6 Run app Tap "Create Document" Observe: crash in _dispatch_assert_queue_fail Does anyone know of a work around other than downgrading to Swift 5?
0
1
40
Apr ’25
Problems visualizing UIApplicationShortcutIcon with shortcuts
Hi Everybody, I am actually developing dynamic shortcuts for my app. I have a problem with the class UIApplicationShortcutIcon. When I pass a personalized icon in the parameter icon as a UIApplicationShortcutIcon(templateImageName: "nameOfTheAsset" I always visualize a black dot instead of my Icon. The icon is imported as .SVG file and rendered as a template. Sincerely I do not know what to do to solve this problem since the documentation is little. Hoping somebody can give some tips to solve the problem
1
0
28
Apr ’25
UIPasteControl Not Recognizing Tap
I have an iOS app where I'm trying to paste something previously copied to the user's UIPasteboard. I came across the UIPasteControl as an option for a user to tap to silently paste without having the prompt "Allow Paste" pop up. For some reason, despite having what seemingly is the correct configurations for the UIPasteControl, on testing a tap, nothing is called. I expected override func paste(itemProviders: [NSItemProvider]) to fire, but it does not. Any help would be appreciated as there doesn't seem to be much info anywhere regarding UIPasteControl. import UniformTypeIdentifiers class ViewController: UIViewController { private let pasteControl = UIPasteControl() override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .systemBackground pasteControl.target = self pasteConfiguration = UIPasteConfiguration(acceptableTypeIdentifiers: [ UTType.text.identifier, UTType.url.identifier, UTType.plainText.identifier ]) view.addSubview(pasteControl) pasteControl.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ pasteControl.centerXAnchor.constraint(equalTo: view.centerXAnchor), pasteControl.centerYAnchor.constraint(equalTo: view.centerYAnchor), ]) } } extension ViewController { override func paste(itemProviders: [NSItemProvider]) { for provider in itemProviders { if provider.hasItemConformingToTypeIdentifier(UTType.url.identifier) { provider.loadObject(ofClass: URL.self) { [weak self] reading, _ in guard let url = reading as? URL else { return } print(url) } } else if provider.hasItemConformingToTypeIdentifier(UTType.plainText.identifier) { provider.loadObject(ofClass: NSString.self) { [weak self] reading, _ in guard let nsstr = reading as? NSString else { return } let str = nsstr as String if let url = URL(string: str) { print(url) } } } } } }
2
0
59
Apr ’25
RealityView in UIHostingController/UIKit transparency
I'm experimenting with RealityView in the UI of an AUv3 plug-in. The plug-in UI is implemented in a UIKitViewController with a UIHostingController hosting a RealityView. When i run the standalone app on visionOS I want the background to be transparent, and the reality view content. how can i achieve that? I've tried turning off opaque in many views and and setting background colors to .clear.
1
0
34
Apr ’25
App Crashes on Paper Selection After Background Printer Connection
Description: When initiating the print flow via UIPrintInteractionController, and no printer is initially connected, iOS displays all possible paper sizes in the paper selection UI. However, if a printer connects in the background after this view is shown, the list of paper sizes does not automatically refresh to reflect only the options supported by the connected printer. If the user selects an incompatible paper size (one not supported by the printer that has just connected), the app crashes due to an invalid configuration. Steps to Reproduce: Launch the app and navigate to the print functionality. Tap the Print button to invoke UIPrintInteractionController. At this point, no printer is yet connected. iOS displays all available paper sizes. While the paper selection UI is visible, the AirPrint-compatible printer connects in the background. Without dismissing the controller, the user selects a paper size (e.g., one that is not supported by the printer). The app crashes. Expected Result: App should not crash Once the printer becomes available (connected in the background), the paper size options should refresh automatically. The list should be filtered to only include sizes that are compatible with the connected printer. This prevents the user from selecting an invalid option, avoiding crashes. Actual Result: App crashes The paper size list remains unfiltered. The user can still select unsupported paper sizes. Selecting an incompatible option causes the app to crash, due to a mismatch between UI selection and printer capability.
Topic: UI Frameworks SubTopic: UIKit
0
0
39
Apr ’25
How to detect iPad trackpad touch-down (indirectPointer) to immediately stop coasting animation
Hello, I have a custom 3D object viewer on iOS that lets users spin the model using the touchscreen or a trackpad and supports coasting (momentum spinning). I need to stop the coasting animation as soon as the user touches down, but I can only immediately detect touches on the screen itself - on the trackpad I can't get an immediate notification of the touches. So far I’ve tried: State.began on my UIPanGestureRecognizer. It only fires after a small movement on both touchscreen and trackpad. .possible on the pan gesture; this state never occurs during the gesture cycle. UIApplicationSupportsIndirectInputEvents = YES in Info.plist; it didn’t make touchesBegan fire for indirectPointer touches. Since UITableView (and other UIScrollView subclasses) clearly detect trackpad “touch-down” to cancel scrolling, there must be a way to receive that event. Does anyone know how to catch the initial trackpad contact—before any movement—on an indirect input device? Below is a minimal code snippet demonstrating the issue. On the touchscreen you'll see a message the moment you touch the view, but the trackpad doesn't trigger any messages until your fingers move. Any advice would be greatly appreciated. Thanks in advance, John import UIKit class ViewController: UIViewController { private let debugView = DebugView() override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white // Fill the screen with our debug view debugView.frame = view.bounds debugView.autoresizingMask = [.flexibleWidth, .flexibleHeight] debugView.backgroundColor = UIColor(white: 0.95, alpha: 1) view.addSubview(debugView) // Attach a pan recognizer that logs its state let panGR = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:))) panGR.allowedScrollTypesMask = .all debugView.addGestureRecognizer(panGR) } @objc private func handlePan(_ gr: UIPanGestureRecognizer) { switch gr.state { case .possible: print("Pan state: possible") case .began: print("Pan state: began") case .changed: print("Pan state: changed – translation = \(gr.translation(in: debugView))") case .ended: print("Pan state: ended – velocity = \(gr.velocity(in: debugView))") case .cancelled: print("Pan state: cancelled") case .failed: print("Pan state: failed") @unknown default: print("Pan state: unknown") } } } class DebugView: UIView { override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { super.touchesBegan(touches, with: event) for t in touches { let typeDesc: String switch t.type { case .direct: typeDesc = "direct (finger)" case .indirectPointer: typeDesc = "indirectPointer (trackpad/mouse)" case .indirect: typeDesc = "indirect (Apple TV remote)" case .pencil: typeDesc = "pencil (Apple Pencil)" @unknown default: typeDesc = "unknown" } print("touchesBegan on DebugView – touch type: \(typeDesc), location: \(t.location(in: self))") } } }
Topic: UI Frameworks SubTopic: UIKit Tags:
2
0
34
Apr ’25
Using the UIPasteControl
Hello 👋🏽 I am a new iOS developer and I am having a hard time understanding the behavior of the new UIPasteControl to avoid showing the system prompt. Does anyone has any example code I could look at to understand the behavior. Idk how to set the target of the button to the general pasteboard. also I am using objective-c . thanks cristian
5
0
4.0k
Apr ’25
How to make a UIButton resize its custom font text using `configurationUpdateHandler`?
I've read in this post that in order to make the configuration of UIButton adjust my custom font's size automatically I need to add implementation to recalculate the font's size inside configurationUpdateHandler. But how would this look like? I also read something about matching the font's text style. But at this point I'm just guessing. Here's the code: let loginButton = UIButton(configuration: config, primaryAction: nil) loginButton.configurationUpdateHandler = { button in guard var config = button.configuration else { return } let traits = button.traitCollection let baseTitleFont = UIFont.customFont(ofSize: 18, weight: .semibold) let baseSubtitleFont = UIFont.customFont(ofSize: 18, weight: .regular) let scaledTitleFont = UIFontMetrics(forTextStyle: .body).scaledFont(for: baseTitleFont, compatibleWith: traits) let scaledSubtitleFont = UIFontMetrics(forTextStyle: .body).scaledFont(for: baseSubtitleFont, compatibleWith: traits) config.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { incoming in var outgoing = incoming outgoing.font = scaledTitleFont return outgoing } config.subtitleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { incoming in var outgoing = incoming outgoing.font = baseSubtitleFont return outgoing } button.configuration = config } Thanks in advance!
3
0
88
Apr ’25
App Crash with CarPlay & UIScene
My app crashed on iOS 18.1 only, here is the crash log: *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'BUG IN CLIENT OF UIKIT: <CPTemplateApplicationScene: 0x1114bb780> -[UIScene _registerSettingsDiffActionArray:forKey:]: Registering the scene itself results in a retain cycle.' And I found this post: https://mastodon.social/@marcoarment/113280078320422999 Is this a system bug in iOS 18.1 beta 5?
1
0
52
Apr ’25
Hover effect in Custom UIKit Views
I am adapting my custom UI Framework for visionOS, and I'm wondering if it is going to be possible to detect hover over different UI elements within my view. The UI Framework draws to a Metal layer in a UIView. I don't currently support uihovergesturerecognizer on the view but I guess this wouldn't help, since you don't get coordinates. I can imagine an unpleasant solution might be to add invisible UIControls for each of my custom controls that are drawn in my own framework.
1
0
29
Apr ’25
Toggling UITextView attributes for spellchecking, smart quotes, etc stops working
I've added some menu actions to toggle various text view attributes named in the subject. The default for Simulator and my devices is to have these features turned on. But I'm finding that toggling them in my menu actions doesn't actually work. Toggling spellchecking or smart quotes (I haven't yet bothered to add more actions and test them) to .off does indeed set the correct value on the UITextView, but the features are still happening when I type (soft or hard keyboards behave the same). What's wrong? Is it simply broken and is caching the initial value or something? 18.4 is being used on my Simulator and my devices. I also tried 18.3.1 in Simulator with the same results.
Topic: UI Frameworks SubTopic: UIKit
3
0
34
Apr ’25
UIInputView not being deallocated
I am experiencing memory leaks in my iOS app that seem to be related to an issue between UIInputView and _UIInputViewContent. After using the memory graph, I'm seeing that instances of these objects aren't being deallocated properly. The UIInputViewController whichs holds the inputView is being deallocated properly along with its subviews.I have tried to remove all of UIInputViewController's subviews and their functions but the uiInputView is not being deallocated. The current setup of my app is a collectionView with multiple cells,each possessing a textfield with holds a UIInputViewController.When i scroll up or down,the views are being reused as expected and the number of UIInputViewController stays consistent with the number of textfields.However the number of inputView keeps increasing referencing solely _UIInputViewContent. class KeyboardViewController: UIInputViewController { // Callbacks var key1: ((String) -> Void)? var key2: (() -> Void)? var key3: (() -> Void)? var key4: (() -> Void)? private lazy var buttonTitles = [ ["1", "2", "3"], ["4", "5", "6"], ["7", "8", "9"] ] override func viewDidLoad() { super.viewDidLoad() setupKeyboard() } lazy var mainStackView: UIStackView = { let mainStackView = UIStackView() mainStackView.axis = .vertical mainStackView.distribution = .fillEqually mainStackView.spacing = 16 mainStackView.translatesAutoresizingMaskIntoConstraints = false return mainStackView }() private func setupKeyboard() { let keyboardView = UIView(frame:CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 279.0)) keyboardView.addSubview(mainStackView) NSLayoutConstraint.activate([ mainStackView.topAnchor.constraint(equalTo: keyboardView.topAnchor, constant: 16), mainStackView.leadingAnchor.constraint(equalTo: keyboardView.leadingAnchor, constant: 0), mainStackView.trailingAnchor.constraint(equalTo: keyboardView.trailingAnchor, constant: -24), mainStackView.bottomAnchor.constraint(equalTo: keyboardView.bottomAnchor, constant: -35) ]) // Create rows for (_, _) in buttonTitles.enumerated() { let rowStackView = UIStackView() rowStackView.axis = .horizontal rowStackView.distribution = .fillEqually rowStackView.spacing = 1 // Create buttons for each row for title in rowTitles { let button = createButton(title: title) rowStackView.addArrangedSubview(button) } mainStackView.addArrangedSubview(rowStackView) } self.view = keyboardView } private func createButton(title: String) -> UIButton { switch title { ///returns a uibutton based on title } } // MARK: - Button Actions @objc private func numberTapped(_ sender: UIButton) { if let number = sender.title(for: .normal) { key1?(number) } } @objc private func key2Called() { key2?() } @objc private func key3Called() { key3?() } @objc private func key4Called() { key4?() } deinit { // Clear any strong references key1 = nil key2 = nil key3 = nil key4 = nil for subview in mainStackView.arrangedSubviews { if let stackView = subview as? UIStackView { for button in stackView.arrangedSubviews { (button as? UIButton)?.removeTarget(self, action: nil, for: .allEvents) } } } mainStackView.removeFromSuperview() } } Environment iOS 16.3 Xcode 18.3.1 Any insights would be greatly appreciated as this is causing noticeable memory growth in my app over time.
1
0
35
Apr ’25
UIInputView not being deallocated
I am experiencing memory leaks in my iOS app that seem to be related to an issue between UIInputView and _UIInputViewContent. After using the memory graph, I'm seeing that instances of these objects aren't being deallocated properly. The UIInputViewController whichs holds the inputView is being deallocated properly along with its subviews.I have tried to remove all of UIInputViewController's subviews and their functions but the uiInputView is not being deallocated. The current setup of my app is a collectionView with multiple cell,each possessing a textfield with holds a UIInputViewController.When i scroll up or down,the views are being reused as expected and the number of UIInputViewController stays consistent with the number of textfields.However the number of inputView keeps increasing referencing solely _UIInputViewContent. class KeyboardViewController: UIInputViewController { // Callbacks var key1: ((String) -> Void)? var key2: (() -> Void)? var key3: (() -> Void)? var key4: (() -> Void)? private lazy var buttonTitles = [ ["1", "2", "3"], ["4", "5", "6"], ["7", "8", "9"] ] override func viewDidLoad() { super.viewDidLoad() setupKeyboard() } lazy var mainStackView: UIStackView = { let mainStackView = UIStackView() mainStackView.axis = .vertical mainStackView.distribution = .fillEqually mainStackView.spacing = 16 mainStackView.translatesAutoresizingMaskIntoConstraints = false return mainStackView }() private func setupKeyboard() { let keyboardView = UIView(frame:CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 279.0)) keyboardView.addSubview(mainStackView) NSLayoutConstraint.activate([ mainStackView.topAnchor.constraint(equalTo: keyboardView.topAnchor, constant: 16), mainStackView.leadingAnchor.constraint(equalTo: keyboardView.leadingAnchor, constant: 0), mainStackView.trailingAnchor.constraint(equalTo: keyboardView.trailingAnchor, constant: -24), mainStackView.bottomAnchor.constraint(equalTo: keyboardView.bottomAnchor, constant: -35) ]) // Create rows for (_, _) in buttonTitles.enumerated() { let rowStackView = UIStackView() rowStackView.axis = .horizontal rowStackView.distribution = .fillEqually rowStackView.spacing = 1 // Create buttons for each row for title in rowTitles { let button = createButton(title: title) rowStackView.addArrangedSubview(button) } mainStackView.addArrangedSubview(rowStackView) } self.view = keyboardView } private func createButton(title: String) -> UIButton { switch title { ///returns a uibutton based on title } } // MARK: - Button Actions @objc private func numberTapped(_ sender: UIButton) { if let number = sender.title(for: .normal) { key1?(number) } } @objc private func key2Called() { key2?() } @objc private func key3Called() { key3?() } @objc private func key4Called() { key4?() } deinit { // Clear any strong references key1 = nil key2 = nil key3 = nil key4 = nil for subview in mainStackView.arrangedSubviews { if let stackView = subview as? UIStackView { for button in stackView.arrangedSubviews { (button as? UIButton)?.removeTarget(self, action: nil, for: .allEvents) } } } mainStackView.removeFromSuperview() } } Environment iOS 16.3 Xcode 18.3.1 Any insights would be greatly appreciated as this is causing noticeable memory growth in my app over time.
0
0
27
Apr ’25
scrolling beyond bottom in iOS
I have a scrollable text field where the text changes programmatically. when I scroll up to see the end of the text, I can keep scrolling so that all of the text scrolls out of site (this is bad). I should only be able to scroll up until I reach the end of the text. Even worse, something in the scrolling goes into an infinite loop, and the app starts use up memory until I have to kill it. I assume that it is something that is set wrong in Main.storyboard, but I am not sure. Andy ideas?
Topic: UI Frameworks SubTopic: UIKit
0
0
28
Apr ’25
Simulating key press event to type text in UITextField
in iOS, user can set focus on UItextField and tapping a key in the virtual keyboard updates the text in the textfield. This user action causes the relevant delegates of UITextFieldDelegate to get invoked, i.e the handlers associated with action of user entering some text in the textfield. I m trying to simulate this user action where I am trying to do this programatically. I want to simulate it in a way such that all the handlers/listeners which otherwise would have been invoked as a result of user typing in the textfield should also get invoked now when i am trying to do it programatically. I have a specific usecase of this in my application. Below is how I m performing this simulation. I m manually updating the text field associated(UITextField.text) and updating its value. And then I m invoking the delegate manually as textField.delegate?.textField?(textField, shouldChangeCharactersIn: nsRange, replacementString: replacementString) I wanted to know If this is the right way to do this. Is there something better available that can be used, such that simulation has the same affect as the user performing the update?
Topic: UI Frameworks SubTopic: UIKit Tags:
2
0
280
Apr ’25
UITextField with isSecureTextEntry in Catalyst display an empty box
Hi, In a Mac Catalyst app, I need to allow the user insert a passcode using a UITextField. The field is used to insert a one time passcode and I want to keep the content hidden. For this reason I set the isSecureTextEntry property to true. passcodeTextField.isSecureTextEntry = true By doing this, a button to allow the user to pick a password from the keychain is displayed: This option in my case should not appear because the password is a one time password that change every time. For that reason I set the textContentType to oneTimeCode. passcodeTextField.textContentType = .oneTimeCode This actually removes the password button, but introduce something weird. If the user type something and then delete everything, a big empty box appear under the field: I have no idea what this box is and why it appears. Does anyone know why it appears and how I can remove it? Thank you
1
1
802
Apr ’25
Printing NSTextStorage over multiple UITextView produces weird results
I would like to print a NSTextStorage on multiple pages and add annotations to the side margins corresponding to certain text ranges. For example, for all occurrences of # at the start of a line, the side margin should show an automatically increasing number. My idea was to create a NSLayoutManager and dynamically add NSTextContainer instances to it until all text is laid out. The layoutManager would then allow me to get the bounding rectangle of the interesting text ranges so that I can draw the corresponding numbers at the same height inside the side margin. This approach works well on macOS, but I'm having some issues on iOS. When running the code below in an iPad Simulator, I would expect that the print preview shows 3 pages, the first with the numbers 0-1, the second with the numbers 2-3, and the last one with the number 4. Instead the first page shows the number 4, the second one the numbers 2-4, and the last one the numbers 0-4. It's as if the pages are inverted, and each page shows the text starting at the correct location but always ending at the end of the complete text (and not the range assigned to the relative textContainer). I've created FB17026419. class ViewController: UIViewController { override func viewDidAppear(_ animated: Bool) { let printController = UIPrintInteractionController.shared let printPageRenderer = PrintPageRenderer() printPageRenderer.pageSize = CGSize(width: 100, height: 100) printPageRenderer.textStorage = NSTextStorage(string: (0..<5).map({ "\($0)" }).joined(separator: "\n"), attributes: [.font: UIFont.systemFont(ofSize: 30)]) printController.printPageRenderer = printPageRenderer printController.present(animated: true) { _, _, error in if let error = error { print(error.localizedDescription) } } } } class PrintPageRenderer: UIPrintPageRenderer, NSLayoutManagerDelegate { var pageSize: CGSize! var textStorage: NSTextStorage! private let layoutManager = NSLayoutManager() private var textViews = [UITextView]() override var numberOfPages: Int { if !Thread.isMainThread { return DispatchQueue.main.sync { [self] in numberOfPages } } printFormatters = nil layoutManager.delegate = self textStorage.addLayoutManager(layoutManager) if textStorage.length > 0 { let glyphRange = layoutManager.glyphRange(forCharacterRange: NSRange(location: textStorage.length - 1, length: 0), actualCharacterRange: nil) layoutManager.textContainer(forGlyphAt: glyphRange.location, effectiveRange: nil) } var page = 0 for textView in textViews { let printFormatter = textView.viewPrintFormatter() addPrintFormatter(printFormatter, startingAtPageAt: page) page += printFormatter.pageCount } return page } func layoutManager(_ layoutManager: NSLayoutManager, didCompleteLayoutFor textContainer: NSTextContainer?, atEnd layoutFinishedFlag: Bool) { if textContainer == nil { addPage() } } private func addPage() { let textContainer = NSTextContainer(size: pageSize) layoutManager.addTextContainer(textContainer) let textView = UITextView(frame: CGRect(origin: .zero, size: pageSize), textContainer: textContainer) textViews.append(textView) } }
Topic: UI Frameworks SubTopic: UIKit Tags:
4
0
69
Apr ’25
iOS 18 SDK causing random UI changes and crashes with my app
I am a developer on an enterprise application. Our team just updated our pipeline to build our app on the iOS 18 SDK instead of the 17.4 SDK and this has caused a lot of our ui elements to change and several crashes within the app resulting in just the simple error message "Swift runtime failure: unhandled C++ / Objective-C exception". Why is just updating the SDK causing all these issues? Is there anyway to keep the previous version or will we have to go component by component to fix the constraints and crashes? These issues seem to be happening to our users on iOS 18 and beyond.
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
73
Apr ’25