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

iPadOS 26.0 RC–27.2: Four/Five-finger swipe still triggers system gesture and swallows touches even with all Multitasking Gestures disabled (FB24795986)
Summary: With all Multitasking Gestures disabled and Full Screen Apps enabled, four/five-finger pinch or swipe gestures are still intercepted by the system and swallow all touch points, so the foreground app stops receiving touch input. This is most noticeable in games that rely on multi-finger controls. The issue has persisted from iPadOS 26.0 RC through 27.2 — over a year — and remains unfixed(open). Multiple Feedback reports have been marked Open without a fix. one related report was marked “Potential Fix Identified – For a Future OS Update” and later reverted. Environment: iPad running any iPadOS version from 26.0 RC through 27.2 Settings > Multitasking & Gestures > all gestures disabled Full Screen Apps enabled (not Stage Manager or windowed apps) Steps to Reproduce: On the above configuration, open any app (most noticeable in games). Perform a four-finger pinch, or a four/five-finger left/right swipe. Observe that all touch points are immediately swallowed by the system, and the foreground app stops receiving touch input. Expected Result: Since all multitasking gestures are disabled in Settings, four/five-finger gestures should not respond at all, and the app should continue receiving touch input normally. Actual Result: The system still intercepts touches in the gesture area, causing the app to lose touch input temporarily or persistently. In games that rely on multi-finger input, this effectively breaks controls. FB Number: FB24795986
0
0
123
1w
Custom Navigation Item
If we have create a custom Navigation back item, while running on iPhone Duo simulator, we see it at normal position i.e. on screen's top left side. How can we move it to the safe area like when we use default back button?
Topic: UI Frameworks SubTopic: UIKit
2
0
403
1w
iPhone Duo vertical bar: system back button ignores custom back indicator image (UINavigationBarAppearance.setBackIndicatorImage)
On iPhone Duo (iOS 27.1), when UIKit moves a navigation controller's system back button into the vertical bar, the button always shows the system chevron. Every public API for customizing the back indicator image is ignored there, although the same configuration is honored in the horizontal (top) navigation bar. APIs tested (each one alone, on the second view controller of a UINavigationController stack, with no leftBarButtonItem): A. Nothing set (default). B. UINavigationBar.standardAppearance set to a UINavigationBarAppearance on which setBackIndicatorImage(_:transitionMaskImage:) was called. C. Same appearance assigned to all four UINavigationBar properties: standardAppearance, compactAppearance, scrollEdgeAppearance, compactScrollEdgeAppearance. D. Same appearance assigned to all four UINavigationItem properties of the pushed view controller: standardAppearance, compactAppearance, scrollEdgeAppearance, compactScrollEdgeAppearance. E. Legacy UINavigationBar.backIndicatorImage and UINavigationBar.backIndicatorTransitionMaskImage, with no appearance objects set. F. UINavigationBar.appearance() proxy: all four appearance properties, set before the navigation controller is created. G. UINavigationItem.backBarButtonItem of the previous view controller set to UIBarButtonItem(image:style:target:action:). H. Control: UINavigationItem.leftBarButtonItem set to UIBarButtonItem(image:style:target:action:) with the same image (axisBehavior left at .automatic). The marker image is UIImage(systemName: "arrow.uturn.backward"), so it cannot be mistaken for the system chevron. Results: Top navigation bar (iPhone 17 Pro iOS 27.0, and iPhone Duo open with portrait UI): B, C, D, E and F show the custom image. G shows the chevron followed by the image. Vertical bar (iPhone Duo closed; iPhone Duo open with landscape UI; also inside a UITabBarController with the tab bar hidden or visible): A through G all show the system chevron. Only H shows the custom image. At viewDidAppear, the app confirms that the configuration is in place: navigationBar.standardAppearance.backIndicatorImage is the marker image (B, C), navigationItem.standardAppearance is non-nil (D), and traitCollection.verticalBarEdge is .trailing. This contradicts the guidance given by an Apple Technology Evangelist in https://developer.apple.com/forums/thread/847875: "If you are only replacing the icon on the back button, you could use set the backIndicatorImage and maintain default system behavior. This would be the recommended approach." As things stand, the only way to show a custom back icon in the vertical bar is to replace the system back button with a leading item. That loses the system behavior that comes with it: UINavigationController.interactivePopGestureRecognizer, interactiveContentPopGestureRecognizer and the back-history menu.
Topic: UI Frameworks SubTopic: UIKit Tags:
1
2
470
1w
Hinge listeners don't work in Keyboard Extension on iPhone Duo (iOS 27.1)
Hi, I've discovered that my Keyboard Extension is unable to detect any hinge status update on iPhone Duo. I tired both UIKit and SwiftUI approach - nothing works. Is there any workaround to make it work? Reproducible demo: https://www.icloud.com/iclouddrive/0460exMJtAdRkpk8EDjb751nw Xcode 27.1 (27A9269) iOS 27.1 beta 1 (24A94401) I also created a bug report: FB24883137
4
1
968
1w
Back button with custom title goes blank and unresponsive when collapsed multiple times on iOS 27
Hi, it seems there's an issue with back button on iOS 27 when it has a custom title defined and the title is forced to collapse in runtime due to other items taking space in the header. I have the following setup in the header of the second screen in a stack: a back button that displays custom title and 2 rightBarButtonItems. There is a toggle that adds the third item to rightBarButtonItems or removes it. This forces to hide the back title or display it again. I expect the button to resize as needed and go back to previous state as needed, without flashing, and correctly respond to presses at all times. What actually happens: I repeat the action multiple times (up to 5 times should be enough), the back button goes blank and unresponsive. There is only the glass background present, which does correctly resize. I filed the issue in Feedback Assistant: ID FB24801640 Is there a way to workaround this?
Topic: UI Frameworks SubTopic: UIKit Tags:
1
2
246
1w
iOS 27 reorderContainer: destination appearance changes ~0.9s after cross-collection drop
I'm seeing a delayed appearance change when moving a row between two collections using the new SwiftUI reordering APIs. The data updates immediately, but the dragged row retains its source appearance throughout settling, then abruptly switches to its destination appearance about 0.9 seconds after the move callback. Environment Xcode 27.0 (27A266a), macOS 26.7 (25G229) iOS Simulator 27.0 (24A434), iPhone 17 Pro Feedback: FB25054984 These observations are from the original simulator tests. I haven't established whether the same behavior occurs on a physical device or a newer runtime. Structure and observed behavior The hierarchy is a ScrollView containing a LazyVStack with sections. Each section uses ForEach(...).reorderable(collectionID:), under one .reorderContainer(for:in:move:). A dragContainer supplies transferable items, with DragConfiguration(allowMove: true). The same item has a compact appearance inside a group and a wider card appearance when standalone. Moving it between those collections updates membership, order, and the state driving its appearance synchronously in the move callback. Item IDs remain stable. Drag a compact grouped row into the standalone collection. Drop it between two standalone rows. The model and live presentation state update immediately. The dropped row keeps the source appearance during settling, then snaps to the destination appearance approximately 0.9 seconds later. Moving it back shows the same behavior. Different row heights also cause adjacent rows to step when the appearance changes. Measured delays in the application's synthetic-data sandbox were approximately 930 ms out and 921 ms back in. What I've tried Removing role-dependent content identity. Moving into an already populated destination collection. Giving source and destination rows equal occupied height. Using identity transitions. Bypassing the app's drawer modifier. None removed the late appearance switch. Equal occupied height removed the displacement of adjacent rows, but not the delayed visual change. A comparison using custom drop handling updated the appearance promptly, but did not preserve native insertion-position reordering. The feedback contains the original video, relevant logs and before/after frames. I also have a reduced standalone project that builds, but its manual drag-and-drop reproduction hasn't yet been verified; the timings above are from the application's sandbox, not that standalone sample. Questions Is retaining the source row's appearance until after settling expected when moving between collections? Is there a supported API or recommended row structure that lets the destination appearance and geometry participate in the settling animation? Has anyone reproduced this on iOS 27, or found it fixed in a newer runtime? I'd like to keep native reordering without timed refreshes, container identity resets, or private APIs.
0
0
89
1w
macOS widget stays on the grey placeholder after a Developer ID app is replaced by a Mac App Store build of the same app
I have a macOS app with a WidgetKit widget extension, distributed two ways: a notarised Developer ID download, and a Mac App Store build (same bundle identifiers, same team, different signature). When a user replaces the Developer ID copy in /Applications with the store-signed copy, the desktop widget draws only the grey placeholder and never recovers. The app itself runs normally. What I saw (8 October 2026, macOS 27): An iMac had the Developer ID build 47 (version 1.6.3) in /Applications with the widget on the desktop. I installed build 48 (version 1.6.4), signed for the store, from TestFlight. It replaced the Developer ID copy in /Applications. The app worked. The large widget showed grey placeholder bars and no data, for at least five minutes. killall chronod in Terminal brought the widget back straight away. On a MacBook, updating from one TestFlight build to the next (builds 46, 47, 48) redrew the widget each time. So it is the change from a Developer ID signature to a store signature, not an ordinary update. What I think is happening, and would like confirmed or corrected: the widget process that was started from the Developer ID copy keeps running after the app is replaced, and the system refuses what it draws (or never asks it for a new timeline), while the widget gallery and desktop keep showing that process's placeholder. What I already do: The Developer ID build ships a small helper outside the sandbox that ends the old widget process after an update. The Mac App Store build cannot carry that helper. The widget extension compares the build number in its bundle's Info.plist on disk with the one it started with, and exits if they differ. This ran in the case above (the build numbers were 47 and 48) and did not clear the placeholder. I suspect the check only runs when the system asks the widget for a snapshot or timeline, and the system had stopped asking. I call WidgetCenter.shared.reloadAllTimelines() after the app writes new data. Questions: Is there a supported way for a sandboxed app (or its widget extension) to make the system replace or restart a widget process that belongs to an earlier, differently signed copy of the same app? Without a Terminal command, and without a helper outside the sandbox. Is it expected that chronod keeps the old extension process after the containing app is replaced by a copy with a different signing identity, and that the widget then stays on the placeholder? Is there a log subsystem or predicate that shows why the old extension process was kept, or what the system refused? Thank you.
0
0
293
2w
Inconsistent text scaling in web views on iPhone Duo
On iPad, text in a web view is always rendered at the same font size regardless of device orientation, sidebar presence, and window resizing. The text simply reflows according to the available space, as you would expect. In comparison, there appears to be a bug in iPhone Duo (or the Duo simulator) that causes web views to scale inconsistently depending on device orientation, presense/absence of the sidebar, and inner vs. outer screens. For example, showing and hiding the sidebar causes text in a web view to be rendered at different sizes rather than reflowing the text. Likewise, switching between portrait and landscape orientations causes text to be rendered at different sizes rather than reflowing. This occurs with the modern WebPage APIs introduced in iOS 26 as well as the older WKWebView APIs. Is this a known bug on the iPhone Duo? Is it just a simulator problem? Are there any recommended workarounds? Here's a quick example: import SwiftUI import WebKit struct ContentView: View { let webPage = WebPage() var body: some View { NavigationStack { WebView(webPage) } .task { webPage.load(html: """ <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Test page</title> </head> <body> <h1>This is a title</h1> <p>This is a paragraph.</p> </body> </html> """ ) } } }
Topic: UI Frameworks SubTopic: SwiftUI
0
0
285
2w
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
611
2w
Confirmation dialog anchor for a ToolbarOverflowMenu item
I have a destructive action exposed as a toolbar item, which might be collapsed into a ToolbarOverflowMenu. I'd present the delete confirmation as a confirmation dialog anchored to the button that triggered it. But when the action is inside the overflow menu, the menu item isn't a view I can anchor it to. What's the recommended pattern for the delete confirmation in that case? Is an alert the intended fallback, is there a supported way to anchor a confirmation dialog to a toolbar overflow item, or would you recommend a different approach altogether?
Topic: UI Frameworks SubTopic: SwiftUI
3
1
742
2w
SwiftUI Table on iPhone Duo
I am using the Table view in my app. On iPhone it only shows the first column, on iPad and Mac it shows all the columns. Since the Table view does not have an API to determine if the columns are shown, I am using self.horizontalSizeClass == .compact to find out if I need to show all content in the one column. Since the iPhone Duo is still an iPhone, even if it's unfolded, it only shows the one column, but the horizontalSizeClass is not compact. If we ignore that this all doesn't make any sense (why doesn't the Table just show the columns?!) my question is: how can I handle this case? Currently it just shows the first columns content.
Topic: UI Frameworks SubTopic: SwiftUI
8
0
1.4k
2w
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
418
2w
TabView auto-dismisses fullScreenCover after tab list changes (crash with .zoom animation)
Summary A TabView with .tabViewStyle(.page) builds its tabs with ForEach; each tab presents a fullScreenCover(item:) from inside. Once the TabView is on screen, either of these breaks every later presentation: a tab is added or removed, or a tab's root view changes identity (Group { switch state } going from .loading to .loaded, with no tab added or removed). From then on each cover is dismissed by SwiftUI itself 15–70 ms after the present. With the standard transition it opens and closes once. With .navigationTransition(.zoom) the dismissal reaches UIKit while the cover is still animating in, and the app crashes: NSInternalInconsistencyException: Cannot morph from a view that is not in the hierarchy. Reproduces on iOS 26.0, 26.5 and 27.1 simulators and on devices on iOS 27.0.x. In our shipping app it is the top crash, ~2,000 events/day. How we got here The crash appeared when we adopted .navigationTransition(.zoom) for this cover. Every report is SheetBridge.dismiss/present → dismissViewControllerAnimated: → -[UIView(UIMorphableInternal) _morphPreviewFromCurrentState:…]. A second tap while the cover was still zooming in reproduced it; we guarded against that. Crashes continued. Disassembling UIKit showed that a dismissal during a zoom presentation preempts it and morphs from the presented view; if that view is not in the hierarchy, UIKit asserts instead of falling back. Any premature dismissal is enough. Our crash breadcrumbs showed every user navigating between tabs of a page-style TabView shortly before the crash, so we went looking for what dismisses a cover that was just presented. A lab with our topology (~1,700 automated presents) found the two triggers above. Both reproduce on iOS 26.0, 26.5 and 27.1, so the SwiftUI side is not new; the zoom transition is what makes it fatal. Steps to reproduce Run the PagedTabViewCoverRepro scheme (https://github.com/matheusmdutra03/PagedTabViewCoverRepro). The bottom tab bar selects the scenario; each screen explains the cause and shows the steps. "Page list changes": tap Add a tab, then tap any photo. "Page content changes": tap Reload tab content, then tap any photo. Expected The photo opens and stays until Close. Actual Zoom on: the app crashes with "Cannot morph from a view that is not in the hierarchy." Zoom off: the photo closes by itself about 1 s later. The on-screen counter shows "Dismissed by system". Why we think it happens The page-style TabView tracks the presentations made from its tabs, keyed by each tab's identity in the ForEach. Scenario 1 changes that identity directly: the tab list is diffed. Scenario 2 changes it indirectly. Group adds no view of its own, so the tab is whichever switch branch is active. When state flips, the branch changes type and SwiftUI sees a different view in that slot. For the TabView that is the same as removing the tab and inserting a new one. Either way the tracking is rebuilt and the tab's fullScreenCover loses the presentation it owns. Every present after that is treated as orphaned: SwiftUI dismisses it, presents a second copy, and dismisses that too (captured with method hooks on present/dismiss in the sample). With .zoom the final dismissal lands while the cover is still animating in and its view is not in the window yet; UIKit's zoom-out has no fallback for that and asserts. The broken state lives in the TabView subtree: recreating only the TabView clears it, and a cover attached outside the TabView is never affected. What fixed it in the sample Scenario 1: .id(tabs.map(\.title)) on the TabView, so a list change recreates the TabView instead of diffing it. 20/20 clean. Does not help scenario 2. Scenario 2: ZStack { switch state { … } } instead of Group { … } as the tab's root. ZStack is a real view, so the tab keeps its identity and the switch only changes its content. 20/20 clean. Does not help scenario 1. Both are app-side workarounds, one per trigger. A standard TabView, a paging ScrollView, or a cover attached outside the TabView never reproduce. Suggested fix Keep each tab's presentation bookkeeping bound to its ForEach identity across list diffs and root-identity changes, so a tab's fullScreenCover/sheet never loses the presentation it owns. If SwiftUI still has to dismiss a presentation it no longer tracks, do it without animation while the presented view is not in the window, so the UIKit zoom transition cannot assert. Results (iOS 27.1, 20 presents each) Scenario 1: 0 clean · 9 dismissed by system · 11 crashes. With .id(tabs): 20 clean. Scenario 2: 0 clean · 0 dismissed · 20 crashes. With ZStack: 20 clean. Attachments Evidence/ has crash logs (iOS 27.1 and 26.5), a screen recording, and the raw trial logs. The ZoomDismissCrashRepro scheme in the same project reproduces the UIKit assertion with five public-API calls and no SwiftUI.
Topic: UI Frameworks SubTopic: SwiftUI
2
0
141
2w
Duo not having different z index with overlay arrangement view style
When using ArrangementView with the overlay style, the Duo simulator does not appear to return a distinct z-index environment value, though it correctly displays z-index 0 and 1 on other iPhone simulators. I would like to use this value to determine whether the overlay is active. Currently, this does not seem possible. Is this behavior intended, or is it a bug? If intended, what is the recommended approach to determine if the Duo is displaying the arranged view over another arranged view? import SwiftUI struct ContentView: View { var body: some View { ArrangementView { Controls() } secondary: { Player() } .arrangementViewStyle(.overlay) } } struct Controls: View { @Environment(\.overlayArrangementZIndex) var zIndex var body: some View { Text("Controls Z:\(zIndex)") .frame(maxWidth: .infinity, alignment: .leading) } } struct Player: View { @Environment(\.overlayArrangementZIndex) var zIndex var body: some View { Text("Player Z:\(zIndex)") .frame(maxWidth: .infinity, alignment: .trailing) } } #Preview { ContentView() }
Topic: UI Frameworks SubTopic: SwiftUI
3
0
183
2w
RTL Layout Issue on iPhone Duo Simulator (iOS 27.1) When Switching App Language to Arabic
Hello Apple Developer Community, We are adapting our UIKit-based iOS application for iPhone Duo and have encountered an unexpected layout issue when switching the app language to Arabic. We would appreciate any guidance from Apple engineers or developers who have experience with RTL layout behavior on this device form factor. ### Environment - Device: iPhone Duo Simulator - OS: iOS 27.1 (official release, non-beta) - Xcode: 27.1 (official release, non-beta) - Framework: UIKit - Layout system: Auto Layout - Device system language: English (LTR) - App language: Arabic (RTL) ### Problem Description Our application supports changing the app language independently of the device's system language. When the system language is English and the app language is Arabic, we configure the semantic content attributes of several UIKit classes globally: ```swift let cAttribute: UISemanticContentAttribute = language.isRTL ? .forceRightToLeft : .forceLeftToRight UIView.appearance().semanticContentAttribute = cAttribute UIButton.appearance().semanticContentAttribute = cAttribute UICollectionView.appearance().semanticContentAttribute = cAttribute UITableView.appearance().semanticContentAttribute = cAttribute UITableViewHeaderFooterView.appearance().semanticContentAttribute = cAttribute ``` After applying these settings, we observe a large, unexpected blank area along the left side of the interface on the iPhone Duo simulator. Multiple screens are affected, and views positioned using Auto Layout appear to leave additional space on the left, resembling an unexpected safe-area inset or margin. When the app language is English, the layout behaves as expected. The issue occurs when the app language is Arabic while the device system language remains English. We have not yet determined whether this is related to semantic content attributes, trait propagation, Auto Layout, safe-area behavior, or a device-specific layout consideration. ### Questions 1. Is using `UIAppearance` to set `semanticContentAttribute` globally a recommended approach for app-level RTL language switching in UIKit? 2. Could this configuration affect safe-area insets, layout margins, or Auto Layout behavior on iPhone Duo? 3. Would `traitOverrides.layoutDirection` be a better approach for controlling the layout direction when the app language differs from the system language? 4. If `traitOverrides.layoutDirection` is appropriate, where should it be applied—for example, on the root view controller or a container view controller—to ensure that the intended layout direction propagates correctly to descendant views? 5. Are there any iPhone Duo-specific layout behaviors or known issues that developers should consider when implementing RTL support? 6. What implementation strategy does Apple recommend for supporting in-app language switching between LTR and RTL languages in an existing UIKit application? Our goal is to support Arabic and other RTL languages reliably without introducing unintended spacing or layout changes, while keeping the device's system language unchanged. Any suggestions, documentation references, sample code, or insights into the underlying behavior would be greatly appreciated. Thank you for your time and help! Best regards, iOS Development Team
Topic: UI Frameworks SubTopic: UIKit
1
0
82
2w
Regression: AxisValueLabel anchor parameter ignores .topLeading on iOS 27
Hello Apple SwiftUI / Swift Charts Engineering Team, I am writing to report a layout regression regarding Swift Charts in iOS 27. The anchor property on AxisValueLabel has stopped honoring the .topLeading layout coordinate, whereas it functions perfectly in iOS 26. Bug Description: To prevent the first label on a bottom X-axis from clipping past the left screen edge, a .topLeading anchor is applied. In iOS 27, this specific anchor alignment is completely ignored. The chart falls back to a standard top-center alignment, causing the initial boundary label to clip off-screen. Core Code Snippet to Reproduce: struct XAxisAnchorBugView: View { let dates = [ Calendar.current.date(from: DateComponents(year: 2026, month: 10, day: 1))!, Calendar.current.date(from: DateComponents(year: 2026, month: 10, day: 2))! ] var body: some View { Chart(dates, id: .self) { date in LineMark(x: .value("Date", date), y: .value("Value", 100)) } .frame(height: 300) .padding() .chartXAxis { AxisMarks(preset: .aligned, position: .bottom, values: .stride(by: .day, count: 1)) { value in AxisTick() let currentAnchor: UnitPoint = { guard let currentDate = value.as(Date.self) else { return .top } // BUG: .topLeading layout anchor parameter is completely ignored on iOS 27 return (currentDate == dates.first) ? .topLeading : .top }() AxisValueLabel(format: .dateTime.month(.abbreviated).day(), anchor: currentAnchor) } } } } Steps to Reproduce: Render an X-axis with a .bottom position. Assign anchor: .topLeading strictly to the first axis element's label. Run on an iOS 26 simulator (the first label anchors its top-left corner correctly, preventing edge clipping). Run on an iOS 27 simulator (the .topLeading anchor is ignored, reverting to standard top-center alignment). Expected Behavior: AxisValueLabel should position its layout bounding box using the .topLeading anchor point when specified. Actual Behavior: The layout engine ignores the .topLeading parameter on iOS 27, causing the boundary text to shift left and clip. Attachments: I have attached Xcode Simulator screenshots demonstrating this regression: Best regards, Soumyajit Das
2
0
133
2w
Regression: AxisValueLabel multiLabelAlignment parameter ignored in iOS 27
Hello Apple SwiftUI / Swift Charts Engineering Team, I am writing to report a layout regression regarding Swift Charts in iOS 27. The multiLabelAlignment property on AxisValueLabel has stopped working as expected, whereas it functions perfectly in iOS 26. Bug Description: When configuring custom string values within AxisMarks using AxisValueLabel with multiLabelAlignment: .trailing, the alignment configuration is completely ignored on iOS 27. Labels fail to align text properly to the trailing edge, causing rendering layout issues for multi-line or custom text labels on the Y-axis. This exact same implementation compiles and aligns correctly on iOS 26. Code Snippet to Reproduce: swift struct YAxisAlignmentBugView: View { // data points to render the chart frame let data = [(date: Date(), revenue: 3000.0), (date: Date().addingTimeInterval(10000), revenue: 4000.0)] var body: some View { Chart(data, id: .date) { item in LineMark(x: .value("Date", item.date), y: .value("Revenue", item.revenue)) } .frame(height: 300) .padding() .chartYAxis { AxisMarks(preset: .aligned, position: .trailing, values: [12.0, 600.0, 3000.0, 6000.0]) { value in if let revenue = value.as(Double.self) { // BUG: multiLabelAlignment: .trailing is completely ignored on iOS 27 AxisValueLabel("y-(Int(revenue))", anchor: .leading, multiLabelAlignment: .trailing) } } } } } Steps to Reproduce: Render a Swift Chart containing a .chartYAxis configuration with position: .trailing. Pass a string directly using AxisValueLabel(customText, anchor: .leading, multiLabelAlignment: .trailing). Run the application on an iOS 26 simulator (text aligns properly to the trailing edge). Run the identical application code on an iOS 27 simulator. Expected Behavior: The text inside the AxisValueLabel should honor the multiLabelAlignment: .trailing parameter and align the text strings flush right. Actual Behavior: The multiLabelAlignment layout modifier is ignored on iOS 27, resulting in unexpected default left-alignment of the text strings. Attachments: I have attached screenshots from the Xcode Simulator demonstrating the regression: Please let me know if you need any further diagnostic details. Best regards, Soumyajit Das
2
0
104
2w
dismissalConfirmationDialog not working in iOS
It compiles for iOS but seems to be a no-op. Is this coming in a future beta? Or is there a way to hide the default back button when using the presentation + zoom navigationTransition APIs? I have a view that needs to show a confirmation on dismissal. I was previously doing this manually using a custom toolbar button + confirmationDialog modifier. But in iOS 27 I don't seem to be able to hide the navigation back button since I added the zoom navigationTransition API. This allows the user to tap the back button and lose changes. Not a great UX.
1
1
297
2w
Is NavigationSplitView on macOS 27 broken?
On macOS 27 Beta 2, a simple NavigationSplitView example exhibits bizarre behaviour when the window is resized. The sidebar seemingly expands and collapses at random as the window is resized. The symptoms can be exacerbated with toolbar items. The sidebar appears to behave correctly when an inspector view is not present. Copy paste the code below into a new Xcode 27 project and run on macOS 27 and then resize the window: File -> New -> Project... -> App import SwiftUI @main struct MyApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct ContentView: View { var body: some View { NavigationSplitView { Text("Sidebar") } detail: { Text("Content") } .inspector(isPresented: .constant(true)) { Text("Inspector") } } } Adding .frame or .inspectorColumnWidth to any of the Text views does not appear to fix the issues. macOS: 27.0 Beta (26A5368g) Xcode: 27.0 beta 2 (27A5209h)
Topic: UI Frameworks SubTopic: SwiftUI Tags:
5
1
713
2w
iPadOS 26.0 RC–27.2: Four/Five-finger swipe still triggers system gesture and swallows touches even with all Multitasking Gestures disabled (FB24795986)
Summary: With all Multitasking Gestures disabled and Full Screen Apps enabled, four/five-finger pinch or swipe gestures are still intercepted by the system and swallow all touch points, so the foreground app stops receiving touch input. This is most noticeable in games that rely on multi-finger controls. The issue has persisted from iPadOS 26.0 RC through 27.2 — over a year — and remains unfixed(open). Multiple Feedback reports have been marked Open without a fix. one related report was marked “Potential Fix Identified – For a Future OS Update” and later reverted. Environment: iPad running any iPadOS version from 26.0 RC through 27.2 Settings > Multitasking & Gestures > all gestures disabled Full Screen Apps enabled (not Stage Manager or windowed apps) Steps to Reproduce: On the above configuration, open any app (most noticeable in games). Perform a four-finger pinch, or a four/five-finger left/right swipe. Observe that all touch points are immediately swallowed by the system, and the foreground app stops receiving touch input. Expected Result: Since all multitasking gestures are disabled in Settings, four/five-finger gestures should not respond at all, and the app should continue receiving touch input normally. Actual Result: The system still intercepts touches in the gesture area, causing the app to lose touch input temporarily or persistently. In games that rely on multi-finger input, this effectively breaks controls. FB Number: FB24795986
Replies
0
Boosts
0
Views
123
Activity
1w
Custom Navigation Item
If we have create a custom Navigation back item, while running on iPhone Duo simulator, we see it at normal position i.e. on screen's top left side. How can we move it to the safe area like when we use default back button?
Topic: UI Frameworks SubTopic: UIKit
Replies
2
Boosts
0
Views
403
Activity
1w
iPhone Duo vertical bar: system back button ignores custom back indicator image (UINavigationBarAppearance.setBackIndicatorImage)
On iPhone Duo (iOS 27.1), when UIKit moves a navigation controller's system back button into the vertical bar, the button always shows the system chevron. Every public API for customizing the back indicator image is ignored there, although the same configuration is honored in the horizontal (top) navigation bar. APIs tested (each one alone, on the second view controller of a UINavigationController stack, with no leftBarButtonItem): A. Nothing set (default). B. UINavigationBar.standardAppearance set to a UINavigationBarAppearance on which setBackIndicatorImage(_:transitionMaskImage:) was called. C. Same appearance assigned to all four UINavigationBar properties: standardAppearance, compactAppearance, scrollEdgeAppearance, compactScrollEdgeAppearance. D. Same appearance assigned to all four UINavigationItem properties of the pushed view controller: standardAppearance, compactAppearance, scrollEdgeAppearance, compactScrollEdgeAppearance. E. Legacy UINavigationBar.backIndicatorImage and UINavigationBar.backIndicatorTransitionMaskImage, with no appearance objects set. F. UINavigationBar.appearance() proxy: all four appearance properties, set before the navigation controller is created. G. UINavigationItem.backBarButtonItem of the previous view controller set to UIBarButtonItem(image:style:target:action:). H. Control: UINavigationItem.leftBarButtonItem set to UIBarButtonItem(image:style:target:action:) with the same image (axisBehavior left at .automatic). The marker image is UIImage(systemName: "arrow.uturn.backward"), so it cannot be mistaken for the system chevron. Results: Top navigation bar (iPhone 17 Pro iOS 27.0, and iPhone Duo open with portrait UI): B, C, D, E and F show the custom image. G shows the chevron followed by the image. Vertical bar (iPhone Duo closed; iPhone Duo open with landscape UI; also inside a UITabBarController with the tab bar hidden or visible): A through G all show the system chevron. Only H shows the custom image. At viewDidAppear, the app confirms that the configuration is in place: navigationBar.standardAppearance.backIndicatorImage is the marker image (B, C), navigationItem.standardAppearance is non-nil (D), and traitCollection.verticalBarEdge is .trailing. This contradicts the guidance given by an Apple Technology Evangelist in https://developer.apple.com/forums/thread/847875: "If you are only replacing the icon on the back button, you could use set the backIndicatorImage and maintain default system behavior. This would be the recommended approach." As things stand, the only way to show a custom back icon in the vertical bar is to replace the system back button with a leading item. That loses the system behavior that comes with it: UINavigationController.interactivePopGestureRecognizer, interactiveContentPopGestureRecognizer and the back-history menu.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
1
Boosts
2
Views
470
Activity
1w
Hinge listeners don't work in Keyboard Extension on iPhone Duo (iOS 27.1)
Hi, I've discovered that my Keyboard Extension is unable to detect any hinge status update on iPhone Duo. I tired both UIKit and SwiftUI approach - nothing works. Is there any workaround to make it work? Reproducible demo: https://www.icloud.com/iclouddrive/0460exMJtAdRkpk8EDjb751nw Xcode 27.1 (27A9269) iOS 27.1 beta 1 (24A94401) I also created a bug report: FB24883137
Replies
4
Boosts
1
Views
968
Activity
1w
Back button with custom title goes blank and unresponsive when collapsed multiple times on iOS 27
Hi, it seems there's an issue with back button on iOS 27 when it has a custom title defined and the title is forced to collapse in runtime due to other items taking space in the header. I have the following setup in the header of the second screen in a stack: a back button that displays custom title and 2 rightBarButtonItems. There is a toggle that adds the third item to rightBarButtonItems or removes it. This forces to hide the back title or display it again. I expect the button to resize as needed and go back to previous state as needed, without flashing, and correctly respond to presses at all times. What actually happens: I repeat the action multiple times (up to 5 times should be enough), the back button goes blank and unresponsive. There is only the glass background present, which does correctly resize. I filed the issue in Feedback Assistant: ID FB24801640 Is there a way to workaround this?
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
1
Boosts
2
Views
246
Activity
1w
iOS 27 reorderContainer: destination appearance changes ~0.9s after cross-collection drop
I'm seeing a delayed appearance change when moving a row between two collections using the new SwiftUI reordering APIs. The data updates immediately, but the dragged row retains its source appearance throughout settling, then abruptly switches to its destination appearance about 0.9 seconds after the move callback. Environment Xcode 27.0 (27A266a), macOS 26.7 (25G229) iOS Simulator 27.0 (24A434), iPhone 17 Pro Feedback: FB25054984 These observations are from the original simulator tests. I haven't established whether the same behavior occurs on a physical device or a newer runtime. Structure and observed behavior The hierarchy is a ScrollView containing a LazyVStack with sections. Each section uses ForEach(...).reorderable(collectionID:), under one .reorderContainer(for:in:move:). A dragContainer supplies transferable items, with DragConfiguration(allowMove: true). The same item has a compact appearance inside a group and a wider card appearance when standalone. Moving it between those collections updates membership, order, and the state driving its appearance synchronously in the move callback. Item IDs remain stable. Drag a compact grouped row into the standalone collection. Drop it between two standalone rows. The model and live presentation state update immediately. The dropped row keeps the source appearance during settling, then snaps to the destination appearance approximately 0.9 seconds later. Moving it back shows the same behavior. Different row heights also cause adjacent rows to step when the appearance changes. Measured delays in the application's synthetic-data sandbox were approximately 930 ms out and 921 ms back in. What I've tried Removing role-dependent content identity. Moving into an already populated destination collection. Giving source and destination rows equal occupied height. Using identity transitions. Bypassing the app's drawer modifier. None removed the late appearance switch. Equal occupied height removed the displacement of adjacent rows, but not the delayed visual change. A comparison using custom drop handling updated the appearance promptly, but did not preserve native insertion-position reordering. The feedback contains the original video, relevant logs and before/after frames. I also have a reduced standalone project that builds, but its manual drag-and-drop reproduction hasn't yet been verified; the timings above are from the application's sandbox, not that standalone sample. Questions Is retaining the source row's appearance until after settling expected when moving between collections? Is there a supported API or recommended row structure that lets the destination appearance and geometry participate in the settling animation? Has anyone reproduced this on iOS 27, or found it fixed in a newer runtime? I'd like to keep native reordering without timed refreshes, container identity resets, or private APIs.
Replies
0
Boosts
0
Views
89
Activity
1w
macOS widget stays on the grey placeholder after a Developer ID app is replaced by a Mac App Store build of the same app
I have a macOS app with a WidgetKit widget extension, distributed two ways: a notarised Developer ID download, and a Mac App Store build (same bundle identifiers, same team, different signature). When a user replaces the Developer ID copy in /Applications with the store-signed copy, the desktop widget draws only the grey placeholder and never recovers. The app itself runs normally. What I saw (8 October 2026, macOS 27): An iMac had the Developer ID build 47 (version 1.6.3) in /Applications with the widget on the desktop. I installed build 48 (version 1.6.4), signed for the store, from TestFlight. It replaced the Developer ID copy in /Applications. The app worked. The large widget showed grey placeholder bars and no data, for at least five minutes. killall chronod in Terminal brought the widget back straight away. On a MacBook, updating from one TestFlight build to the next (builds 46, 47, 48) redrew the widget each time. So it is the change from a Developer ID signature to a store signature, not an ordinary update. What I think is happening, and would like confirmed or corrected: the widget process that was started from the Developer ID copy keeps running after the app is replaced, and the system refuses what it draws (or never asks it for a new timeline), while the widget gallery and desktop keep showing that process's placeholder. What I already do: The Developer ID build ships a small helper outside the sandbox that ends the old widget process after an update. The Mac App Store build cannot carry that helper. The widget extension compares the build number in its bundle's Info.plist on disk with the one it started with, and exits if they differ. This ran in the case above (the build numbers were 47 and 48) and did not clear the placeholder. I suspect the check only runs when the system asks the widget for a snapshot or timeline, and the system had stopped asking. I call WidgetCenter.shared.reloadAllTimelines() after the app writes new data. Questions: Is there a supported way for a sandboxed app (or its widget extension) to make the system replace or restart a widget process that belongs to an earlier, differently signed copy of the same app? Without a Terminal command, and without a helper outside the sandbox. Is it expected that chronod keeps the old extension process after the containing app is replaced by a copy with a different signing identity, and that the widget then stays on the placeholder? Is there a log subsystem or predicate that shows why the old extension process was kept, or what the system refused? Thank you.
Replies
0
Boosts
0
Views
293
Activity
2w
Inconsistent text scaling in web views on iPhone Duo
On iPad, text in a web view is always rendered at the same font size regardless of device orientation, sidebar presence, and window resizing. The text simply reflows according to the available space, as you would expect. In comparison, there appears to be a bug in iPhone Duo (or the Duo simulator) that causes web views to scale inconsistently depending on device orientation, presense/absence of the sidebar, and inner vs. outer screens. For example, showing and hiding the sidebar causes text in a web view to be rendered at different sizes rather than reflowing the text. Likewise, switching between portrait and landscape orientations causes text to be rendered at different sizes rather than reflowing. This occurs with the modern WebPage APIs introduced in iOS 26 as well as the older WKWebView APIs. Is this a known bug on the iPhone Duo? Is it just a simulator problem? Are there any recommended workarounds? Here's a quick example: import SwiftUI import WebKit struct ContentView: View { let webPage = WebPage() var body: some View { NavigationStack { WebView(webPage) } .task { webPage.load(html: """ <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Test page</title> </head> <body> <h1>This is a title</h1> <p>This is a paragraph.</p> </body> </html> """ ) } } }
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
0
Views
285
Activity
2w
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
611
Activity
2w
Confirmation dialog anchor for a ToolbarOverflowMenu item
I have a destructive action exposed as a toolbar item, which might be collapsed into a ToolbarOverflowMenu. I'd present the delete confirmation as a confirmation dialog anchored to the button that triggered it. But when the action is inside the overflow menu, the menu item isn't a view I can anchor it to. What's the recommended pattern for the delete confirmation in that case? Is an alert the intended fallback, is there a supported way to anchor a confirmation dialog to a toolbar overflow item, or would you recommend a different approach altogether?
Topic: UI Frameworks SubTopic: SwiftUI
Replies
3
Boosts
1
Views
742
Activity
2w
SwiftUI Table on iPhone Duo
I am using the Table view in my app. On iPhone it only shows the first column, on iPad and Mac it shows all the columns. Since the Table view does not have an API to determine if the columns are shown, I am using self.horizontalSizeClass == .compact to find out if I need to show all content in the one column. Since the iPhone Duo is still an iPhone, even if it's unfolded, it only shows the one column, but the horizontalSizeClass is not compact. If we ignore that this all doesn't make any sense (why doesn't the Table just show the columns?!) my question is: how can I handle this case? Currently it just shows the first columns content.
Topic: UI Frameworks SubTopic: SwiftUI
Replies
8
Boosts
0
Views
1.4k
Activity
2w
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
418
Activity
2w
TabView auto-dismisses fullScreenCover after tab list changes (crash with .zoom animation)
Summary A TabView with .tabViewStyle(.page) builds its tabs with ForEach; each tab presents a fullScreenCover(item:) from inside. Once the TabView is on screen, either of these breaks every later presentation: a tab is added or removed, or a tab's root view changes identity (Group { switch state } going from .loading to .loaded, with no tab added or removed). From then on each cover is dismissed by SwiftUI itself 15–70 ms after the present. With the standard transition it opens and closes once. With .navigationTransition(.zoom) the dismissal reaches UIKit while the cover is still animating in, and the app crashes: NSInternalInconsistencyException: Cannot morph from a view that is not in the hierarchy. Reproduces on iOS 26.0, 26.5 and 27.1 simulators and on devices on iOS 27.0.x. In our shipping app it is the top crash, ~2,000 events/day. How we got here The crash appeared when we adopted .navigationTransition(.zoom) for this cover. Every report is SheetBridge.dismiss/present → dismissViewControllerAnimated: → -[UIView(UIMorphableInternal) _morphPreviewFromCurrentState:…]. A second tap while the cover was still zooming in reproduced it; we guarded against that. Crashes continued. Disassembling UIKit showed that a dismissal during a zoom presentation preempts it and morphs from the presented view; if that view is not in the hierarchy, UIKit asserts instead of falling back. Any premature dismissal is enough. Our crash breadcrumbs showed every user navigating between tabs of a page-style TabView shortly before the crash, so we went looking for what dismisses a cover that was just presented. A lab with our topology (~1,700 automated presents) found the two triggers above. Both reproduce on iOS 26.0, 26.5 and 27.1, so the SwiftUI side is not new; the zoom transition is what makes it fatal. Steps to reproduce Run the PagedTabViewCoverRepro scheme (https://github.com/matheusmdutra03/PagedTabViewCoverRepro). The bottom tab bar selects the scenario; each screen explains the cause and shows the steps. "Page list changes": tap Add a tab, then tap any photo. "Page content changes": tap Reload tab content, then tap any photo. Expected The photo opens and stays until Close. Actual Zoom on: the app crashes with "Cannot morph from a view that is not in the hierarchy." Zoom off: the photo closes by itself about 1 s later. The on-screen counter shows "Dismissed by system". Why we think it happens The page-style TabView tracks the presentations made from its tabs, keyed by each tab's identity in the ForEach. Scenario 1 changes that identity directly: the tab list is diffed. Scenario 2 changes it indirectly. Group adds no view of its own, so the tab is whichever switch branch is active. When state flips, the branch changes type and SwiftUI sees a different view in that slot. For the TabView that is the same as removing the tab and inserting a new one. Either way the tracking is rebuilt and the tab's fullScreenCover loses the presentation it owns. Every present after that is treated as orphaned: SwiftUI dismisses it, presents a second copy, and dismisses that too (captured with method hooks on present/dismiss in the sample). With .zoom the final dismissal lands while the cover is still animating in and its view is not in the window yet; UIKit's zoom-out has no fallback for that and asserts. The broken state lives in the TabView subtree: recreating only the TabView clears it, and a cover attached outside the TabView is never affected. What fixed it in the sample Scenario 1: .id(tabs.map(\.title)) on the TabView, so a list change recreates the TabView instead of diffing it. 20/20 clean. Does not help scenario 2. Scenario 2: ZStack { switch state { … } } instead of Group { … } as the tab's root. ZStack is a real view, so the tab keeps its identity and the switch only changes its content. 20/20 clean. Does not help scenario 1. Both are app-side workarounds, one per trigger. A standard TabView, a paging ScrollView, or a cover attached outside the TabView never reproduce. Suggested fix Keep each tab's presentation bookkeeping bound to its ForEach identity across list diffs and root-identity changes, so a tab's fullScreenCover/sheet never loses the presentation it owns. If SwiftUI still has to dismiss a presentation it no longer tracks, do it without animation while the presented view is not in the window, so the UIKit zoom transition cannot assert. Results (iOS 27.1, 20 presents each) Scenario 1: 0 clean · 9 dismissed by system · 11 crashes. With .id(tabs): 20 clean. Scenario 2: 0 clean · 0 dismissed · 20 crashes. With ZStack: 20 clean. Attachments Evidence/ has crash logs (iOS 27.1 and 26.5), a screen recording, and the raw trial logs. The ZoomDismissCrashRepro scheme in the same project reproduces the UIKit assertion with five public-API calls and no SwiftUI.
Topic: UI Frameworks SubTopic: SwiftUI
Replies
2
Boosts
0
Views
141
Activity
2w
Duo not having different z index with overlay arrangement view style
When using ArrangementView with the overlay style, the Duo simulator does not appear to return a distinct z-index environment value, though it correctly displays z-index 0 and 1 on other iPhone simulators. I would like to use this value to determine whether the overlay is active. Currently, this does not seem possible. Is this behavior intended, or is it a bug? If intended, what is the recommended approach to determine if the Duo is displaying the arranged view over another arranged view? import SwiftUI struct ContentView: View { var body: some View { ArrangementView { Controls() } secondary: { Player() } .arrangementViewStyle(.overlay) } } struct Controls: View { @Environment(\.overlayArrangementZIndex) var zIndex var body: some View { Text("Controls Z:\(zIndex)") .frame(maxWidth: .infinity, alignment: .leading) } } struct Player: View { @Environment(\.overlayArrangementZIndex) var zIndex var body: some View { Text("Player Z:\(zIndex)") .frame(maxWidth: .infinity, alignment: .trailing) } } #Preview { ContentView() }
Topic: UI Frameworks SubTopic: SwiftUI
Replies
3
Boosts
0
Views
183
Activity
2w
RTL Layout Issue on iPhone Duo Simulator (iOS 27.1) When Switching App Language to Arabic
Hello Apple Developer Community, We are adapting our UIKit-based iOS application for iPhone Duo and have encountered an unexpected layout issue when switching the app language to Arabic. We would appreciate any guidance from Apple engineers or developers who have experience with RTL layout behavior on this device form factor. ### Environment - Device: iPhone Duo Simulator - OS: iOS 27.1 (official release, non-beta) - Xcode: 27.1 (official release, non-beta) - Framework: UIKit - Layout system: Auto Layout - Device system language: English (LTR) - App language: Arabic (RTL) ### Problem Description Our application supports changing the app language independently of the device's system language. When the system language is English and the app language is Arabic, we configure the semantic content attributes of several UIKit classes globally: ```swift let cAttribute: UISemanticContentAttribute = language.isRTL ? .forceRightToLeft : .forceLeftToRight UIView.appearance().semanticContentAttribute = cAttribute UIButton.appearance().semanticContentAttribute = cAttribute UICollectionView.appearance().semanticContentAttribute = cAttribute UITableView.appearance().semanticContentAttribute = cAttribute UITableViewHeaderFooterView.appearance().semanticContentAttribute = cAttribute ``` After applying these settings, we observe a large, unexpected blank area along the left side of the interface on the iPhone Duo simulator. Multiple screens are affected, and views positioned using Auto Layout appear to leave additional space on the left, resembling an unexpected safe-area inset or margin. When the app language is English, the layout behaves as expected. The issue occurs when the app language is Arabic while the device system language remains English. We have not yet determined whether this is related to semantic content attributes, trait propagation, Auto Layout, safe-area behavior, or a device-specific layout consideration. ### Questions 1. Is using `UIAppearance` to set `semanticContentAttribute` globally a recommended approach for app-level RTL language switching in UIKit? 2. Could this configuration affect safe-area insets, layout margins, or Auto Layout behavior on iPhone Duo? 3. Would `traitOverrides.layoutDirection` be a better approach for controlling the layout direction when the app language differs from the system language? 4. If `traitOverrides.layoutDirection` is appropriate, where should it be applied—for example, on the root view controller or a container view controller—to ensure that the intended layout direction propagates correctly to descendant views? 5. Are there any iPhone Duo-specific layout behaviors or known issues that developers should consider when implementing RTL support? 6. What implementation strategy does Apple recommend for supporting in-app language switching between LTR and RTL languages in an existing UIKit application? Our goal is to support Arabic and other RTL languages reliably without introducing unintended spacing or layout changes, while keeping the device's system language unchanged. Any suggestions, documentation references, sample code, or insights into the underlying behavior would be greatly appreciated. Thank you for your time and help! Best regards, iOS Development Team
Topic: UI Frameworks SubTopic: UIKit
Replies
1
Boosts
0
Views
82
Activity
2w
Regression: AxisValueLabel anchor parameter ignores .topLeading on iOS 27
Hello Apple SwiftUI / Swift Charts Engineering Team, I am writing to report a layout regression regarding Swift Charts in iOS 27. The anchor property on AxisValueLabel has stopped honoring the .topLeading layout coordinate, whereas it functions perfectly in iOS 26. Bug Description: To prevent the first label on a bottom X-axis from clipping past the left screen edge, a .topLeading anchor is applied. In iOS 27, this specific anchor alignment is completely ignored. The chart falls back to a standard top-center alignment, causing the initial boundary label to clip off-screen. Core Code Snippet to Reproduce: struct XAxisAnchorBugView: View { let dates = [ Calendar.current.date(from: DateComponents(year: 2026, month: 10, day: 1))!, Calendar.current.date(from: DateComponents(year: 2026, month: 10, day: 2))! ] var body: some View { Chart(dates, id: .self) { date in LineMark(x: .value("Date", date), y: .value("Value", 100)) } .frame(height: 300) .padding() .chartXAxis { AxisMarks(preset: .aligned, position: .bottom, values: .stride(by: .day, count: 1)) { value in AxisTick() let currentAnchor: UnitPoint = { guard let currentDate = value.as(Date.self) else { return .top } // BUG: .topLeading layout anchor parameter is completely ignored on iOS 27 return (currentDate == dates.first) ? .topLeading : .top }() AxisValueLabel(format: .dateTime.month(.abbreviated).day(), anchor: currentAnchor) } } } } Steps to Reproduce: Render an X-axis with a .bottom position. Assign anchor: .topLeading strictly to the first axis element's label. Run on an iOS 26 simulator (the first label anchors its top-left corner correctly, preventing edge clipping). Run on an iOS 27 simulator (the .topLeading anchor is ignored, reverting to standard top-center alignment). Expected Behavior: AxisValueLabel should position its layout bounding box using the .topLeading anchor point when specified. Actual Behavior: The layout engine ignores the .topLeading parameter on iOS 27, causing the boundary text to shift left and clip. Attachments: I have attached Xcode Simulator screenshots demonstrating this regression: Best regards, Soumyajit Das
Replies
2
Boosts
0
Views
133
Activity
2w
Regression: AxisValueLabel multiLabelAlignment parameter ignored in iOS 27
Hello Apple SwiftUI / Swift Charts Engineering Team, I am writing to report a layout regression regarding Swift Charts in iOS 27. The multiLabelAlignment property on AxisValueLabel has stopped working as expected, whereas it functions perfectly in iOS 26. Bug Description: When configuring custom string values within AxisMarks using AxisValueLabel with multiLabelAlignment: .trailing, the alignment configuration is completely ignored on iOS 27. Labels fail to align text properly to the trailing edge, causing rendering layout issues for multi-line or custom text labels on the Y-axis. This exact same implementation compiles and aligns correctly on iOS 26. Code Snippet to Reproduce: swift struct YAxisAlignmentBugView: View { // data points to render the chart frame let data = [(date: Date(), revenue: 3000.0), (date: Date().addingTimeInterval(10000), revenue: 4000.0)] var body: some View { Chart(data, id: .date) { item in LineMark(x: .value("Date", item.date), y: .value("Revenue", item.revenue)) } .frame(height: 300) .padding() .chartYAxis { AxisMarks(preset: .aligned, position: .trailing, values: [12.0, 600.0, 3000.0, 6000.0]) { value in if let revenue = value.as(Double.self) { // BUG: multiLabelAlignment: .trailing is completely ignored on iOS 27 AxisValueLabel("y-(Int(revenue))", anchor: .leading, multiLabelAlignment: .trailing) } } } } } Steps to Reproduce: Render a Swift Chart containing a .chartYAxis configuration with position: .trailing. Pass a string directly using AxisValueLabel(customText, anchor: .leading, multiLabelAlignment: .trailing). Run the application on an iOS 26 simulator (text aligns properly to the trailing edge). Run the identical application code on an iOS 27 simulator. Expected Behavior: The text inside the AxisValueLabel should honor the multiLabelAlignment: .trailing parameter and align the text strings flush right. Actual Behavior: The multiLabelAlignment layout modifier is ignored on iOS 27, resulting in unexpected default left-alignment of the text strings. Attachments: I have attached screenshots from the Xcode Simulator demonstrating the regression: Please let me know if you need any further diagnostic details. Best regards, Soumyajit Das
Replies
2
Boosts
0
Views
104
Activity
2w
dismissalConfirmationDialog not working in iOS
It compiles for iOS but seems to be a no-op. Is this coming in a future beta? Or is there a way to hide the default back button when using the presentation + zoom navigationTransition APIs? I have a view that needs to show a confirmation on dismissal. I was previously doing this manually using a custom toolbar button + confirmationDialog modifier. But in iOS 27 I don't seem to be able to hide the navigation back button since I added the zoom navigationTransition API. This allows the user to tap the back button and lose changes. Not a great UX.
Replies
1
Boosts
1
Views
297
Activity
2w
Is NavigationSplitView on macOS 27 broken?
On macOS 27 Beta 2, a simple NavigationSplitView example exhibits bizarre behaviour when the window is resized. The sidebar seemingly expands and collapses at random as the window is resized. The symptoms can be exacerbated with toolbar items. The sidebar appears to behave correctly when an inspector view is not present. Copy paste the code below into a new Xcode 27 project and run on macOS 27 and then resize the window: File -> New -> Project... -> App import SwiftUI @main struct MyApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct ContentView: View { var body: some View { NavigationSplitView { Text("Sidebar") } detail: { Text("Content") } .inspector(isPresented: .constant(true)) { Text("Inspector") } } } Adding .frame or .inspectorColumnWidth to any of the Text views does not appear to fix the issues. macOS: 27.0 Beta (26A5368g) Xcode: 27.0 beta 2 (27A5209h)
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
5
Boosts
1
Views
713
Activity
2w