Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.

All subtopics
Posts under UI Frameworks topic

Post

Replies

Boosts

Views

Activity

X button disappeared on iPadOS 26.4 in MFMailComposeViewController
I’m using MFMailComposeViewController to send emails from my app. Since updating to iPadOS 26.4, there is no way to cancel the mail composer because the “X” button in the top-left corner has disappeared. On iPhone with iOS 26.4, everything still seems to work as expected. Is this a known issue, or am I missing something? Has anyone else experienced this, or found a workaround?
Topic: UI Frameworks SubTopic: UIKit
13
1
2.5k
2w
Supported way to put an iPhone Duo simulator into the unfolded state programmatically
The Duo simulator boots showing only the outer display: the window is fixed at 382×644 pt and our layout classifier always reports the compact stack mode. We measured this on two separate clean boots (shutdown, erase, boot). xcrun simctl help lists no subcommand for folding, posture, or selecting the inner display — we read the full list. xcrun simctl io screenshot does reveal a second display (LCD-1, 2007×2853 px, aspect 0.70, close to the 669×951 inner portrait size). Unfolding manually in the Simulator UI works and the app then renders the two-column layout correctly, but we could not find a programmatic equivalent. Is there a supported way to unfold a Duo simulator from the command line or from XCTest?
Topic: UI Frameworks SubTopic: SwiftUI
4
6
1.5k
2w
Supported public API for individual Magic Mouse contacts in a sandboxed macOS app
We are investigating a Mac App Store version of an app that provides tap-to-click and two-finger dragging for Magic Mouse. We need contact identity, finger positions, touch-down/up, and simultaneous contact count while the pointer is over other apps. We want a supported public API and normal App Sandbox entitlements. We are not asking how to use a private framework or bypass the sandbox. Environment tested: macOS 27.0.1 (26A434), Apple Silicon arm64, Bluetooth Magic Mouse vendor 0x004c / product 0x0269. Both IOHIDManager/IOHIDDevice and CoreHID are tested in a standalone sandboxed diagnostic app, signed with a persistent local certificate. Sandbox is confirmed via SecTask, Input Monitoring granted via System Settings and confirmed by IOHIDCheckAccess. Entitlements: app-sandbox, device.usb, device.bluetooth. No temporary exceptions, no seizeDevice, no SetReport or device reconfiguration. The normal app was still running during capture; we can repeat with it stopped if necessary. We discover four mouse interfaces, primary usage pairs FF00/03, FF00/12, FF00/0B, and 01/02. All open successfully after Input Monitoring is granted. The latter descriptor includes a 0D/05 Touch Pad collection but only vendor-defined payload for that collection. Standard individual contact fields are not declared. Input report IDs 0x3f and 0x44 are declared in addition to mouse report 0x12. Two 60-second captures, one per API, include user-performed phases for hands off, one finger, two fingers, moving each finger independently, scrolling, and physical movement/click. IOHID received 1310 input reports; CoreHID received 2349. Every report was ID 0x12, 8 bytes. Element updates were exclusively Generic Desktop X/Y, without individual contact identity or finger coordinates. Neither 0x3f nor 0x44 was delivered. The diagnostic client only reads mouse interfaces and does not read keyboard input. Questions: Is there a supported public API to observe global individual Magic Mouse contacts in an App Sandbox app, including when another app is active? Is individual-contact data expected to be available through IOHIDDevice input reports or CoreHID for this device? If so, what documented setup and entitlements are required? Are the declared vendor-defined reports 0x3f/0x44 intended for third-party clients, and is their payload documented for this purpose? If there is no supported public route, should this functionality remain outside the Mac App Store, or is there a supported capability path we should investigate? The diagnostic source is independent of the production app. Please advise whether further captures with all other input utilities stopped would help distinguish a driver/client interaction from an unsupported use case. No logs or source attachments are included in this public post.
0
0
150
2w
Mission Control Window Management update
Dear Apple, I am sending feedback regarding the desktop management of macOS to improve the user experience. Mission Control currently only has a “+” button to the right, meaning that all new desktops are forced to the right side of the line. Adding an identical “+” button to the left will increase ease of using the OS, as I don’t necessarily need every new desktop to be on the right side. This will increase usability and make using desktops significantly easier than manually dragging them into the needed positions every time I add a desktop. Another thing is that when I maximize apps, all desktops go to the left by one spot. There should be a setting where you can control where desktops go when maximizing screens, either you want every desktop to go to the right or the left. This makes things easier as sometimes I have my main app on the right, with all the multi-tasking on the left. If desktops move to the right instead of the left, no open apps will be interfered with. (Please put this setting in the “Desktop and Dock” section). I have been using macOS for a year now, and those details were quite clear. Please consider this as a software update for over 100 million Macbook users, increasing usability without changing the OS so much people barely know how to use it. I have been concentrating significantly on macOS lately, noticing an upgrade followed by another, and is how I noticed this. Please consider this a fresh start for my feedback. I apologize for my previous un-trained replies. I am not a trained professional, but I genuinely care about improving the user experience and wanted to share these layout ideas. I promise to keep my interactions respectful of the forum guidelines from now on. May these desktop management ideas be considered? Thanks, Alyaman
Topic: UI Frameworks SubTopic: General
2
0
446
2w
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
862
3w
Binding Picker to enum value in SwiftData struct
I have a SwiftData @Model class that has a var of Media. enum Media: String, CaseIterable, Identifiable, Codable { case dvd = "DVD" case bluray = "Blu-ray" case bluray4k = "Blu-ray 4k" var id:String { self.rawValue } } In one of my views, I'm trying to show a Picker with the enum values, and then bind the @Model's field to the Picker's selection. I've been trying all kinds of things from suggesting I'm finding online. Here's a poorly pasted version of what my last attempt looks like (I'm sure I have the wrong number of closing curly brackets, but just ignore that): struct DetailView: View { @Binding var item:Item; // The @Model class. @State private var selectedMedia:Media = .dvd; var body:some View { Picker("Media", selection:$selectedMedia) { ForEach(Media.allCases, id:\.self) { media in Text(media.rawValue); } } .labelsHidden() .onAppear() { selectedMedia = item.media; } .onChange(of:selectedMedia) { oldValue, newValue in item.media = selectedMedia; } } } What's a good way to make this work? Am I going to have to use a custom formatter of some type, bind the Picker to a string, and convert the selected value with the formatter?
1
0
413
3w
Crash in ResolvedStyledText.draw
Hi! We're trying to investigate the following crash, but have a little bit hard time of understanding what the reason for it might be. I assume this might be us trying to reduce the state too often? Thread 0 Crashed: 0 libswiftCore.dylib 0x00000001884fec20 _swift_release_dealloc + 48 (:-1) 1 libswiftCore.dylib 0x00000001884fd938 bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 240 (:-1) 2 SwiftUICore 0x000000018ed7f940 specialized _ArrayBuffer._consumeAndCreateNew(bufferIsUnique:minimumCapacity:growForAppend:) + 244 (:-1) 3 SwiftUICore 0x000000018ed7ecdc specialized Array._createNewBuffer(bufferIsUnique:minimumCapacity:growForAppend:) + 16 (:-1) 4 SwiftUICore 0x000000018ed7ecdc specialized Array._reserveCapacityAssumingUniqueBuffer(oldCount:) + 24 (:-1) 5 SwiftUICore 0x000000018ed7ecdc specialized Array.append(_:) + 56 (:-1) 6 SwiftUICore 0x000000018ed7ecdc NSAttributedString.MetricsCache.metrics(requestedSize:layoutMargins:wantsNumberOfLineFragments:context:) + 2996 (:-1) 7 SwiftUICore 0x000000018eda7afc ResolvedStyledText.StringDrawing.draw(in:with:applyingMarginOffsets:containsResolvable:context:renderer:) + 208 (:-1) 8 SwiftUICore 0x000000018ee5fe90 ResolvedStyledText.draw(in:with:applyingMarginOffsets:context:renderer:) + 100 (:-1) 9 SwiftUICore 0x000000018ee5fe90 closure #1 in DisplayList.ViewUpdater.Platform.updateItemView(_:index:item:state:) + 176 (:-1) 10 SwiftUICore 0x000000018ee5f7a0 closure #1 in PlatformDrawableContent.draw(in:size:contentsScale:state:) + 20 (:-1) 11 SwiftUICore 0x000000018ee5f7a0 CGContextRef.withPlatformContext(do:) + 56 (:-1) 12 SwiftUICore 0x000000018ee5f7a0 PlatformDrawableContent.draw(in:size:contentsScale:state:) + 136 (:-1) 13 SwiftUICore 0x000000018ee5fd94 CGDrawingLayer.draw(in:) + 88 (:-1) 14 SwiftUICore 0x000000018ee5fd94 @objc CGDrawingLayer.draw(in:) + 224 (:-1) 15 QuartzCore 0x000000018ad2304c CABackingStoreUpdate_ + 344 (:-1) 16 QuartzCore 0x000000018ad22df0 invocation function for block in CA::Layer::display_() + 72 (:-1) 17 QuartzCore 0x000000018ad257c4 CA::Layer::display_() + 2180 (:-1) 18 QuartzCore 0x000000018ad257c4 -[CALayer _display] + 2312 (:-1) 19 QuartzCore 0x000000018ac5d0f4 CA::Layer::display_if_needed(CA::Transaction*) + 256 (:-1) 20 QuartzCore 0x000000018ac5d0f4 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 732 (:-1) 21 QuartzCore 0x000000018ac593c8 CA::Context::commit_transaction(CA::Transaction*, double, double*) + 568 (:-1) 22 QuartzCore 0x000000018ac587c0 CA::Transaction::commit() + 428 (:-1) 23 QuartzCore 0x000000018ac59018 CA::Transaction::flush() + 84 (:-1) 24 QuartzCore 0x000000018ac585c0 CA::Transaction::flush_as_runloop_observer(bool) + 224 (:-1) 25 UIKitCore 0x000000018b111800 _UIApplicationFlushCATransaction + 52 (:-1) 26 UIKitCore 0x000000018b110e74 performCATransactionCommitAction + 308 (:-1) 27 UIKitCore 0x000000018b110e74 __setupUpdateSequence_block_invoke_2 + 336 (:-1) 28 UIKitCore 0x000000018b117b88 _UIUpdateSequenceRunNext + 128 (:-1) 29 UIKitCore 0x000000018b117928 schedulerStepScheduledMainSectionContinue + 48 (:-1) 30 UpdateCycle 0x00000002b9c47bc0 UC::DriverCore::continueProcessing() + 84 (:-1) 31 CoreFoundation 0x0000000186ea8c20 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28 (:-1) 32 CoreFoundation 0x0000000186ea8b94 __CFRunLoopDoSource0 + 192 (:-1) 33 CoreFoundation 0x0000000186e8a268 __CFRunLoopDoSources0 + 316 (:-1) 34 CoreFoundation 0x0000000186e89384 __CFRunLoopRun + 416 (:-1) 35 CoreFoundation 0x0000000186e8a7f4 _CFRunLoopRunSpecificWithOptions + 344 (:-1) 36 GraphicsServices 0x000000023154cf24 GSEventRunModal + 120 (:-1) 37 UIKitCore 0x000000018b1681cc UIApplicationMain + 336 (:-1) 38 UIKitCore 0x000000018b403644 UIApplicationMain(_:_:_:_:) + 104 (:-1) 39 MyApp 0x00000001021d9c08 main + 116 (/<compiler-generated>:10) 40 MyApp 0x00000001021d9c08 0x1021d4000 + 23560 (AppDelegate.swift:0) 41 dyld 0x0000000186cdb5b8 start + 6616 (:-1) Attaching one of the crashes, but I do have an access to xcrashpoint file as well. Crash: 2026-10-13_00-35-13.8383_-0400-3db78b940c1a263bd5595645b082edf503063be8.crash It seems to happen on the following version of iOS: 18.7.8 26.5 26.6.2 26.7.1 27.0 27.0.1 Would appreciate any tips!
1
0
467
3w
SwiftUI design options needed
OK, I'm going to try SwiftUI one more time. Every other time I've tried it I've run into major blockages that prevented it from being usable. So far I've code up this basic design (see screenshot at end). It's a common thing: Filters in the left sidebar, filtered assets in the center list (ignore the temp IDs for debugging purposes), and a detail view of the selected asset on the right. I have no part of the filters figured out yet, so I wouldn't mind getting advice of how to use that to filter the SwiftData. It's currently just using the common @Query to get all the items into a var of the main ContentView. As for the asset list and detail view, my current layout works, but the detail only shows for the first item clicked. Rather than show my SwiftUI code, it might be best to just ask for expert opinions about what is the right way to achieve this design. I want it to run on macOS and iOS. The details field all need to be editable. I'm currently doing this by declaring a struct as such: struct TitledField:View { let title:String; @Binding var value:String; var body:some View { LabeledContent("\(self.title):") { TextField(self.title, text:$value) .labelsHidden(); } } }
2
0
420
3w
EyeFlow: Which Apple APIs support camera-based gaze scrolling and dwell selection?
Hello Apple Developer Community, I’m Yashwanth Pentakota, the independent developer behind EyeFlow, a prototype exploring hands-free screen navigation using a standard device camera. EyeFlow focuses on gaze-based scrolling and dwell-based selection. The goal is to support people who have difficulty using a mouse or touchscreen. My current work includes improving calibration, reducing gaze jitter, and preventing unintended actions. I’m exploring bringing this interaction model to Apple platforms and would appreciate guidance on one architectural question: For gaze-controlled scrolling and selection within my own app, which supported Apple frameworks or APIs should I evaluate first, and what platform limitations should I account for? My current pipeline is: Camera capture → face/eye detection → gaze estimation → calibration and smoothing → scrolling or selection. This is an experimental prototype; I’m still evaluating its accuracy and usability. Prototype/source: https://github.com/Yashwanth6121/Eye-Flow-v3. Suggestions on relevant documentation or sample projects would be helpful. Thank you, Yashwanth Pentakota
0
0
248
3w
macOS 27 Golden Gate – Serious UI rendering issues on two different Apple Silicon Macs
Hello everyone, Since upgrading to macOS 27 Golden Gate, I've been experiencing numerous graphical interface issues on both of my Macs: MacBook Pro M4 Pro (work computer) MacBook Air M4 (personal computer) Both machines use completely separate Apple Accounts, yet they exhibit the same problems. The issues mainly affect window controls, menus, buttons, and title bars. For example: The red, yellow, and green window control buttons sometimes disappear completely. Safari's toolbar or title bar occasionally fails to render properly. When closing another application, such as Microsoft Word, parts of the Safari interface can disappear or become blank. Certain interface elements are not properly redrawn when switching between applications or rearranging windows. I've attached screenshots illustrating these problems. I don't use Stage Manager or any third-party window management utilities. Both Macs are running standard macOS configurations. These issues only started after upgrading to Golden Gate. Given that they occur on two different Apple Silicon Macs with separate Apple Accounts, I strongly suspect a macOS-level window rendering bug rather than a hardware or user-specific issue. The problems are quite disruptive during everyday work. Is anyone else experiencing similar issues? Has Apple acknowledged these rendering bugs, and is there any indication of when a fix might be released? Thanks in advance for your feedback.
Topic: UI Frameworks SubTopic: AppKit
0
0
198
3w
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
264
3w
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
651
3w
(iPhone Duo) Toolbar Items are misplaced for RTL layout-direction
On iPhone Duo, when I use .environment(\.layoutDirection, .rightToLeft) for a navigation view, the toolbar items sometimes appear on the left side instead of the right side, below the camera. This results in a view with two sides, and in some cases, it displays in an unexpected place. For example, in the code below, the button is placed behind the camera, as shown in the attachment. NavigationSplitView { Text("Sidebar") .toolbar { ToolbarItem(placement: .cancellationAction) { Button("X", systemImage: "xmark", action: {}) } } } detail: { Text("Detail") } .environment(\.layoutDirection, .rightToLeft) Is this intended behavior for RTL layout direction, a known issue, or a simulator issue?
5
1
384
3w
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
141
3w
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
382
3w
How to preserve collection view scroll anchor when folding/unfolding iPhone Duo
The following question was asked in the Oct 13 iPhone Duo group lab: when you unfold iPhone Duo after you’ve scrolled down, does UIKit keep the position or should we re-anchor ourselves? The answer was various scroll views like collection views and text views will handle this for you to keep visible items visible, which also works when resizing the window on iPad. This is not working for me with a simple UICollectionView. What do I need to do to obtain this behavior? class ViewController: UIViewController, UICollectionViewDataSource { override func viewDidLoad() { super.viewDidLoad() let layout = UICollectionViewFlowLayout() layout.itemSize = CGSize(width: 80, height: 80) layout.minimumInteritemSpacing = 8 layout.minimumLineSpacing = 8 layout.sectionInsetReference = .fromLayoutMargins let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) collectionView.translatesAutoresizingMaskIntoConstraints = false collectionView.backgroundColor = .systemBackground collectionView.dataSource = self collectionView.insetsLayoutMarginsFromSafeArea = true collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell") view.addSubview(collectionView) NSLayoutConstraint.activate([ collectionView.topAnchor.constraint(equalTo: view.topAnchor), collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor), collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor), collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 5000 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) var content = UIListContentConfiguration.cell() content.text = String(indexPath.item) content.textProperties.alignment = .center cell.contentConfiguration = content var background = UIBackgroundConfiguration.clear() background.backgroundColor = .secondarySystemBackground cell.backgroundConfiguration = background return cell } } Run the app on iPhone Duo Scroll down to cell 100 on the outer display Unfold the device Expected: It should stay scrolled to item 100 Actual: It scrolled down to item 225 (or more accurately, the content offset did not change, more content was added higher up with the contentSize shrinking due to the expanded width) In the past I've put so much work into trying to maintain the expected scroll position for orientation changes on iPhone and iPad/Mac Catalyst resize events, it's surprisingly incredibly hard to get working in every scenario, so I am SUPER interested to learn the system can do it for us!
0
0
252
3w
How to set custom height for keyboard extension without resize flicker?
Description I'm developing a custom keyboard extension using UIInputViewController and need to set a specific height of 268 points. The keyboard functions correctly, but there's a visible flicker and resize animation during launch that I cannot eliminate. The Problem When the keyboard launches, iOS provides incorrect heights before settling on the correct one. At launch, the view starts at 0×0. Around 295ms later, iOS sets the frame to 440×956 which is full screen height and wrong. Around 373ms, iOS changes it to 440×452 which is still wrong. Finally around 390ms, iOS settles at 440×268 which matches our constraint. This causes visible flicker as the view resizes three times rapidly. The keyboard appears to shrink from full screen down to the correct height, and users can clearly see this animation happening. What I've Tried I've tried adding a height constraint on self.view which gives me the correct height but causes the visible flicker. I created a custom UIInputView subclass and overrode intrinsicContentSize to return my desired height. iOS completely ignores this and gives random heights like 471pt, 680pt, or 956pt instead. I set allowsSelfSizing to true on my UIInputView subclass. iOS ignores this property. I set preferredContentSize on the view controller. iOS ignores this as well. I tried adding the constraint in viewDidAppear instead of viewDidLoad, thinking iOS might have settled by then. It still causes flicker. I overrode the frame and bounds setters on my UIInputView to clamp the height to my desired value. iOS bypasses these overrides somehow. I overrode layoutSubviews to force the correct height after the super call. iOS still applies its own height. Specific Question What is the correct API or technique to specify a keyboard extension's height that iOS will respect immediately upon launch, without triggering the resize animation sequence? Other third-party keyboards like Grammarly and SwiftKey appear to have solved this problem. Their keyboards appear at the correct height without any visible flicker. How do they achieve this? Expected Outcome The keyboard should appear at 268pt height on the first frame with no visible resize animation. Steps to Reproduce Create a new iOS App project in Xcode and add a Keyboard Extension target. In KeyboardViewController.swift, add a height constraint in viewDidLoad: override func viewDidLoad() { super.viewDidLoad() let heightConstraint = view.heightAnchor.constraint(equalToConstant: 268) heightConstraint.priority = .defaultHigh heightConstraint.isActive = true let label = UILabel() label.text = "Demo Keyboard" label.textAlignment = .center label.translatesAutoresizingMaskIntoConstraints = false view.addSubview(label) NSLayoutConstraint.activate([ label.centerXAnchor.constraint(equalTo: view.centerXAnchor), label.centerYAnchor.constraint(equalTo: view.centerYAnchor) ]) } Build and run on a physical device. Enable the keyboard in Settings, then General, then Keyboard, then Keyboards. Open any app with a text field and switch to the custom keyboard using the globe button. Observe the height changing from around 956pt to 452pt to 268pt with visible animation. Environment iOS 17 and iOS 18 and 26.2, Xcode 16 and Xcode 26, affects all iPhone models tested, reproducible on both simulator and physical device.
4
6
1.3k
3w
Tapping saved login does nothing after typing when .autocorrectionDisabled() or .textInputAutocapitalization(.never) modifier is applied
If a username field has .autocorrectionDisabled() or .textInputAutocapitalization(.never), tapping the saved login above the keyboard stops working once the user has typed part of their email. Nothing gets filled in. Seen on iPhone 16, iOS 27.0 (24A437). I've also reported this to Apple through Feedback Assistant (FB24825410). Steps to reproduce You need an app with Password AutoFill set up (a webcredentials associated domain) and a saved login for that domain. Tap the email field. The saved login appears above the keyboard. Type a few letters of the email. Tap the saved login. Expected: the email and password fields fill in, replacing what was typed. Actual: nothing happens. What works A username field with only .textContentType(.username) and .keyboardType(.emailAddress). Tapping the saved login fills both fields, no matter how much the user has typed. What breaks With .autocorrectionDisabled(), the tap works after 1 typed character, but does nothing after 2 or more. With .textInputAutocapitalization(.never), the tap does nothing after even 1 typed character. UIKit has the same problem: a UITextField with autocorrectionType = .no behaves like .autocorrectionDisabled(). In all of these cases, choosing the login from the key icon's Passwords sheet still fills both fields. Only the tap on the suggestion above the keyboard fails. Sample struct LoginView: View { @State private var email = "" @State private var password = "" var body: some View { VStack { TextField("Email", text: $email) .textContentType(.username) .keyboardType(.emailAddress) // Either of these breaks AutoFill once the user types: .autocorrectionDisabled() // fails after 2+ typed characters .textInputAutocapitalization(.never) // fails after 1 typed character SecureField("Password", text: $password) .textContentType(.password) } } } Workaround I removed both modifiers from our username field and it works. Typed emails still didn't get autocorrected in my testing. Has anyone found a way to keep these modifiers on a username field without breaking AutoFill? Possibly related: https://developer.apple.com/forums/thread/702970
2
0
484
3w
X button disappeared on iPadOS 26.4 in MFMailComposeViewController
I’m using MFMailComposeViewController to send emails from my app. Since updating to iPadOS 26.4, there is no way to cancel the mail composer because the “X” button in the top-left corner has disappeared. On iPhone with iOS 26.4, everything still seems to work as expected. Is this a known issue, or am I missing something? Has anyone else experienced this, or found a workaround?
Topic: UI Frameworks SubTopic: UIKit
Replies
13
Boosts
1
Views
2.5k
Activity
2w
Supported way to put an iPhone Duo simulator into the unfolded state programmatically
The Duo simulator boots showing only the outer display: the window is fixed at 382×644 pt and our layout classifier always reports the compact stack mode. We measured this on two separate clean boots (shutdown, erase, boot). xcrun simctl help lists no subcommand for folding, posture, or selecting the inner display — we read the full list. xcrun simctl io screenshot does reveal a second display (LCD-1, 2007×2853 px, aspect 0.70, close to the 669×951 inner portrait size). Unfolding manually in the Simulator UI works and the app then renders the two-column layout correctly, but we could not find a programmatic equivalent. Is there a supported way to unfold a Duo simulator from the command line or from XCTest?
Topic: UI Frameworks SubTopic: SwiftUI
Replies
4
Boosts
6
Views
1.5k
Activity
2w
Supported public API for individual Magic Mouse contacts in a sandboxed macOS app
We are investigating a Mac App Store version of an app that provides tap-to-click and two-finger dragging for Magic Mouse. We need contact identity, finger positions, touch-down/up, and simultaneous contact count while the pointer is over other apps. We want a supported public API and normal App Sandbox entitlements. We are not asking how to use a private framework or bypass the sandbox. Environment tested: macOS 27.0.1 (26A434), Apple Silicon arm64, Bluetooth Magic Mouse vendor 0x004c / product 0x0269. Both IOHIDManager/IOHIDDevice and CoreHID are tested in a standalone sandboxed diagnostic app, signed with a persistent local certificate. Sandbox is confirmed via SecTask, Input Monitoring granted via System Settings and confirmed by IOHIDCheckAccess. Entitlements: app-sandbox, device.usb, device.bluetooth. No temporary exceptions, no seizeDevice, no SetReport or device reconfiguration. The normal app was still running during capture; we can repeat with it stopped if necessary. We discover four mouse interfaces, primary usage pairs FF00/03, FF00/12, FF00/0B, and 01/02. All open successfully after Input Monitoring is granted. The latter descriptor includes a 0D/05 Touch Pad collection but only vendor-defined payload for that collection. Standard individual contact fields are not declared. Input report IDs 0x3f and 0x44 are declared in addition to mouse report 0x12. Two 60-second captures, one per API, include user-performed phases for hands off, one finger, two fingers, moving each finger independently, scrolling, and physical movement/click. IOHID received 1310 input reports; CoreHID received 2349. Every report was ID 0x12, 8 bytes. Element updates were exclusively Generic Desktop X/Y, without individual contact identity or finger coordinates. Neither 0x3f nor 0x44 was delivered. The diagnostic client only reads mouse interfaces and does not read keyboard input. Questions: Is there a supported public API to observe global individual Magic Mouse contacts in an App Sandbox app, including when another app is active? Is individual-contact data expected to be available through IOHIDDevice input reports or CoreHID for this device? If so, what documented setup and entitlements are required? Are the declared vendor-defined reports 0x3f/0x44 intended for third-party clients, and is their payload documented for this purpose? If there is no supported public route, should this functionality remain outside the Mac App Store, or is there a supported capability path we should investigate? The diagnostic source is independent of the production app. Please advise whether further captures with all other input utilities stopped would help distinguish a driver/client interaction from an unsupported use case. No logs or source attachments are included in this public post.
Replies
0
Boosts
0
Views
150
Activity
2w
Mission Control Window Management update
Dear Apple, I am sending feedback regarding the desktop management of macOS to improve the user experience. Mission Control currently only has a “+” button to the right, meaning that all new desktops are forced to the right side of the line. Adding an identical “+” button to the left will increase ease of using the OS, as I don’t necessarily need every new desktop to be on the right side. This will increase usability and make using desktops significantly easier than manually dragging them into the needed positions every time I add a desktop. Another thing is that when I maximize apps, all desktops go to the left by one spot. There should be a setting where you can control where desktops go when maximizing screens, either you want every desktop to go to the right or the left. This makes things easier as sometimes I have my main app on the right, with all the multi-tasking on the left. If desktops move to the right instead of the left, no open apps will be interfered with. (Please put this setting in the “Desktop and Dock” section). I have been using macOS for a year now, and those details were quite clear. Please consider this as a software update for over 100 million Macbook users, increasing usability without changing the OS so much people barely know how to use it. I have been concentrating significantly on macOS lately, noticing an upgrade followed by another, and is how I noticed this. Please consider this a fresh start for my feedback. I apologize for my previous un-trained replies. I am not a trained professional, but I genuinely care about improving the user experience and wanted to share these layout ideas. I promise to keep my interactions respectful of the forum guidelines from now on. May these desktop management ideas be considered? Thanks, Alyaman
Topic: UI Frameworks SubTopic: General
Replies
2
Boosts
0
Views
446
Activity
2w
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
862
Activity
3w
Binding Picker to enum value in SwiftData struct
I have a SwiftData @Model class that has a var of Media. enum Media: String, CaseIterable, Identifiable, Codable { case dvd = "DVD" case bluray = "Blu-ray" case bluray4k = "Blu-ray 4k" var id:String { self.rawValue } } In one of my views, I'm trying to show a Picker with the enum values, and then bind the @Model's field to the Picker's selection. I've been trying all kinds of things from suggesting I'm finding online. Here's a poorly pasted version of what my last attempt looks like (I'm sure I have the wrong number of closing curly brackets, but just ignore that): struct DetailView: View { @Binding var item:Item; // The @Model class. @State private var selectedMedia:Media = .dvd; var body:some View { Picker("Media", selection:$selectedMedia) { ForEach(Media.allCases, id:\.self) { media in Text(media.rawValue); } } .labelsHidden() .onAppear() { selectedMedia = item.media; } .onChange(of:selectedMedia) { oldValue, newValue in item.media = selectedMedia; } } } What's a good way to make this work? Am I going to have to use a custom formatter of some type, bind the Picker to a string, and convert the selected value with the formatter?
Replies
1
Boosts
0
Views
413
Activity
3w
Crash in ResolvedStyledText.draw
Hi! We're trying to investigate the following crash, but have a little bit hard time of understanding what the reason for it might be. I assume this might be us trying to reduce the state too often? Thread 0 Crashed: 0 libswiftCore.dylib 0x00000001884fec20 _swift_release_dealloc + 48 (:-1) 1 libswiftCore.dylib 0x00000001884fd938 bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 240 (:-1) 2 SwiftUICore 0x000000018ed7f940 specialized _ArrayBuffer._consumeAndCreateNew(bufferIsUnique:minimumCapacity:growForAppend:) + 244 (:-1) 3 SwiftUICore 0x000000018ed7ecdc specialized Array._createNewBuffer(bufferIsUnique:minimumCapacity:growForAppend:) + 16 (:-1) 4 SwiftUICore 0x000000018ed7ecdc specialized Array._reserveCapacityAssumingUniqueBuffer(oldCount:) + 24 (:-1) 5 SwiftUICore 0x000000018ed7ecdc specialized Array.append(_:) + 56 (:-1) 6 SwiftUICore 0x000000018ed7ecdc NSAttributedString.MetricsCache.metrics(requestedSize:layoutMargins:wantsNumberOfLineFragments:context:) + 2996 (:-1) 7 SwiftUICore 0x000000018eda7afc ResolvedStyledText.StringDrawing.draw(in:with:applyingMarginOffsets:containsResolvable:context:renderer:) + 208 (:-1) 8 SwiftUICore 0x000000018ee5fe90 ResolvedStyledText.draw(in:with:applyingMarginOffsets:context:renderer:) + 100 (:-1) 9 SwiftUICore 0x000000018ee5fe90 closure #1 in DisplayList.ViewUpdater.Platform.updateItemView(_:index:item:state:) + 176 (:-1) 10 SwiftUICore 0x000000018ee5f7a0 closure #1 in PlatformDrawableContent.draw(in:size:contentsScale:state:) + 20 (:-1) 11 SwiftUICore 0x000000018ee5f7a0 CGContextRef.withPlatformContext(do:) + 56 (:-1) 12 SwiftUICore 0x000000018ee5f7a0 PlatformDrawableContent.draw(in:size:contentsScale:state:) + 136 (:-1) 13 SwiftUICore 0x000000018ee5fd94 CGDrawingLayer.draw(in:) + 88 (:-1) 14 SwiftUICore 0x000000018ee5fd94 @objc CGDrawingLayer.draw(in:) + 224 (:-1) 15 QuartzCore 0x000000018ad2304c CABackingStoreUpdate_ + 344 (:-1) 16 QuartzCore 0x000000018ad22df0 invocation function for block in CA::Layer::display_() + 72 (:-1) 17 QuartzCore 0x000000018ad257c4 CA::Layer::display_() + 2180 (:-1) 18 QuartzCore 0x000000018ad257c4 -[CALayer _display] + 2312 (:-1) 19 QuartzCore 0x000000018ac5d0f4 CA::Layer::display_if_needed(CA::Transaction*) + 256 (:-1) 20 QuartzCore 0x000000018ac5d0f4 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 732 (:-1) 21 QuartzCore 0x000000018ac593c8 CA::Context::commit_transaction(CA::Transaction*, double, double*) + 568 (:-1) 22 QuartzCore 0x000000018ac587c0 CA::Transaction::commit() + 428 (:-1) 23 QuartzCore 0x000000018ac59018 CA::Transaction::flush() + 84 (:-1) 24 QuartzCore 0x000000018ac585c0 CA::Transaction::flush_as_runloop_observer(bool) + 224 (:-1) 25 UIKitCore 0x000000018b111800 _UIApplicationFlushCATransaction + 52 (:-1) 26 UIKitCore 0x000000018b110e74 performCATransactionCommitAction + 308 (:-1) 27 UIKitCore 0x000000018b110e74 __setupUpdateSequence_block_invoke_2 + 336 (:-1) 28 UIKitCore 0x000000018b117b88 _UIUpdateSequenceRunNext + 128 (:-1) 29 UIKitCore 0x000000018b117928 schedulerStepScheduledMainSectionContinue + 48 (:-1) 30 UpdateCycle 0x00000002b9c47bc0 UC::DriverCore::continueProcessing() + 84 (:-1) 31 CoreFoundation 0x0000000186ea8c20 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28 (:-1) 32 CoreFoundation 0x0000000186ea8b94 __CFRunLoopDoSource0 + 192 (:-1) 33 CoreFoundation 0x0000000186e8a268 __CFRunLoopDoSources0 + 316 (:-1) 34 CoreFoundation 0x0000000186e89384 __CFRunLoopRun + 416 (:-1) 35 CoreFoundation 0x0000000186e8a7f4 _CFRunLoopRunSpecificWithOptions + 344 (:-1) 36 GraphicsServices 0x000000023154cf24 GSEventRunModal + 120 (:-1) 37 UIKitCore 0x000000018b1681cc UIApplicationMain + 336 (:-1) 38 UIKitCore 0x000000018b403644 UIApplicationMain(_:_:_:_:) + 104 (:-1) 39 MyApp 0x00000001021d9c08 main + 116 (/<compiler-generated>:10) 40 MyApp 0x00000001021d9c08 0x1021d4000 + 23560 (AppDelegate.swift:0) 41 dyld 0x0000000186cdb5b8 start + 6616 (:-1) Attaching one of the crashes, but I do have an access to xcrashpoint file as well. Crash: 2026-10-13_00-35-13.8383_-0400-3db78b940c1a263bd5595645b082edf503063be8.crash It seems to happen on the following version of iOS: 18.7.8 26.5 26.6.2 26.7.1 27.0 27.0.1 Would appreciate any tips!
Replies
1
Boosts
0
Views
467
Activity
3w
SwiftUI design options needed
OK, I'm going to try SwiftUI one more time. Every other time I've tried it I've run into major blockages that prevented it from being usable. So far I've code up this basic design (see screenshot at end). It's a common thing: Filters in the left sidebar, filtered assets in the center list (ignore the temp IDs for debugging purposes), and a detail view of the selected asset on the right. I have no part of the filters figured out yet, so I wouldn't mind getting advice of how to use that to filter the SwiftData. It's currently just using the common @Query to get all the items into a var of the main ContentView. As for the asset list and detail view, my current layout works, but the detail only shows for the first item clicked. Rather than show my SwiftUI code, it might be best to just ask for expert opinions about what is the right way to achieve this design. I want it to run on macOS and iOS. The details field all need to be editable. I'm currently doing this by declaring a struct as such: struct TitledField:View { let title:String; @Binding var value:String; var body:some View { LabeledContent("\(self.title):") { TextField(self.title, text:$value) .labelsHidden(); } } }
Replies
2
Boosts
0
Views
420
Activity
3w
EyeFlow: Which Apple APIs support camera-based gaze scrolling and dwell selection?
Hello Apple Developer Community, I’m Yashwanth Pentakota, the independent developer behind EyeFlow, a prototype exploring hands-free screen navigation using a standard device camera. EyeFlow focuses on gaze-based scrolling and dwell-based selection. The goal is to support people who have difficulty using a mouse or touchscreen. My current work includes improving calibration, reducing gaze jitter, and preventing unintended actions. I’m exploring bringing this interaction model to Apple platforms and would appreciate guidance on one architectural question: For gaze-controlled scrolling and selection within my own app, which supported Apple frameworks or APIs should I evaluate first, and what platform limitations should I account for? My current pipeline is: Camera capture → face/eye detection → gaze estimation → calibration and smoothing → scrolling or selection. This is an experimental prototype; I’m still evaluating its accuracy and usability. Prototype/source: https://github.com/Yashwanth6121/Eye-Flow-v3. Suggestions on relevant documentation or sample projects would be helpful. Thank you, Yashwanth Pentakota
Replies
0
Boosts
0
Views
248
Activity
3w
macOS 27 Golden Gate – Serious UI rendering issues on two different Apple Silicon Macs
Hello everyone, Since upgrading to macOS 27 Golden Gate, I've been experiencing numerous graphical interface issues on both of my Macs: MacBook Pro M4 Pro (work computer) MacBook Air M4 (personal computer) Both machines use completely separate Apple Accounts, yet they exhibit the same problems. The issues mainly affect window controls, menus, buttons, and title bars. For example: The red, yellow, and green window control buttons sometimes disappear completely. Safari's toolbar or title bar occasionally fails to render properly. When closing another application, such as Microsoft Word, parts of the Safari interface can disappear or become blank. Certain interface elements are not properly redrawn when switching between applications or rearranging windows. I've attached screenshots illustrating these problems. I don't use Stage Manager or any third-party window management utilities. Both Macs are running standard macOS configurations. These issues only started after upgrading to Golden Gate. Given that they occur on two different Apple Silicon Macs with separate Apple Accounts, I strongly suspect a macOS-level window rendering bug rather than a hardware or user-specific issue. The problems are quite disruptive during everyday work. Is anyone else experiencing similar issues? Has Apple acknowledged these rendering bugs, and is there any indication of when a fix might be released? Thanks in advance for your feedback.
Topic: UI Frameworks SubTopic: AppKit
Replies
0
Boosts
0
Views
198
Activity
3w
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
264
Activity
3w
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
651
Activity
3w
(iPhone Duo) Toolbar Items are misplaced for RTL layout-direction
On iPhone Duo, when I use .environment(\.layoutDirection, .rightToLeft) for a navigation view, the toolbar items sometimes appear on the left side instead of the right side, below the camera. This results in a view with two sides, and in some cases, it displays in an unexpected place. For example, in the code below, the button is placed behind the camera, as shown in the attachment. NavigationSplitView { Text("Sidebar") .toolbar { ToolbarItem(placement: .cancellationAction) { Button("X", systemImage: "xmark", action: {}) } } } detail: { Text("Detail") } .environment(\.layoutDirection, .rightToLeft) Is this intended behavior for RTL layout direction, a known issue, or a simulator issue?
Replies
5
Boosts
1
Views
384
Activity
3w
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
141
Activity
3w
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
382
Activity
3w
How to preserve collection view scroll anchor when folding/unfolding iPhone Duo
The following question was asked in the Oct 13 iPhone Duo group lab: when you unfold iPhone Duo after you’ve scrolled down, does UIKit keep the position or should we re-anchor ourselves? The answer was various scroll views like collection views and text views will handle this for you to keep visible items visible, which also works when resizing the window on iPad. This is not working for me with a simple UICollectionView. What do I need to do to obtain this behavior? class ViewController: UIViewController, UICollectionViewDataSource { override func viewDidLoad() { super.viewDidLoad() let layout = UICollectionViewFlowLayout() layout.itemSize = CGSize(width: 80, height: 80) layout.minimumInteritemSpacing = 8 layout.minimumLineSpacing = 8 layout.sectionInsetReference = .fromLayoutMargins let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) collectionView.translatesAutoresizingMaskIntoConstraints = false collectionView.backgroundColor = .systemBackground collectionView.dataSource = self collectionView.insetsLayoutMarginsFromSafeArea = true collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell") view.addSubview(collectionView) NSLayoutConstraint.activate([ collectionView.topAnchor.constraint(equalTo: view.topAnchor), collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor), collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor), collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 5000 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) var content = UIListContentConfiguration.cell() content.text = String(indexPath.item) content.textProperties.alignment = .center cell.contentConfiguration = content var background = UIBackgroundConfiguration.clear() background.backgroundColor = .secondarySystemBackground cell.backgroundConfiguration = background return cell } } Run the app on iPhone Duo Scroll down to cell 100 on the outer display Unfold the device Expected: It should stay scrolled to item 100 Actual: It scrolled down to item 225 (or more accurately, the content offset did not change, more content was added higher up with the contentSize shrinking due to the expanded width) In the past I've put so much work into trying to maintain the expected scroll position for orientation changes on iPhone and iPad/Mac Catalyst resize events, it's surprisingly incredibly hard to get working in every scenario, so I am SUPER interested to learn the system can do it for us!
Replies
0
Boosts
0
Views
252
Activity
3w
How to set custom height for keyboard extension without resize flicker?
Description I'm developing a custom keyboard extension using UIInputViewController and need to set a specific height of 268 points. The keyboard functions correctly, but there's a visible flicker and resize animation during launch that I cannot eliminate. The Problem When the keyboard launches, iOS provides incorrect heights before settling on the correct one. At launch, the view starts at 0×0. Around 295ms later, iOS sets the frame to 440×956 which is full screen height and wrong. Around 373ms, iOS changes it to 440×452 which is still wrong. Finally around 390ms, iOS settles at 440×268 which matches our constraint. This causes visible flicker as the view resizes three times rapidly. The keyboard appears to shrink from full screen down to the correct height, and users can clearly see this animation happening. What I've Tried I've tried adding a height constraint on self.view which gives me the correct height but causes the visible flicker. I created a custom UIInputView subclass and overrode intrinsicContentSize to return my desired height. iOS completely ignores this and gives random heights like 471pt, 680pt, or 956pt instead. I set allowsSelfSizing to true on my UIInputView subclass. iOS ignores this property. I set preferredContentSize on the view controller. iOS ignores this as well. I tried adding the constraint in viewDidAppear instead of viewDidLoad, thinking iOS might have settled by then. It still causes flicker. I overrode the frame and bounds setters on my UIInputView to clamp the height to my desired value. iOS bypasses these overrides somehow. I overrode layoutSubviews to force the correct height after the super call. iOS still applies its own height. Specific Question What is the correct API or technique to specify a keyboard extension's height that iOS will respect immediately upon launch, without triggering the resize animation sequence? Other third-party keyboards like Grammarly and SwiftKey appear to have solved this problem. Their keyboards appear at the correct height without any visible flicker. How do they achieve this? Expected Outcome The keyboard should appear at 268pt height on the first frame with no visible resize animation. Steps to Reproduce Create a new iOS App project in Xcode and add a Keyboard Extension target. In KeyboardViewController.swift, add a height constraint in viewDidLoad: override func viewDidLoad() { super.viewDidLoad() let heightConstraint = view.heightAnchor.constraint(equalToConstant: 268) heightConstraint.priority = .defaultHigh heightConstraint.isActive = true let label = UILabel() label.text = "Demo Keyboard" label.textAlignment = .center label.translatesAutoresizingMaskIntoConstraints = false view.addSubview(label) NSLayoutConstraint.activate([ label.centerXAnchor.constraint(equalTo: view.centerXAnchor), label.centerYAnchor.constraint(equalTo: view.centerYAnchor) ]) } Build and run on a physical device. Enable the keyboard in Settings, then General, then Keyboard, then Keyboards. Open any app with a text field and switch to the custom keyboard using the globe button. Observe the height changing from around 956pt to 452pt to 268pt with visible animation. Environment iOS 17 and iOS 18 and 26.2, Xcode 16 and Xcode 26, affects all iPhone models tested, reproducible on both simulator and physical device.
Replies
4
Boosts
6
Views
1.3k
Activity
3w
Tapping saved login does nothing after typing when .autocorrectionDisabled() or .textInputAutocapitalization(.never) modifier is applied
If a username field has .autocorrectionDisabled() or .textInputAutocapitalization(.never), tapping the saved login above the keyboard stops working once the user has typed part of their email. Nothing gets filled in. Seen on iPhone 16, iOS 27.0 (24A437). I've also reported this to Apple through Feedback Assistant (FB24825410). Steps to reproduce You need an app with Password AutoFill set up (a webcredentials associated domain) and a saved login for that domain. Tap the email field. The saved login appears above the keyboard. Type a few letters of the email. Tap the saved login. Expected: the email and password fields fill in, replacing what was typed. Actual: nothing happens. What works A username field with only .textContentType(.username) and .keyboardType(.emailAddress). Tapping the saved login fills both fields, no matter how much the user has typed. What breaks With .autocorrectionDisabled(), the tap works after 1 typed character, but does nothing after 2 or more. With .textInputAutocapitalization(.never), the tap does nothing after even 1 typed character. UIKit has the same problem: a UITextField with autocorrectionType = .no behaves like .autocorrectionDisabled(). In all of these cases, choosing the login from the key icon's Passwords sheet still fills both fields. Only the tap on the suggestion above the keyboard fails. Sample struct LoginView: View { @State private var email = "" @State private var password = "" var body: some View { VStack { TextField("Email", text: $email) .textContentType(.username) .keyboardType(.emailAddress) // Either of these breaks AutoFill once the user types: .autocorrectionDisabled() // fails after 2+ typed characters .textInputAutocapitalization(.never) // fails after 1 typed character SecureField("Password", text: $password) .textContentType(.password) } } } Workaround I removed both modifiers from our username field and it works. Typed emails still didn't get autocorrected in my testing. Has anyone found a way to keep these modifiers on a username field without breaking AutoFill? Possibly related: https://developer.apple.com/forums/thread/702970
Replies
2
Boosts
0
Views
484
Activity
3w