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

Posts under UIKit tag

200 Posts

Post

Replies

Boosts

Views

Activity

iPhone Duo - UIViewController viewWillTransition(to:with:) is not called when fold is changed
Let's say we start with a fully open iPhone Duo. We then present a view controller as a form sheet or page sheet. If the device is then rotated between landscape and portrait, the view controller's viewWillTransition(to:with:) is called to reflect the change in size between orientations. So far so good. Now put the fully open Duo in landscape. Then partially close the Duo. The presented view controller will automatically move off to the left half of the screen to avoid the fold. That's expected. However, the view controller's viewWillTransition(to:with:) is NOT called in this case even though its size has changed. Does this seem like a bug or is this somehow expected? I have a particular view controller that needs to know its size has changed so it can make some adjustments. Other lifecycle methods such as viewDidLayoutSubviews are called but I'd prefer to have viewWillTransition(to:with:) called.
0
0
273
7h
How does a view controller know when the reserved regions change?
I've looked at the UIKit docs for UIView reservedRegions(kind:options:). I've watched the video "Strike a pose with adaptive layouts on iPhone Duo". So I know how to get the current reserved regions. But I can't find the APIs to know when the reserved regions change. This means I can setup my custom view controller with the reserved regions that exist when the view controller is first displayed. But if the user changes the Duo, say from fully open to partially open, what API is triggered that lets me know that I need to call reservedRegions(kind:options:) and update the layout as needed? I played around with UIHingeInteraction but that isn't the right approach. In most cases I tried calling reservedRegions(kind:options:) on each call to the interaction handler but I almost always got the wrong results (maybe a simulator issue?). And of course that interactiion handler will be called a lot just to report the new fold angle. I also tried various UIViewController methods for size changes and registered for size class changes. None of these were appropriate. I just need a single notification that the Duo went from fully open to partially open, partially open to fully open, and partially open between landscape/portrait so that I can call reservedRegions(kind:options:) and get the correct, current divider info. What am I missing? My use case is for a custom fullscreen view controller that needs to layout a few items based on whether the Duo is fully open or partially open and whether the fold is horizontal or vertical. Unless I'm mistaken this precludes the use of UIArrangementViewController since I only have one view controller with one set of content to display. Showing the view controller as a form sheet, page sheet, or popover won't work since I need this to be fullscreen. I just need the fullscreen content to adjust for any fold (reserved region).
4
0
308
12h
iPadOS 26: App crashes in system keyboard – NSAllocateMemoryPages failure in -[TIImageCacheItem encodeWithCoder:]
Since iPadOS 26 we have been seeing a crash inside the system keyboard. It happens while the system keyboard renders key images. Our code is not on the crashing stack. Crash The app is terminated by an uncaught NSInvalidArgumentException. The NSXPC encoder fails to allocate a very large buffer while a keyboard image cache item is being encoded: NSInvalidArgumentException: *** NSAllocateMemoryPages(60003072) failedRequested sizes seen across reports: 60,003,072 / 60,558,656 / 78,724,160 / 240,001,920 / 933,149,952 bytes. Xcode Organizer groups these reports under the signature TextInput: -[TIImageCacheItem encodeWithCoder:] + 276. Relevant frames (main thread, simplified): objc_exception_throw NSAllocateMemoryPages NSXPCEncoder (encoding) -[TIImageCacheItem encodeWithCoder:] + 276 (TextInput) TIDispatchSync TIImageCacheClient UIKeyboardCache -[UIKBKeyView displayLayer:] ... UIApplicationMainScope (about 3 months of data) 327 crashes from 43 users. iPad only. iPadOS 26.1 – 26.7.1. No crashes on iPhone and none on iPadOS 18 or earlier. No single iPadOS 26 minor version stands out. The first occurrence did not line up with any release of our app. Our keyboard-related code did not change at that time. Free memory at crash time ranges from 33 MB to 4.8 GB. Some crashes happen within 40 seconds of launch. This looks like an abnormally large encode request, not memory pressure or a leak in the app. All affected users use the zh_CN locale. Context The screen has a plain UITextField, the standard system keyboard, and no custom inputView. It also has a UIIndirectScribbleInteraction for Apple Pencil handwriting. The crash happens shortly after the keyboard appears. Breadcrumbs show UICompatibilityInputViewController, UISystemInputAssistantViewController and UIPredictionViewController being set up just before the crash. Many crashes happen when the app window is not full screen (Split View / Stage Manager). For example, a 629.5 pt wide app window on a 1180 pt screen, or 936×954 on 1373×954. Some devices were rotating frequently. In a few cases there was a rapid burst of multi-tap gestures about 20 ms apart just before the crash (Pencil/Scribble-like input). What we tried We could not reproduce it on our own iPads running iPadOS 26. Memory stays flat and there is no crash. Questions Is this a known issue in the iPadOS 26 keyboard image cache (TIImageCacheItem)? Is there a recommended workaround on the app side, for example avoiding certain input view reloads or trait changes while the keyboard is visible?
1
0
39
1d
iPhone Duo bug: Popovers presented with their arrow restricted to left/right appear partially offscreen
The following has been reported as FB25281446 I've come across a serious user interface issue on the iPhone Duo when you show a popover with the permitted arrow direction set to only left or right. Here's a screenshot from a test app of a correct popover shown from a form sheet on a fully open iPhone Duo: Here's the same UI after switching the Duo from fully open to partially open: Note how the popover is now partially offscreen. Oddly the toolbar is still kept onscreen. You are unable to scroll to the last rows of the table view. You can replicate this problem by taking the following steps: 1) Create a new Storyboard/Swift app with Xcode 27.2 RC 2) Edit the Main storyboard by removing the default view controller 3) Add a navigation controller (and its default root view controller) 4) Set the navigation controller as the initial view controller 5) Replace the contents of the default ViewController.swift file with the following code: ```swift import UIKit class ViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() let showPopover = UIBarButtonItem() // Show the view controller as a popover let action = UIAction(title: "Popover", handler: { _ in let vc = ViewController() let nc = UINavigationController(rootViewController: vc) nc.modalPresentationStyle = .popover nc.popoverPresentationController?.sourceItem = showPopover nc.popoverPresentationController?.permittedArrowDirections = .any self.present(nc, animated: true) }) showPopover.primaryAction = action self.navigationItem.rightBarButtonItem = showPopover // Show the view controller in a form sheet let showFormSheet = UIBarButtonItem() let action2 = UIAction(title: "FormSheet", handler: { _ in let vc = ViewController() // Applying a preferred content size affects the results in one // case - the popover works correctly when the Duo is fully open // in portrait and you show a popover from a form sheet. //vc.preferredContentSize = .init(width: 540, height: 620) let nc = UINavigationController(rootViewController: vc) nc.modalPresentationStyle = .formSheet self.present(nc, animated: true) }) showFormSheet.primaryAction = action2 self.navigationItem.leftBarButtonItem = showFormSheet // Show some dummy toolbar items to help demonstrate the issue self.navigationController?.isToolbarHidden = false self.toolbarItems = [ UIBarButtonItem(systemItem: .add), UIBarButtonItem.flexibleSpace(), UIBarButtonItem(systemItem: .action), ] } } extension ViewController { override func numberOfSections(in tableView: UITableView) -> Int { return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 20 } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell") ?? UITableViewCell(style: .subtitle, reuseIdentifier: "cell") cell.textLabel?.text = "Row \(indexPath.row)" cell.detailTextLabel?.text = "Tap me to show popover" return cell } // Show a popover from a selected cell. The popover will appear partially // offscreen under the following conditions: // - When the Duo is fully open and landscape: // - A row near the bottom of the root view controller is selected. // - When the Duo is fully open and portrait: // - A row near the bottom of the root view controller is selected. // - A row near the bottom of a form sheet is selected (unless the form // sheet has a preferredContentSize set). // - When the Duo is partially open and landscape or portrait: // - A row near the bottom of the root view controller is selected. // - A row near the bottom of a form sheet is selected. // - If you then fully open the Duo, the partially offscreen popover // moves into the correct, fully visible position. // Note that the toolbar of the partially offscreen popover stays on screen. // // There are no issues when the Duo is closed. override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { if let cell = tableView.cellForRow(at: indexPath) { let vc = ViewController() let nc = UINavigationController(rootViewController: vc) nc.modalPresentationStyle = .popover nc.popoverPresentationController?.sourceItem = cell // The problem only happens if the arrow is limited to left or right nc.popoverPresentationController?.permittedArrowDirections = [ .left, .right ] self.present(nc, animated: true) } } } ``` 6) In the Main storyboard, change the root view controller's class to ViewController 7) Build and run the app against an iPhone Duo running iOS 27.2 RC You can now replicate the two screenshots by fully opening the Duo and putting it in landscape. Then do the following: 1) Tap the FormSheet button 2) In the form sheet table, select a row near the bottom of the form sheet 3) Note the popover appears correctly with an arrow on the right side pointing to the selected row 4) Now put the iPhone Duo in the partially open mode (still landscape) 5) Note the problem. The popover moves partially offscreen. You can’t even scroll to the last row. The popover show remain fully onscreen and of reasonable height just like it was when the Duo was fully open. As noted in the ViewController.swift file, the issue appears under the following conditions: - When the Duo is fully open and landscape: - A row near the bottom of the root view controller is selected. - When the Duo is fully open and portrait: - A row near the bottom of the root view controller is selected. - A row near the bottom of a presented form sheet is selected (unless the form sheet has a preferredContentSize set). - When the Duo is partially open and landscape or portrait: - A row near the bottom of the root view controller is selected. - A row near the bottom of a presented form sheet is selected. - If you then fully open the Duo, the partially offscreen popover moves into the correct, fully visible position.
1
0
279
1d
Best Practice to adopt iPhone Duo
What's the best practices to adopt iPhone Duo for a production UIKit app? What few things we need to consider during the development? "As long as we use auto layout, it should be fine" is this correct term for iPhone Duo? Meaning, as long as our app use proper auto layout, our app should be able to support iPhone Duo properly.
2
0
285
2d
API request: Query default toolbar item size
On the iPhone Duo, default toolbar items are 48 pt instead of 44 pt, even when the navigation bar is horizontal. There doesn't seem to be a public API to query this size, making it difficult to match custom toolbar items to system controls without device-specific checks. I've filed FB25271102 requesting an API to expose the default toolbar item dimensions, ideally through a SwiftUI environment value.
0
0
59
2d
Vertical tab bar doesn't appear when tab bar controller is added to view controller while iPhone Duo is unfolded
Hi, I would like to share an issue with UITabBarController's vertical tab bar and iPhone Duo's unfolded pose. On iPhone Duo (27.2 beta 3), when tab bar controller is added to the view controller while in unfolded pose, the vertical tab bar doesn't appear unless the tab bar controller view's frame is set manually before adding it to the parent's view. Show any VC. Use unfolded Duo pose. After some time/on button press add a UITabBarController to it: (https://developer.apple.com/documentation/uikit/creating-a-custom-container-view-controller#Add-a-child-view-controller-programmatically-to-your-content) with Auto Layout constraints. Vertical tab bar does not appear. Fold and unfold the device. The tab bar appears. Expected: Tab bar appears after adding the UITabBarController in unfolded Duo pose. Actual: Tab bar does not appear after adding the UITabBarController in unfolded Duo pose. In Feedback Assistant report (FB25261013) I attached minimal reproduction example and recordings showing the different behavior in folded and unfolded poses and behavior with manual frame application fix (commented out in minimal reproduction example). Minimal reproduction example: // SceneDelegate.swift import UIKit class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } window = UIWindow(windowScene: windowScene) window?.rootViewController = ViewController() window?.makeKeyAndVisible() } } // ViewController.swift import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .systemBackground let button = UIButton(configuration: .filled(), primaryAction: UIAction(title: "Show Tab Bar Controller") { [weak self] _ in self?.showTabBarController() }) button.translatesAutoresizingMaskIntoConstraints = false view.addSubview(button) NSLayoutConstraint.activate([ button.centerXAnchor.constraint(equalTo: view.centerXAnchor), button.centerYAnchor.constraint(equalTo: view.centerYAnchor), ]) } private func showTabBarController() { let tabBarController = UITabBarController() tabBarController.tabs = ["First", "Second", "Third"].map { title in UITab(title: title, image: UIImage(systemName: "circle"), identifier: title) { _ in let viewController = UIViewController() viewController.view.backgroundColor = .systemBackground return viewController } } addChild(tabBarController) // Uncomment to show the tab bar on the unfolded iPhone Duo. tabBarController.view.frame = view.bounds view.addSubview(tabBarController.view) tabBarController.view.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ tabBarController.view.topAnchor.constraint(equalTo: view.topAnchor), tabBarController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor), tabBarController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), tabBarController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), ]) tabBarController.didMove(toParent: self) } } Thank you in advance.
Topic: UI Frameworks SubTopic: UIKit Tags:
1
0
378
3d
Public API for a transparent PencilKit layer above another foreground app?
Is there a public iPadOS API (or entitlement) that lets a third-party app present a transparent, interactive drawing layer over another foreground app? What I want: App A (Safari, a video app, etc.) stays in the foreground and remains visible. My app draws Apple Pencil ink on a transparent layer above that content. Pencil strokes go to my layer. I do not need to read the pixels underneath. This must be possible with public APIs only, for an App Store app. What I already checked, and why it does not match: UIWindow / windowLevel: only orders windows inside my own scene, not above another app. Slide Over, Split View, Stage Manager: a separate window beside or over the other app, not a transparent ink layer on its pixels. Picture in Picture with a custom content source: a floating window, not a full-screen transparent canvas. ReplayKit / ScreenCaptureKit: capture or broadcast, not an interactive overlay. Screen Time shields / AssistiveTouch-style overlays: system UI, not available to third-party apps. I am not asking for a review of an app concept. I am asking whether any current public API can do this, and if not, which of the options above is the supported boundary. Environment: iPadOS 26, Xcode 26, PencilKit.
0
0
48
3d
iPhone Duo - Buggy margin shift while dragging down a modal view controller
Has anyone else run into this issue? If you present a view controller and set its isModalInPresentation property to true, then when you try to drag down the view controller (which can't be dismissed), the view controller's content on the side of the vertical toolbar is shifted inward. This happens on a closed iPhone Duo. Even the title shifts if the vertical toolbar is on the left side. To replicate, create a Swift/UIKit project. Edit the main storyboard by deleting the default view controller scene and add a navigation controller (and its default root view controller). Set the class for the root view controller to ViewController. Then replace the default ViewController.swift code with the following: import UIKit class ViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() let modal = UIBarButtonItem(systemItem: .add, primaryAction: .init(handler: { _ in let vc = ViewController() vc.title = "Some Modal" // If the following is true, dragging the modal view controller // down results in the table margins being shifted on whichever // side has a vertical toolbar. This happens on the iPhone Duo // when closed in either portrait or landscape. Whichever side // has the vertical toolbar gets shifted. // When the iPhone Duo is open the modal appears in a form sheet // and it does not demonstrate the issue. // The navigation title is also affected when the iPhone Duo is // closed and in landscape with the vertical toolbar on the left. // If the following is false, dismissing the modal by dragging it // down does NOT result in any change in the table's margins. vc.isModalInPresentation = true // false let nc = UINavigationController(rootViewController: vc) self.present(nc, animated: true) })) navigationItem.rightBarButtonItem = modal } } extension ViewController { override func numberOfSections(in tableView: UITableView) -> Int { 2 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 4 } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // Some simple table cells to demonstrate the margin shift let cell = tableView.dequeueReusableCell(withIdentifier: "cell") ?? UITableViewCell(style: .value1, reuseIdentifier: "cell") cell.textLabel?.text = "Some Text" cell.detailTextLabel?.text = "Value" cell.accessoryType = .disclosureIndicator return cell } } Build and run the app with Xcode 27.1 and run it on an iPhone Duo (simulated or real). Tap the + icon to display the modal view controller (just another instance of ViewController). Now try to drag down the modal view controller. Notice the margin shift if the Duo is closed. There is no margin shift is the Duo is open or if isModalInPresentation is set to false. This has been reported as FB25221160.
1
0
603
4d
UIDesignRequiresCompatibility for Xcode27
Hallo everyone, We are building our app with Xcode 27 and noticed that UIDesignRequiresCompatibility still appears to be honored on iOS 26 devices. Questions: Could you confirm whether this key is still supported on iOS 26 when built with Xcode 27? If our deployment target includes iOS 26, should we keep the key for backward compatibility, or is Apple's recommendation to remove it entirely? Additionally, are there any risks associated with removing it for iOS 26 users?
1
0
439
4d
Third-party keyboards get an extra 17pt gap at the top after switching apps on iOS 27 beta.
Feedback submitted: FB24460699 The sample projects are attached to the feedback report. Environment:iOS27 Beta6; iPhone 17Pro Problem:I have encountered a consistently reproducible third-party custom keyboard layout issue in iOS 27.0 beta 1 through beta 6. The custom keyboard initially appears correctly. If I switch apps while the text input remains focused and the keyboard remains visible, and then return to the host app, the system adds a 17-point area above the custom keyboard extension. Steps to reproduce Install and enable a third-party custom keyboard. Switch to the sample custom keyboard and open the host app so that the text editor in the center receives focus. Do not dismiss the keyboard or remove focus from the editor. Return to the Home Screen or switch to another app. Return to the host app. A new blank area now appears above the custom keyboard content. I tested both a system-determined extension view height and an extension view explicitly constrained to 180 points. Both configurations produce exactly the same change. After the foreground transition, the following extension-side values remain unchanged: view.bounds inputView.bounds extension.window.bounds view.safeAreaInsets, which remains {0, 0, 0, 0} The requested 180-point extension height Only the system keyboard frame received by the host app increases by 17 points. I also drew a rounded pink boundary inside the transparent extension root view. When the issue occurs, the new area appears outside that boundary. I tested several third-party keyboards and reproduced the issue with all of them. This suggests that the behavior is caused by iOS rather than by my app. Questions On iOS 27, is it expected behavior for a custom keyboard to gain a 17pt top area after its host app returns from the background? If this is a system issue, is there any workaround that can be used until it is fixed?
9
8
1.4k
4d
Can an App Clip share an image to Apple Notes through the share sheet?
My App Clip shows an image, and I need that image to end up in Apple Notes as a new note with as few taps as possible. The plan is to present UIActivityViewController with the image, then the user taps Notes, then Save. I know clips can’t use PhotoKit, so “Save Image” is likely out. What I can’t find documented is whether Notes, or any other app’s share extension, still shows up in a clip’s share sheet and actually saves. Has anyone tried this? I don’t have a paid account yet to test it myself. If someone could run a one-file test clip, I can send the code.
0
0
48
4d
Tapping the top area of iPhone Duo does not respond in Device Hub
I’m simulating an iPhone Duo using Xcode 27.1 beta, and I’m having trouble tapping buttons placed near the top of the screen. It seems that the top ~20 pixels of the screen are not responding to taps. In my ViewController, preferredScreenEdgesDeferringSystemGestures returns .all, so system gestures should require two swipes to be triggered. However, a simple tap in this area does not seem to be recognized. This appears to happen only on iPhone Duo; taps work normally on other iPhone models. Does anyone know whether this behavior is expected to occur on the actual iPhone Duo hardware as well, or is it specific to the simulator? For reference, the buttons are positioned according to LayoutMarginsGuide with Safe Area. FB24914903 I wonder if anyone knows how to get the top margin size programmatically.
1
1
682
6d
How to distinguish a foreground cold launch from a background task cold launch?
I'm trying to determine why my UIKit application was launched, specifically whether it was launched by the user or by the system to execute a background task. I recently added a BGProcessingTask to update data overnight. Consider this scenario: The user backgrounds the app at 10 AM. A background task is scheduled with earliestBeginDate set to 4 AM the following day. During those 18 hours, iOS terminates the app's process to reclaim memory. iOS later decides to execute the scheduled background task and launches a new app process in the background. My understanding is that this results in a cold launch, including a call to application(_:didFinishLaunchingWithOptions:) and the initialization performed there. This matters because some of our startup initialization triggers network requests that are unnecessary when the app is launched only to perform a background task. Questions 1. Can iOS relaunch a previously terminated app to execute a scheduled BGProcessingTask? I'm referring specifically to termination by the system (for example, memory pressure), not the user force-quitting the application. 2. Is there a reliable way to distinguish a foreground cold launch from a background task cold launch inside application(_:didFinishLaunchingWithOptions:)? I tried checking UIApplication.shared.applicationState, but in my testing it was .background during didFinishLaunchingWithOptions in both scenarios, including when the user launched the app by tapping its icon. Is there another documented API or launch context that reliably identifies why the process was started? I'm aware that iOS provides launch options for certain launch scenarios, but I'm specifically interested in distinguishing a background task-triggered cold launch from a user-initiated foreground cold launch. 3. If this distinction cannot be made reliably during didFinishLaunchingWithOptions, what is the earliest lifecycle callback where I can determine that the app is entering the foreground? For example, should foreground-specific initialization be deferred until scene(_:willConnectTo:options:), sceneWillEnterForeground(_:), or another callback? I'm specifically looking for a documented and reliable lifecycle signal, rather than heuristics or arbitrary delays. The goal is to avoid unnecessary startup initialization and network requests when iOS launches the application solely to execute a background task.
2
0
184
1w
iPhone Duo: Making a custom popup avoid the hinge by presenting it as an arrowless popover
Background On iPhone Duo, when the device is unfolded and then partially folded, system alerts (UIAlertController) are automatically repositioned so they stay clear of the hinge. Apple's Tech Talk confirms this: "The system automatically repositions components around the reserved region." Our app uses a custom popup: a view controller presented with .overFullScreen that lays out its own dimming view and a custom-drawn view (here, a coupon ticket with notched edges) in the center of the screen. This popup is not repositioned. It stays centered on screen, right on top of the fold. The recommended approach for custom UI is to query view.reservedRegions(kind: .division) and lay out around the fold manually. Before going that route, I tried something simpler. What I tried The Tech Talk lists popovers among the components the system repositions. So I presented the same custom view as a popover with no arrow, anchored to the center of the presenting view: final class CouponPopoverViewController: UIViewController, UIPopoverPresentationControllerDelegate { private let ticketView = CouponTicketView() // the custom popup view init(centeredIn sourceView: UIView) { super.init(nibName: nil, bundle: nil) modalPresentationStyle = .popover guard let popover = popoverPresentationController else { return } popover.sourceView = sourceView popover.sourceRect = Self.centerPoint(of: sourceView.bounds) popover.permittedArrowDirections = [] // Drop the system popover chrome so only the custom view (and its own shadow) is visible. popover.popoverBackgroundViewClass = ClearPopoverBackgroundView.self popover.delegate = self } required init?(coder: NSCoder) { fatalError() } override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .clear ticketView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(ticketView) NSLayoutConstraint.activate([ ticketView.topAnchor.constraint(equalTo: view.topAnchor), ticketView.bottomAnchor.constraint(equalTo: view.bottomAnchor), ticketView.leadingAnchor.constraint(equalTo: view.leadingAnchor), ticketView.trailingAnchor.constraint(equalTo: view.trailingAnchor) ]) preferredContentSize = ticketView.systemLayoutSizeFitting( CGSize(width: 300, height: UIView.layoutFittingCompressedSize.height), withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel ) } private static func centerPoint(of bounds: CGRect) -> CGRect { CGRect(x: bounds.midX, y: bounds.midY, width: 0, height: 0) } // Keep it a popover on iPhone instead of adapting to a sheet. func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle { .none } // Re-anchor to the center after rotation or fold changes. func popoverPresentationController(_ popoverPresentationController: UIPopoverPresentationController, willRepositionPopoverTo rect: UnsafeMutablePointer<CGRect>, in view: AutoreleasingUnsafeMutablePointer<UIView>) { rect.pointee = Self.centerPoint(of: view.pointee.bounds) } } /// A popover background that draws nothing: no arrow, no insets, no default appearance. final class ClearPopoverBackgroundView: UIPopoverBackgroundView { override class func arrowBase() -> CGFloat { 0 } override class func arrowHeight() -> CGFloat { 0 } override class func contentViewInsets() -> UIEdgeInsets { .zero } override class var wantsDefaultContentAppearance: Bool { false } override var arrowOffset: CGFloat { get { 0 } set {} } override var arrowDirection: UIPopoverArrowDirection { get { .any } set {} } } Result Partially folded, portrait (hinge runs horizontally across the middle of the screen): Before: the custom popup (.overFullScreen) stays centered, right across the hinge. After: the same view presented as an arrowless popover moves into the top half, clear of the hinge. Partially folded, book pose (vertical hinge): the popover moves to the leading page, clear of the hinge. This matches where a system UIAlertController goes in the same pose. I also checked that the popover shows correctly on the outer display (closed) and on a non-Duo iPhone (iPhone 18 Pro, iOS 27.0). Tested on: iPhone Duo simulator (iOS 27.1), Xcode 27.1 RC (27A9275) iPhone 18 Pro simulator (iOS 27.0) Things to handle when switching to a popover Tap-outside dismissal: Popovers dismiss on outside taps by default. Set isModalInPresentation = true or return false from presentationControllerShouldDismiss(_:) if the popup should only close via its buttons. Dimming: Popovers don't dim the background like a typical custom popup (compare the before and after screenshots). Add your own dimming view if needed. Chrome: By default, the system draws its own background behind the content. For a custom-shaped view, this shows through any transparent areas and clips the view's shadow. A UIPopoverBackgroundView subclass that draws nothing (above) removes it. Sizing: Set preferredContentSize explicitly. Recompute it for dynamic content and Dynamic Type. Questions This works well in my testing, but I couldn't find any documentation saying that an arrowless popover anchored to the center gets the same hinge avoidance as alerts. Is this supported behavior that we can rely on going forward? Or is reservedRegions(kind:options:) with manual layout the only recommended approach for custom popups? It would also be great to have a public API that lets custom presentations opt into the same hinge-avoidance placement that system alerts use. Hope this helps anyone else dealing with custom popups on iPhone Duo.
Topic: UI Frameworks SubTopic: UIKit Tags:
2
0
165
1w
iPhone Duo - Current SDK State
We are just 9 days before the iPhone Duo release, and the SDK is still in a pretty bad state, at least for the Keyboard Extension: Hinge detection doesn't work Reserved area detection doesn't work needsInputModeSwitchKey returns false even though iOS doesn't display its own globe button Switching between closed and fully open state loses text field focus and the keyboard disappears (regression bug - it worked in Beta 1) It's unacceptable that, with such a short release date, we still don't have a stable SDK... I expect the iPhone Duo release to be one of the buggiest releases Apple has ever done.
7
0
546
1w
UISheetPresentationController issues on iPhone Duo
I have an App where I use the UISheetPresentationController to present a menu as a "drawer" (like the "FindMy" or "Maps") App. Because the sheet is presented over a map, I made the sheet semi-transparent/blurry, so the Map shines through, which looks nice. The sheet is using a UITableView with the "insetGroup" style, so the table cells have the nice rounded borders and there are margins to the sheet borders. When running the App on the iPhone Duo (Simulator) on the outer display, the tableView does no longer respect the "insetGroup" style, it is rendered like it would have the "plain" style, which destroys everything that look good. No rounded borders, no margins. However if I opt-out of the automatic "vertical toolbar behavior" (overriding preferredVerticalBarBehavior so it returns "disabled"), then everything looks great again, however then the sheet content might overlap with the sidebar icons and camera because it now covers the whole area up to the right screen border. Is this supposed to be this way (if yes, why?), is there a way to fix this, or do we have to wait for a bugfix within iOS 27.1? The tableview still claims to have the "insetGrouped" style, just it does not render this way. I did not see any similar issues under other circumstances. Only UISheetPresentationController seems to be affected by this. Is there a way to correctly detect if the App is running on an iPhone Duo, so we could use this detection to add workarounds for such issues?
4
1
631
1w
How to get UISheetPresentationController width to adjust for vertical toolbar on iPhone Duo?
If you run Safari in the iPhone Duo simulator and choose to share something you get a screen similar to the following: In my own app, if I present a UIActivityViewController I get a similar result. Note that the share sheet does not cover the vertical toolbar at all. So my question is how to present a UISheetPresentationController to look the same way. In other words, how to get the width of the UISheetPresentationController to take into account the vertical toolbar? All of my existing code to create and present a UISheetPresentationController result in the UISheetPresentationController taking the full width of the screen. The contents of the sheet take the safe area into account, but that's not the same result. I need the sheet itself to be narrower. I don't see an API for this. Or does this require more complicated presentation controller / delegate setup? Here is some relevant code in the view controller that I want displayed in the sheet: self.modalPresentationStyle = .popover self.presentationController?.delegate = self if let sheet = popoverPresentationController?.adaptiveSheetPresentationController { popoverPresentationController?.passthroughViews = [] sheet.detents = [ .medium(), .large() ] sheet.largestUndimmedDetentIdentifier = nil sheet.prefersGrabberVisible = false sheet.prefersScrollingExpandsWhenScrolledToEdge = true sheet.prefersEdgeAttachedInCompactHeight = true sheet.widthFollowsPreferredContentSizeWhenEdgeAttached = true } Or maybe UISheetPresentationController is the wrong approach.
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
109
1w
UIAlertController.addTextField results in broken text field in 27.1
I just downloaded Xcode 27.1 to test out the iPhone Duo simulator, and I notice that UIAlertController.addTextField, which was working fine in 27, is now very broken, resulting in a text field that is squashed vertically and pushed over to the right in the alert sheet. This is very easy to reproduce - the following code will show the problem if you build in Xcode 27.1 and run on iOS 27.1 or iOS 27.2: let alert = UIAlertController(title: "Create Something", message: "Enter a title.", preferredStyle: .alert) alert.addTextField { textField in textField.placeholder = "Title" } alert.addAction(UIAlertAction(title: "Cancel", style: .cancel)) present(alert, animated: true) The bug isn't limited to the Duo, but can also be seen on an iPad (and probably a regular phone). I would post a screenshot, but the last time I tried that, the forum software erroneously banned me for two weeks. I have reported this as bug #FB24889500, but given that we use alerts with text fields for users adding new items to the outline in our app, something the user does a lot, I'm wondering if there is a workaround, since this is going to make our app look very buggy.
Topic: UI Frameworks SubTopic: UIKit Tags:
1
2
334
1w
iPhone Duo - UIViewController viewWillTransition(to:with:) is not called when fold is changed
Let's say we start with a fully open iPhone Duo. We then present a view controller as a form sheet or page sheet. If the device is then rotated between landscape and portrait, the view controller's viewWillTransition(to:with:) is called to reflect the change in size between orientations. So far so good. Now put the fully open Duo in landscape. Then partially close the Duo. The presented view controller will automatically move off to the left half of the screen to avoid the fold. That's expected. However, the view controller's viewWillTransition(to:with:) is NOT called in this case even though its size has changed. Does this seem like a bug or is this somehow expected? I have a particular view controller that needs to know its size has changed so it can make some adjustments. Other lifecycle methods such as viewDidLayoutSubviews are called but I'd prefer to have viewWillTransition(to:with:) called.
Replies
0
Boosts
0
Views
273
Activity
7h
How does a view controller know when the reserved regions change?
I've looked at the UIKit docs for UIView reservedRegions(kind:options:). I've watched the video "Strike a pose with adaptive layouts on iPhone Duo". So I know how to get the current reserved regions. But I can't find the APIs to know when the reserved regions change. This means I can setup my custom view controller with the reserved regions that exist when the view controller is first displayed. But if the user changes the Duo, say from fully open to partially open, what API is triggered that lets me know that I need to call reservedRegions(kind:options:) and update the layout as needed? I played around with UIHingeInteraction but that isn't the right approach. In most cases I tried calling reservedRegions(kind:options:) on each call to the interaction handler but I almost always got the wrong results (maybe a simulator issue?). And of course that interactiion handler will be called a lot just to report the new fold angle. I also tried various UIViewController methods for size changes and registered for size class changes. None of these were appropriate. I just need a single notification that the Duo went from fully open to partially open, partially open to fully open, and partially open between landscape/portrait so that I can call reservedRegions(kind:options:) and get the correct, current divider info. What am I missing? My use case is for a custom fullscreen view controller that needs to layout a few items based on whether the Duo is fully open or partially open and whether the fold is horizontal or vertical. Unless I'm mistaken this precludes the use of UIArrangementViewController since I only have one view controller with one set of content to display. Showing the view controller as a form sheet, page sheet, or popover won't work since I need this to be fullscreen. I just need the fullscreen content to adjust for any fold (reserved region).
Replies
4
Boosts
0
Views
308
Activity
12h
Hiding Vertical Tabbar on Iphone Duo UIKit/SwiftUI
Hi apple team, we have a requirement where on certain pages, tabbar should not be displayed. it worked on non iphone-duo phones by utilizing tabbar.isHidden = true yet on iphone duo, it didnt work. is it a bug or are there a missing api that i didnt impl? thanks
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
3
Boosts
0
Views
359
Activity
1d
iPadOS 26: App crashes in system keyboard – NSAllocateMemoryPages failure in -[TIImageCacheItem encodeWithCoder:]
Since iPadOS 26 we have been seeing a crash inside the system keyboard. It happens while the system keyboard renders key images. Our code is not on the crashing stack. Crash The app is terminated by an uncaught NSInvalidArgumentException. The NSXPC encoder fails to allocate a very large buffer while a keyboard image cache item is being encoded: NSInvalidArgumentException: *** NSAllocateMemoryPages(60003072) failedRequested sizes seen across reports: 60,003,072 / 60,558,656 / 78,724,160 / 240,001,920 / 933,149,952 bytes. Xcode Organizer groups these reports under the signature TextInput: -[TIImageCacheItem encodeWithCoder:] + 276. Relevant frames (main thread, simplified): objc_exception_throw NSAllocateMemoryPages NSXPCEncoder (encoding) -[TIImageCacheItem encodeWithCoder:] + 276 (TextInput) TIDispatchSync TIImageCacheClient UIKeyboardCache -[UIKBKeyView displayLayer:] ... UIApplicationMainScope (about 3 months of data) 327 crashes from 43 users. iPad only. iPadOS 26.1 – 26.7.1. No crashes on iPhone and none on iPadOS 18 or earlier. No single iPadOS 26 minor version stands out. The first occurrence did not line up with any release of our app. Our keyboard-related code did not change at that time. Free memory at crash time ranges from 33 MB to 4.8 GB. Some crashes happen within 40 seconds of launch. This looks like an abnormally large encode request, not memory pressure or a leak in the app. All affected users use the zh_CN locale. Context The screen has a plain UITextField, the standard system keyboard, and no custom inputView. It also has a UIIndirectScribbleInteraction for Apple Pencil handwriting. The crash happens shortly after the keyboard appears. Breadcrumbs show UICompatibilityInputViewController, UISystemInputAssistantViewController and UIPredictionViewController being set up just before the crash. Many crashes happen when the app window is not full screen (Split View / Stage Manager). For example, a 629.5 pt wide app window on a 1180 pt screen, or 936×954 on 1373×954. Some devices were rotating frequently. In a few cases there was a rapid burst of multi-tap gestures about 20 ms apart just before the crash (Pencil/Scribble-like input). What we tried We could not reproduce it on our own iPads running iPadOS 26. Memory stays flat and there is no crash. Questions Is this a known issue in the iPadOS 26 keyboard image cache (TIImageCacheItem)? Is there a recommended workaround on the app side, for example avoiding certain input view reloads or trait changes while the keyboard is visible?
Replies
1
Boosts
0
Views
39
Activity
1d
iPhone Duo bug: Popovers presented with their arrow restricted to left/right appear partially offscreen
The following has been reported as FB25281446 I've come across a serious user interface issue on the iPhone Duo when you show a popover with the permitted arrow direction set to only left or right. Here's a screenshot from a test app of a correct popover shown from a form sheet on a fully open iPhone Duo: Here's the same UI after switching the Duo from fully open to partially open: Note how the popover is now partially offscreen. Oddly the toolbar is still kept onscreen. You are unable to scroll to the last rows of the table view. You can replicate this problem by taking the following steps: 1) Create a new Storyboard/Swift app with Xcode 27.2 RC 2) Edit the Main storyboard by removing the default view controller 3) Add a navigation controller (and its default root view controller) 4) Set the navigation controller as the initial view controller 5) Replace the contents of the default ViewController.swift file with the following code: ```swift import UIKit class ViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() let showPopover = UIBarButtonItem() // Show the view controller as a popover let action = UIAction(title: "Popover", handler: { _ in let vc = ViewController() let nc = UINavigationController(rootViewController: vc) nc.modalPresentationStyle = .popover nc.popoverPresentationController?.sourceItem = showPopover nc.popoverPresentationController?.permittedArrowDirections = .any self.present(nc, animated: true) }) showPopover.primaryAction = action self.navigationItem.rightBarButtonItem = showPopover // Show the view controller in a form sheet let showFormSheet = UIBarButtonItem() let action2 = UIAction(title: "FormSheet", handler: { _ in let vc = ViewController() // Applying a preferred content size affects the results in one // case - the popover works correctly when the Duo is fully open // in portrait and you show a popover from a form sheet. //vc.preferredContentSize = .init(width: 540, height: 620) let nc = UINavigationController(rootViewController: vc) nc.modalPresentationStyle = .formSheet self.present(nc, animated: true) }) showFormSheet.primaryAction = action2 self.navigationItem.leftBarButtonItem = showFormSheet // Show some dummy toolbar items to help demonstrate the issue self.navigationController?.isToolbarHidden = false self.toolbarItems = [ UIBarButtonItem(systemItem: .add), UIBarButtonItem.flexibleSpace(), UIBarButtonItem(systemItem: .action), ] } } extension ViewController { override func numberOfSections(in tableView: UITableView) -> Int { return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 20 } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell") ?? UITableViewCell(style: .subtitle, reuseIdentifier: "cell") cell.textLabel?.text = "Row \(indexPath.row)" cell.detailTextLabel?.text = "Tap me to show popover" return cell } // Show a popover from a selected cell. The popover will appear partially // offscreen under the following conditions: // - When the Duo is fully open and landscape: // - A row near the bottom of the root view controller is selected. // - When the Duo is fully open and portrait: // - A row near the bottom of the root view controller is selected. // - A row near the bottom of a form sheet is selected (unless the form // sheet has a preferredContentSize set). // - When the Duo is partially open and landscape or portrait: // - A row near the bottom of the root view controller is selected. // - A row near the bottom of a form sheet is selected. // - If you then fully open the Duo, the partially offscreen popover // moves into the correct, fully visible position. // Note that the toolbar of the partially offscreen popover stays on screen. // // There are no issues when the Duo is closed. override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { if let cell = tableView.cellForRow(at: indexPath) { let vc = ViewController() let nc = UINavigationController(rootViewController: vc) nc.modalPresentationStyle = .popover nc.popoverPresentationController?.sourceItem = cell // The problem only happens if the arrow is limited to left or right nc.popoverPresentationController?.permittedArrowDirections = [ .left, .right ] self.present(nc, animated: true) } } } ``` 6) In the Main storyboard, change the root view controller's class to ViewController 7) Build and run the app against an iPhone Duo running iOS 27.2 RC You can now replicate the two screenshots by fully opening the Duo and putting it in landscape. Then do the following: 1) Tap the FormSheet button 2) In the form sheet table, select a row near the bottom of the form sheet 3) Note the popover appears correctly with an arrow on the right side pointing to the selected row 4) Now put the iPhone Duo in the partially open mode (still landscape) 5) Note the problem. The popover moves partially offscreen. You can’t even scroll to the last row. The popover show remain fully onscreen and of reasonable height just like it was when the Duo was fully open. As noted in the ViewController.swift file, the issue appears under the following conditions: - When the Duo is fully open and landscape: - A row near the bottom of the root view controller is selected. - When the Duo is fully open and portrait: - A row near the bottom of the root view controller is selected. - A row near the bottom of a presented form sheet is selected (unless the form sheet has a preferredContentSize set). - When the Duo is partially open and landscape or portrait: - A row near the bottom of the root view controller is selected. - A row near the bottom of a presented form sheet is selected. - If you then fully open the Duo, the partially offscreen popover moves into the correct, fully visible position.
Replies
1
Boosts
0
Views
279
Activity
1d
Best Practice to adopt iPhone Duo
What's the best practices to adopt iPhone Duo for a production UIKit app? What few things we need to consider during the development? "As long as we use auto layout, it should be fine" is this correct term for iPhone Duo? Meaning, as long as our app use proper auto layout, our app should be able to support iPhone Duo properly.
Replies
2
Boosts
0
Views
285
Activity
2d
API request: Query default toolbar item size
On the iPhone Duo, default toolbar items are 48 pt instead of 44 pt, even when the navigation bar is horizontal. There doesn't seem to be a public API to query this size, making it difficult to match custom toolbar items to system controls without device-specific checks. I've filed FB25271102 requesting an API to expose the default toolbar item dimensions, ideally through a SwiftUI environment value.
Replies
0
Boosts
0
Views
59
Activity
2d
Vertical tab bar doesn't appear when tab bar controller is added to view controller while iPhone Duo is unfolded
Hi, I would like to share an issue with UITabBarController's vertical tab bar and iPhone Duo's unfolded pose. On iPhone Duo (27.2 beta 3), when tab bar controller is added to the view controller while in unfolded pose, the vertical tab bar doesn't appear unless the tab bar controller view's frame is set manually before adding it to the parent's view. Show any VC. Use unfolded Duo pose. After some time/on button press add a UITabBarController to it: (https://developer.apple.com/documentation/uikit/creating-a-custom-container-view-controller#Add-a-child-view-controller-programmatically-to-your-content) with Auto Layout constraints. Vertical tab bar does not appear. Fold and unfold the device. The tab bar appears. Expected: Tab bar appears after adding the UITabBarController in unfolded Duo pose. Actual: Tab bar does not appear after adding the UITabBarController in unfolded Duo pose. In Feedback Assistant report (FB25261013) I attached minimal reproduction example and recordings showing the different behavior in folded and unfolded poses and behavior with manual frame application fix (commented out in minimal reproduction example). Minimal reproduction example: // SceneDelegate.swift import UIKit class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } window = UIWindow(windowScene: windowScene) window?.rootViewController = ViewController() window?.makeKeyAndVisible() } } // ViewController.swift import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .systemBackground let button = UIButton(configuration: .filled(), primaryAction: UIAction(title: "Show Tab Bar Controller") { [weak self] _ in self?.showTabBarController() }) button.translatesAutoresizingMaskIntoConstraints = false view.addSubview(button) NSLayoutConstraint.activate([ button.centerXAnchor.constraint(equalTo: view.centerXAnchor), button.centerYAnchor.constraint(equalTo: view.centerYAnchor), ]) } private func showTabBarController() { let tabBarController = UITabBarController() tabBarController.tabs = ["First", "Second", "Third"].map { title in UITab(title: title, image: UIImage(systemName: "circle"), identifier: title) { _ in let viewController = UIViewController() viewController.view.backgroundColor = .systemBackground return viewController } } addChild(tabBarController) // Uncomment to show the tab bar on the unfolded iPhone Duo. tabBarController.view.frame = view.bounds view.addSubview(tabBarController.view) tabBarController.view.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ tabBarController.view.topAnchor.constraint(equalTo: view.topAnchor), tabBarController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor), tabBarController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), tabBarController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), ]) tabBarController.didMove(toParent: self) } } Thank you in advance.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
1
Boosts
0
Views
378
Activity
3d
Public API for a transparent PencilKit layer above another foreground app?
Is there a public iPadOS API (or entitlement) that lets a third-party app present a transparent, interactive drawing layer over another foreground app? What I want: App A (Safari, a video app, etc.) stays in the foreground and remains visible. My app draws Apple Pencil ink on a transparent layer above that content. Pencil strokes go to my layer. I do not need to read the pixels underneath. This must be possible with public APIs only, for an App Store app. What I already checked, and why it does not match: UIWindow / windowLevel: only orders windows inside my own scene, not above another app. Slide Over, Split View, Stage Manager: a separate window beside or over the other app, not a transparent ink layer on its pixels. Picture in Picture with a custom content source: a floating window, not a full-screen transparent canvas. ReplayKit / ScreenCaptureKit: capture or broadcast, not an interactive overlay. Screen Time shields / AssistiveTouch-style overlays: system UI, not available to third-party apps. I am not asking for a review of an app concept. I am asking whether any current public API can do this, and if not, which of the options above is the supported boundary. Environment: iPadOS 26, Xcode 26, PencilKit.
Replies
0
Boosts
0
Views
48
Activity
3d
iPhone Duo - Buggy margin shift while dragging down a modal view controller
Has anyone else run into this issue? If you present a view controller and set its isModalInPresentation property to true, then when you try to drag down the view controller (which can't be dismissed), the view controller's content on the side of the vertical toolbar is shifted inward. This happens on a closed iPhone Duo. Even the title shifts if the vertical toolbar is on the left side. To replicate, create a Swift/UIKit project. Edit the main storyboard by deleting the default view controller scene and add a navigation controller (and its default root view controller). Set the class for the root view controller to ViewController. Then replace the default ViewController.swift code with the following: import UIKit class ViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() let modal = UIBarButtonItem(systemItem: .add, primaryAction: .init(handler: { _ in let vc = ViewController() vc.title = "Some Modal" // If the following is true, dragging the modal view controller // down results in the table margins being shifted on whichever // side has a vertical toolbar. This happens on the iPhone Duo // when closed in either portrait or landscape. Whichever side // has the vertical toolbar gets shifted. // When the iPhone Duo is open the modal appears in a form sheet // and it does not demonstrate the issue. // The navigation title is also affected when the iPhone Duo is // closed and in landscape with the vertical toolbar on the left. // If the following is false, dismissing the modal by dragging it // down does NOT result in any change in the table's margins. vc.isModalInPresentation = true // false let nc = UINavigationController(rootViewController: vc) self.present(nc, animated: true) })) navigationItem.rightBarButtonItem = modal } } extension ViewController { override func numberOfSections(in tableView: UITableView) -> Int { 2 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 4 } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // Some simple table cells to demonstrate the margin shift let cell = tableView.dequeueReusableCell(withIdentifier: "cell") ?? UITableViewCell(style: .value1, reuseIdentifier: "cell") cell.textLabel?.text = "Some Text" cell.detailTextLabel?.text = "Value" cell.accessoryType = .disclosureIndicator return cell } } Build and run the app with Xcode 27.1 and run it on an iPhone Duo (simulated or real). Tap the + icon to display the modal view controller (just another instance of ViewController). Now try to drag down the modal view controller. Notice the margin shift if the Duo is closed. There is no margin shift is the Duo is open or if isModalInPresentation is set to false. This has been reported as FB25221160.
Replies
1
Boosts
0
Views
603
Activity
4d
UIDesignRequiresCompatibility for Xcode27
Hallo everyone, We are building our app with Xcode 27 and noticed that UIDesignRequiresCompatibility still appears to be honored on iOS 26 devices. Questions: Could you confirm whether this key is still supported on iOS 26 when built with Xcode 27? If our deployment target includes iOS 26, should we keep the key for backward compatibility, or is Apple's recommendation to remove it entirely? Additionally, are there any risks associated with removing it for iOS 26 users?
Replies
1
Boosts
0
Views
439
Activity
4d
Third-party keyboards get an extra 17pt gap at the top after switching apps on iOS 27 beta.
Feedback submitted: FB24460699 The sample projects are attached to the feedback report. Environment:iOS27 Beta6; iPhone 17Pro Problem:I have encountered a consistently reproducible third-party custom keyboard layout issue in iOS 27.0 beta 1 through beta 6. The custom keyboard initially appears correctly. If I switch apps while the text input remains focused and the keyboard remains visible, and then return to the host app, the system adds a 17-point area above the custom keyboard extension. Steps to reproduce Install and enable a third-party custom keyboard. Switch to the sample custom keyboard and open the host app so that the text editor in the center receives focus. Do not dismiss the keyboard or remove focus from the editor. Return to the Home Screen or switch to another app. Return to the host app. A new blank area now appears above the custom keyboard content. I tested both a system-determined extension view height and an extension view explicitly constrained to 180 points. Both configurations produce exactly the same change. After the foreground transition, the following extension-side values remain unchanged: view.bounds inputView.bounds extension.window.bounds view.safeAreaInsets, which remains {0, 0, 0, 0} The requested 180-point extension height Only the system keyboard frame received by the host app increases by 17 points. I also drew a rounded pink boundary inside the transparent extension root view. When the issue occurs, the new area appears outside that boundary. I tested several third-party keyboards and reproduced the issue with all of them. This suggests that the behavior is caused by iOS rather than by my app. Questions On iOS 27, is it expected behavior for a custom keyboard to gain a 17pt top area after its host app returns from the background? If this is a system issue, is there any workaround that can be used until it is fixed?
Replies
9
Boosts
8
Views
1.4k
Activity
4d
Can an App Clip share an image to Apple Notes through the share sheet?
My App Clip shows an image, and I need that image to end up in Apple Notes as a new note with as few taps as possible. The plan is to present UIActivityViewController with the image, then the user taps Notes, then Save. I know clips can’t use PhotoKit, so “Save Image” is likely out. What I can’t find documented is whether Notes, or any other app’s share extension, still shows up in a clip’s share sheet and actually saves. Has anyone tried this? I don’t have a paid account yet to test it myself. If someone could run a one-file test clip, I can send the code.
Replies
0
Boosts
0
Views
48
Activity
4d
Tapping the top area of iPhone Duo does not respond in Device Hub
I’m simulating an iPhone Duo using Xcode 27.1 beta, and I’m having trouble tapping buttons placed near the top of the screen. It seems that the top ~20 pixels of the screen are not responding to taps. In my ViewController, preferredScreenEdgesDeferringSystemGestures returns .all, so system gestures should require two swipes to be triggered. However, a simple tap in this area does not seem to be recognized. This appears to happen only on iPhone Duo; taps work normally on other iPhone models. Does anyone know whether this behavior is expected to occur on the actual iPhone Duo hardware as well, or is it specific to the simulator? For reference, the buttons are positioned according to LayoutMarginsGuide with Safe Area. FB24914903 I wonder if anyone knows how to get the top margin size programmatically.
Replies
1
Boosts
1
Views
682
Activity
6d
How to distinguish a foreground cold launch from a background task cold launch?
I'm trying to determine why my UIKit application was launched, specifically whether it was launched by the user or by the system to execute a background task. I recently added a BGProcessingTask to update data overnight. Consider this scenario: The user backgrounds the app at 10 AM. A background task is scheduled with earliestBeginDate set to 4 AM the following day. During those 18 hours, iOS terminates the app's process to reclaim memory. iOS later decides to execute the scheduled background task and launches a new app process in the background. My understanding is that this results in a cold launch, including a call to application(_:didFinishLaunchingWithOptions:) and the initialization performed there. This matters because some of our startup initialization triggers network requests that are unnecessary when the app is launched only to perform a background task. Questions 1. Can iOS relaunch a previously terminated app to execute a scheduled BGProcessingTask? I'm referring specifically to termination by the system (for example, memory pressure), not the user force-quitting the application. 2. Is there a reliable way to distinguish a foreground cold launch from a background task cold launch inside application(_:didFinishLaunchingWithOptions:)? I tried checking UIApplication.shared.applicationState, but in my testing it was .background during didFinishLaunchingWithOptions in both scenarios, including when the user launched the app by tapping its icon. Is there another documented API or launch context that reliably identifies why the process was started? I'm aware that iOS provides launch options for certain launch scenarios, but I'm specifically interested in distinguishing a background task-triggered cold launch from a user-initiated foreground cold launch. 3. If this distinction cannot be made reliably during didFinishLaunchingWithOptions, what is the earliest lifecycle callback where I can determine that the app is entering the foreground? For example, should foreground-specific initialization be deferred until scene(_:willConnectTo:options:), sceneWillEnterForeground(_:), or another callback? I'm specifically looking for a documented and reliable lifecycle signal, rather than heuristics or arbitrary delays. The goal is to avoid unnecessary startup initialization and network requests when iOS launches the application solely to execute a background task.
Replies
2
Boosts
0
Views
184
Activity
1w
iPhone Duo: Making a custom popup avoid the hinge by presenting it as an arrowless popover
Background On iPhone Duo, when the device is unfolded and then partially folded, system alerts (UIAlertController) are automatically repositioned so they stay clear of the hinge. Apple's Tech Talk confirms this: "The system automatically repositions components around the reserved region." Our app uses a custom popup: a view controller presented with .overFullScreen that lays out its own dimming view and a custom-drawn view (here, a coupon ticket with notched edges) in the center of the screen. This popup is not repositioned. It stays centered on screen, right on top of the fold. The recommended approach for custom UI is to query view.reservedRegions(kind: .division) and lay out around the fold manually. Before going that route, I tried something simpler. What I tried The Tech Talk lists popovers among the components the system repositions. So I presented the same custom view as a popover with no arrow, anchored to the center of the presenting view: final class CouponPopoverViewController: UIViewController, UIPopoverPresentationControllerDelegate { private let ticketView = CouponTicketView() // the custom popup view init(centeredIn sourceView: UIView) { super.init(nibName: nil, bundle: nil) modalPresentationStyle = .popover guard let popover = popoverPresentationController else { return } popover.sourceView = sourceView popover.sourceRect = Self.centerPoint(of: sourceView.bounds) popover.permittedArrowDirections = [] // Drop the system popover chrome so only the custom view (and its own shadow) is visible. popover.popoverBackgroundViewClass = ClearPopoverBackgroundView.self popover.delegate = self } required init?(coder: NSCoder) { fatalError() } override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .clear ticketView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(ticketView) NSLayoutConstraint.activate([ ticketView.topAnchor.constraint(equalTo: view.topAnchor), ticketView.bottomAnchor.constraint(equalTo: view.bottomAnchor), ticketView.leadingAnchor.constraint(equalTo: view.leadingAnchor), ticketView.trailingAnchor.constraint(equalTo: view.trailingAnchor) ]) preferredContentSize = ticketView.systemLayoutSizeFitting( CGSize(width: 300, height: UIView.layoutFittingCompressedSize.height), withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel ) } private static func centerPoint(of bounds: CGRect) -> CGRect { CGRect(x: bounds.midX, y: bounds.midY, width: 0, height: 0) } // Keep it a popover on iPhone instead of adapting to a sheet. func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle { .none } // Re-anchor to the center after rotation or fold changes. func popoverPresentationController(_ popoverPresentationController: UIPopoverPresentationController, willRepositionPopoverTo rect: UnsafeMutablePointer<CGRect>, in view: AutoreleasingUnsafeMutablePointer<UIView>) { rect.pointee = Self.centerPoint(of: view.pointee.bounds) } } /// A popover background that draws nothing: no arrow, no insets, no default appearance. final class ClearPopoverBackgroundView: UIPopoverBackgroundView { override class func arrowBase() -> CGFloat { 0 } override class func arrowHeight() -> CGFloat { 0 } override class func contentViewInsets() -> UIEdgeInsets { .zero } override class var wantsDefaultContentAppearance: Bool { false } override var arrowOffset: CGFloat { get { 0 } set {} } override var arrowDirection: UIPopoverArrowDirection { get { .any } set {} } } Result Partially folded, portrait (hinge runs horizontally across the middle of the screen): Before: the custom popup (.overFullScreen) stays centered, right across the hinge. After: the same view presented as an arrowless popover moves into the top half, clear of the hinge. Partially folded, book pose (vertical hinge): the popover moves to the leading page, clear of the hinge. This matches where a system UIAlertController goes in the same pose. I also checked that the popover shows correctly on the outer display (closed) and on a non-Duo iPhone (iPhone 18 Pro, iOS 27.0). Tested on: iPhone Duo simulator (iOS 27.1), Xcode 27.1 RC (27A9275) iPhone 18 Pro simulator (iOS 27.0) Things to handle when switching to a popover Tap-outside dismissal: Popovers dismiss on outside taps by default. Set isModalInPresentation = true or return false from presentationControllerShouldDismiss(_:) if the popup should only close via its buttons. Dimming: Popovers don't dim the background like a typical custom popup (compare the before and after screenshots). Add your own dimming view if needed. Chrome: By default, the system draws its own background behind the content. For a custom-shaped view, this shows through any transparent areas and clips the view's shadow. A UIPopoverBackgroundView subclass that draws nothing (above) removes it. Sizing: Set preferredContentSize explicitly. Recompute it for dynamic content and Dynamic Type. Questions This works well in my testing, but I couldn't find any documentation saying that an arrowless popover anchored to the center gets the same hinge avoidance as alerts. Is this supported behavior that we can rely on going forward? Or is reservedRegions(kind:options:) with manual layout the only recommended approach for custom popups? It would also be great to have a public API that lets custom presentations opt into the same hinge-avoidance placement that system alerts use. Hope this helps anyone else dealing with custom popups on iPhone Duo.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
2
Boosts
0
Views
165
Activity
1w
iPhone Duo - Current SDK State
We are just 9 days before the iPhone Duo release, and the SDK is still in a pretty bad state, at least for the Keyboard Extension: Hinge detection doesn't work Reserved area detection doesn't work needsInputModeSwitchKey returns false even though iOS doesn't display its own globe button Switching between closed and fully open state loses text field focus and the keyboard disappears (regression bug - it worked in Beta 1) It's unacceptable that, with such a short release date, we still don't have a stable SDK... I expect the iPhone Duo release to be one of the buggiest releases Apple has ever done.
Replies
7
Boosts
0
Views
546
Activity
1w
UISheetPresentationController issues on iPhone Duo
I have an App where I use the UISheetPresentationController to present a menu as a "drawer" (like the "FindMy" or "Maps") App. Because the sheet is presented over a map, I made the sheet semi-transparent/blurry, so the Map shines through, which looks nice. The sheet is using a UITableView with the "insetGroup" style, so the table cells have the nice rounded borders and there are margins to the sheet borders. When running the App on the iPhone Duo (Simulator) on the outer display, the tableView does no longer respect the "insetGroup" style, it is rendered like it would have the "plain" style, which destroys everything that look good. No rounded borders, no margins. However if I opt-out of the automatic "vertical toolbar behavior" (overriding preferredVerticalBarBehavior so it returns "disabled"), then everything looks great again, however then the sheet content might overlap with the sidebar icons and camera because it now covers the whole area up to the right screen border. Is this supposed to be this way (if yes, why?), is there a way to fix this, or do we have to wait for a bugfix within iOS 27.1? The tableview still claims to have the "insetGrouped" style, just it does not render this way. I did not see any similar issues under other circumstances. Only UISheetPresentationController seems to be affected by this. Is there a way to correctly detect if the App is running on an iPhone Duo, so we could use this detection to add workarounds for such issues?
Replies
4
Boosts
1
Views
631
Activity
1w
How to get UISheetPresentationController width to adjust for vertical toolbar on iPhone Duo?
If you run Safari in the iPhone Duo simulator and choose to share something you get a screen similar to the following: In my own app, if I present a UIActivityViewController I get a similar result. Note that the share sheet does not cover the vertical toolbar at all. So my question is how to present a UISheetPresentationController to look the same way. In other words, how to get the width of the UISheetPresentationController to take into account the vertical toolbar? All of my existing code to create and present a UISheetPresentationController result in the UISheetPresentationController taking the full width of the screen. The contents of the sheet take the safe area into account, but that's not the same result. I need the sheet itself to be narrower. I don't see an API for this. Or does this require more complicated presentation controller / delegate setup? Here is some relevant code in the view controller that I want displayed in the sheet: self.modalPresentationStyle = .popover self.presentationController?.delegate = self if let sheet = popoverPresentationController?.adaptiveSheetPresentationController { popoverPresentationController?.passthroughViews = [] sheet.detents = [ .medium(), .large() ] sheet.largestUndimmedDetentIdentifier = nil sheet.prefersGrabberVisible = false sheet.prefersScrollingExpandsWhenScrolledToEdge = true sheet.prefersEdgeAttachedInCompactHeight = true sheet.widthFollowsPreferredContentSizeWhenEdgeAttached = true } Or maybe UISheetPresentationController is the wrong approach.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
0
Boosts
0
Views
109
Activity
1w
UIAlertController.addTextField results in broken text field in 27.1
I just downloaded Xcode 27.1 to test out the iPhone Duo simulator, and I notice that UIAlertController.addTextField, which was working fine in 27, is now very broken, resulting in a text field that is squashed vertically and pushed over to the right in the alert sheet. This is very easy to reproduce - the following code will show the problem if you build in Xcode 27.1 and run on iOS 27.1 or iOS 27.2: let alert = UIAlertController(title: "Create Something", message: "Enter a title.", preferredStyle: .alert) alert.addTextField { textField in textField.placeholder = "Title" } alert.addAction(UIAlertAction(title: "Cancel", style: .cancel)) present(alert, animated: true) The bug isn't limited to the Duo, but can also be seen on an iPad (and probably a regular phone). I would post a screenshot, but the last time I tried that, the forum software erroneously banned me for two weeks. I have reported this as bug #FB24889500, but given that we use alerts with text fields for users adding new items to the outline in our app, something the user does a lot, I'm wondering if there is a workaround, since this is going to make our app look very buggy.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
1
Boosts
2
Views
334
Activity
1w