Provide views, controls, and layout structures for declaring your app's user interface using SwiftUI.

Posts under SwiftUI tag

200 Posts

Post

Replies

Boosts

Views

Activity

iOS options in place of opening 2nd window like on mcOS
I have an app that shows data in a 3-column NavigationSplitView, the columns being collections, items in each collection, and item details. Column 2 shows a toolbar button to add a new item. On Mac, that brings up a window where the user can search an online database and choose the data for that new item. But on iOS, Windows aren't allowed (as it says in the debugger when I try running on iPad in the Simulator). I've seen many examples of putting a NavigationStack inside the detail section of the NavigationSplitView. I want that to happen as the result of tapping the toolbar button. When I try, it does slide a new view into place (although it appears to be empty instead of showing the content in my custom View that provides the content for the 2nd window on Mac), and it then immediately slides away to reveal the original detail view. I'm using the code model presented in a SwiftyPlace example. class NavigationStateManager: ObservableObject { @Published var navPath = NavigationPath() func popToRoot() { navPath = NavigationPath() } func goToSearch() { self.navPath.append("search"); } }The main ContentView contains the NavigationSplitView. Its detail contains this: NavigationStack(path:$nav.navPath) { if !selectionStore.selectedItems.isEmpty { DetailView() } else { Text("Select an item."); } } .navigationDestination(for:String.self) { textValue in if textValue == "search" { SearchWindow() .modelContext(modelContext) } }Column 2's view handles the toolbar button, which calls this in that same view: private func addNewIItem() { #if os(macOS) withAnimation { openWindow(id:"Search"); } #else nav.goToSearch(); #endif }I hope I've added enough of this growing-larger-all-the-time project to show the basic setup. Why is the search view sliding in and then back out? Is there a better way to present another view over the top of the main window/view on iPad and iPhone?
Topic: Design SubTopic: General Tags:
2
0
347
1d
iOS 27: SwiftUI TextField text invisible while typing when the app runs in Arabic (FB25410049)
Since iOS 27, if an app runs in Arabic (or, presumably, any right-to-left language), typing digits or Latin letters into a SwiftUI TextField makes the field look empty. The binding updates and the caret shows, but the text isn't drawn until editing ends. What I measured: The text's layout fragment is placed at about x = −39,655 pt in a 370 pt wide field, so it's drawn far outside the field. A plain TextField and one with .environment(\.layoutDirection, .leftToRight) (phone and card numbers) are both affected. A UIKit UITextField on the same screen isn't affected. The same build on iOS 18.0 works, and iOS 27 in English works. Minimal repro: one SwiftUI file with four fields. Run it with App Language set to Arabic, tap the first field and type 523. Launch with -autoProbe to have it type into each field and print where the text was laid out. PROBE iOS 27.0, language ar, layout RTL PROBE field 1 text="523" fieldWidth=370 fragmentX=[-39655] visible=false // SwiftUI TextField PROBE field 2 text="523" fieldWidth=370 fragmentX=[-39655] visible=false // SwiftUI, LTR pinned PROBE field 3 text="523" fieldWidth=370 fragmentX=[314] visible=true // UIKit UITextFieldWorkaround that works for us, installed once at launch: import UIKit enum TextFieldDirection { static func install() { for name in [UITextField.textDidBeginEditingNotification, UITextField.textDidChangeNotification] { NotificationCenter.default.addObserver(forName: name, object: nil, queue: .main) { note in guard let field = note.object as? UITextField else { return } MainActor.assumeIsolated { settle(field) } // SwiftUI rebuilds the paragraph style right after; settle again. DispatchQueue.main.async { MainActor.assumeIsolated { settle(field) } } } } } @MainActor static func settle(_ field: UITextField) { let direction: NSWritingDirection = field.effectiveUserInterfaceLayoutDirection == .rightToLeft ? .rightToLeft : .leftToRight if let whole = field.textRange(from: field.beginningOfDocument, to: field.endOfDocument) { field.setBaseWritingDirection(direction, for: whole) } func directed(_ attributes: [NSAttributedString.Key: Any]) -> [NSAttributedString.Key: Any] { var attributes = attributes let style = (attributes[.paragraphStyle] as? NSParagraphStyle)?.mutableCopy() as? NSMutableParagraphStyle ?? NSMutableParagraphStyle() style.baseWritingDirection = direction attributes[.paragraphStyle] = style return attributes } if let typing = field.typingAttributes { field.typingAttributes = directed(typing) } field.defaultTextAttributes = directed(field.defaultTextAttributes) field.setNeedsLayout() field.layoutIfNeeded() } }Don't pin textAlignment instead. SwiftUI puts .natural back on every keystroke and the caret jumps from side to side. If you see this too, please file a duplicate referencing FB25410049. Duplicates help Apple prioritise it.
1
0
48
1d
Thin border around VideoPlayer
A thin gray border appears around assets presented using VideoPlayer. It was tested on iPhone 8, iPhone 13 mini, and iPhone 15, and the border only appeared on the 13 mini. The iOS version didn't matter, we checked the 13 mini on both iOS 18 and iOS 26 and the border appeared on both. I created a minimal version of the app with just the VideoPlayer and the asset and the frame still appeared. We tried different assets and it was visible on all of them. import SwiftUI import AVKit struct ContentView: View { private let player = AVPlayer(url: Bundle.main.url(forResource: "sample", withExtension: "mp4")!) var body: some View { VideoPlayer(player: player) .frame(width: 300, height: 200) } }I found someone that had the same exact problem on Reddit and StackOverflow: https://www.reddit.com/r/swift/comments/8s87hm/weird_borders_around_avplayerviewcontroller/ https://stackoverflow.com/questions/50927561/weird-borders-around-avplayerviewcontroller and their solution included setting: playerLayer.shouldRasterize = true playerLayer.rasterizationScale = UIScreen.main.scaleThis fixed the issue but isn't suitable for our app due to offscreen rendering performance. They also found that issue on other devices, noting: "After testing this code on multiple devices (actual physical devices, not simulators), this bug appears to happen only on Plus devices (I tested it on i8 on iOS 11, i8+ on iOS 11, iX on iOS 11 and i6+ on iOS 10)." The bug doesn't appear on simulator, isn't visible on a screenshot, the frame disappears when using accessibility zoom. When we encoded the video file to Apple ProRes the border disappeared, but the size of the video bumped from 342 KB to 6.3 MB so we couldn't do that. I'm attaching photo from this person's post since our issue looked exactly the same. Has anyone had a similar issue and maybe found another workaround?
0
0
226
1d
How do deal with NavigationSplitView not saving selection on iPhone
I have a detail view that has a @Binding var Thing, which is passed to it from the parent. It has TextFields that need to use that bound object's fields. // Using this to pass the selection around @Observable class AppSelection { var selectedThings:Set<Thing> = Set(); } struct ContentView: View { @State private var selectionStore = AppSelection(); var body: some View { NavigationSplitView { ... } content: { ...list that sets the selectionStore.selectedThings... } detail: { if !selectionStore.selectedThings.isEmpty { DetailView(thing:Binding( get: { selectionStore.selectedThings.first! }, // Crashes here set: { selectionStore.selectedThings = [$0] } )) .frame(maxHeight:.infinity, alignment:.top) } else { Text("Select a thing."); } } } } struct DetailView:View { @Binding var thing:Thing; var body:some View { TextField("Blah", $thing.name); TextField("Blerg", $thing.stuff); } }A crash happens when I navigate back from the DetailView in the line commented as such. I assume the NavigationSplitView is resetting the selection back to an empty state. Why the Binding given to the DetailView is even trying to get its value at that point is beyond me (so much weirdness in SwiftUI). I've taken so many different stabs at trying to make things work differently, but I just don't understand enough about SwiftUI. Like can I make the DetailView take an optional binding? If the Thing is nil, then all the TextFields complain that they require a non-optional binding. I don't even want to show the Detail view if nothing is selected (hence the "Select a thing.").
1
0
852
2d
Multiseat Subscriptions: Pricing Flexibility and Enterprise Implementation
I have questions about pricing flexibility and technical implementation. In WWDC26 Session 391, you introduced up to five volume pricing bands that allow developers to offer lower per-seat subscription prices as organizations purchase more seats. For example: 1–20 seats: $39.99/month per seat 21–40 seats: $29.99/month per seat 41+ seats: $19.99/month per seat Volume purchasing and volume discounting provide different benefits. Volume purchasing makes it easier for organizations to buy, deploy, and manage subscriptions. This is valuable independently of discounts. Consider a productivity application deployed to 10,000 employees. Unlike AI services that charge separately for tokens or usage credits, an application offering unlimited, unmetered usage receives no additional revenue beyond its subscription fees. Supporting 10,000 deployments also introduces ongoing responsibilities. Major updates, new capabilities, and performance improvements may require additional testing, deployment coordination, compatibility checks, and technical support. Enterprise customers often have greater requirements for reliability, timely updates, and deployment management. Reducing the fixed subscription price per seat does not reduce these responsibilities or account for the additional value delivered across an organization. My questions for the StoreKit team: Business pricing: Can developers create a separate business subscription with a higher base price than their consumer offering, such as $39.99/month for individuals and $59.99/month per business seat, with independent volume pricing bands? Business-only distribution: Can this subscription be offered exclusively through Apple Business while maintaining the existing consumer subscription? Business features in the same app: Can StoreKit 2 identify whether a user has an individual subscription or an organization-assigned seat, allowing developers to unlock additional business capabilities within the same app binary? Onboarding and deployment: What is the recommended approach for adapting onboarding, subscription unlocking, and access management for organization-assigned users? Are there specific considerations for MDM deployment and managed app configurations? Implementation resources: Are there technical documentation or sample projects covering multiseat purchases, entitlement verification, seat reassignment, subscription changes, and ongoing management after release? The primary opportunity is simplifying organizational purchasing and deployment, while allowing developers to deliver additional business value and price subscriptions according to the ongoing requirements of supporting organizations at scale—not simply discounting additional seats. I’d appreciate clarification on the recommended pricing configuration and StoreKit 2 implementation. Thank you. REF: October 22 Announcement — Offer your subscriptions to businesses and schools
0
0
79
2d
NavigationSplitView, endless loop detail<->content
Hi, I already had a problem with the NavigationSplitView before, and I'm still working on it. The NavigationSplitView issue on the phone occurs when trying to navigate back from the detail view to the content view; the app automatically navigates straight back to the detail view. I reproduced the issue in a small program and identified the critical section. However, I do not know why the problem is occurring. I did the same thing again, but this time with @Query, and there was no problem. The categories, recipes and single recipe, all loaded by @Query and no side effects. Requirements for the content: A state variable used in the view, e.g., isLoading A task that loads the data from a ModelActor in a ViewModel, setting isLoading to true beforehand and back to false upon completion Subsequently, it is only possible to exit the detail view after many attempts, because the app immediately navigates back to the detail view automatically upon trying to leave it. One issue is changing the isLoading status variable from within the task. That in itself isn't the problem; the issue only arises when reading data via a ModelActor. If the status variable is changed and, for example, the list is modified manually, there is no problem. It only occurs when a ModelActor is used. I based it on the NavigationCookbook: This is the view I use for the content section (list): @State private var vm: RecipeListViewModel = .init() @State var isLoading: Bool = false if isLoading { ProgressView("Loading...") } else { List(selection: $selectedRecipe) { ForEach(vm.recipes) { recipe in NavigationLink(recipe.name, value: recipe) } } } .task { // bug, when used in UI, because of ModelActor isLoading = true await vm.list(context, categoryName: selectedCategory.name) isLoading = false } .task { // works, because manually modifying the list isLoading = true await vm.addRecipe(context, categoryName: selectedCategory.name) isLoading = false } inside ViewModel // bug func list(_ modelContext: ModelContext, categoryName: String) async { recipes.removeAll() let dh: RecipeDataHandler = .init(modelContainer: modelContext.container) let values = await dh.listByName(categoryName: categoryName) for v in values { recipes.append(.init(recipeId: v.recipeId, name: v.name)) } } // works func addRecipe(_ modelContext: ModelContext, categoryName: String) async { isLoading = true defer { isLoading = false } recipes.removeAll() recipes.append(.init(recipeId: "a", name: "Pambazo")) } ModelActor @ModelActor actor RecipeDataHandler { func listByName(categoryName: String) async -> [RecipeData] { var list: [RecipeData] = [] do { let fd = FetchDescriptor<Recipe>(predicate: #Predicate { $0.category.name == categoryName }, sortBy: [SortDescriptor(\Recipe.name)]) let data = try modelContext.fetch(fd) for item in data { let rec: RecipeData = await .init(recipeId: item.recipeId, name: item.name) list.append(rec) } } catch { print("error: \(error.localizedDescription)") } return list } } Recipe is a @Model and RecipeData just a struct. In principle, everything should run on the MainActor, but the inclusion of the ModelActor still leads to this strange behavior. Any idea what the problem might be? Christian
3
0
343
3d
NavigationSplitView Binding to NavigationSplitViewColumn reset with every NavigationStack path change
I try to create a Navigation that works on iPhone, iPhone Duo and iPad. NavigationSplitView collapses for compact form factors and makes iPhone Duo support much simpler. The Problem is the semantic of the collapse. Switch from detail to sidebar on compact is not a 'back' action in my case. It should have my choosen Icon and has a meaning. So i wanted to control this using the NavigationSpliViewColumn Binding. This does work forward and backward as long as no NavigationStack was used before. But it stops working when you return to the detail root from a Navigation-Action. I left the Backbutton visible so you can test, that it continues to work, when no Navigation-Action preceeded the switch. Here is my Code: import SwiftUI @Observable final class Compass { var path: [Route] init() { self.path = [] } } enum Route: Hashable { case goal } struct ContentView: View { @Environment(\.horizontalSizeClass) private var hsize @State private var compass: Compass = Compass() @State var column: NavigationSplitViewColumn = .detail var body: some View { NavigationSplitView(preferredCompactColumn: $column) { OverviewScreen(column: $column) } detail: { TodayScreen() .toolbar { ToolbarItem(placement: .topBarLeading) { Button("overview", systemImage: "calendar") { self.column = .sidebar } } } } .environment(compass) .onChange(of: column) { old, new in print("column:", old, "→", new) } } } struct OverviewScreen: View { @Binding var column: NavigationSplitViewColumn @Environment(Compass.self) var compass var body: some View { @Bindable var compass = self.compass ScrollView { Text("Overview") .font(.largeTitle) .fontWeight(.heavy) Button("Switch") { self.column = .detail } } } } struct TodayScreen: View { @Environment(Compass.self) var compass var body: some View { @Bindable var compass = self.compass NavigationStack(path: $compass.path) { ScrollView { Text("Today") .font(.largeTitle) .fontWeight(.heavy) Button("Goals programtically", systemImage: "flag.fill") { self.compass.path = [.goal] } NavigationLink(value: Route.goal) { Label("Goal Link", systemImage: "flag.fill") } } .navigationDestination(for: Route.self, destination: self.screen) } } @ContentBuilder func screen(for route: Route) -> some View { switch route { case .goal: Text("Goals") } } } #Preview { ContentView() }This seems unexpected behaviour. If you ask AI the mental model is NavigationSplitViewColumn represents which column is currently visible for the user. That model would be wrong. Also i can't understand why a NavigationStack has to change the Binding? What am i missing here? Is my idea of the programmatic switch not supported? There are other ways to push from compact to your detail column again, but they all have trade-offs or run into other problems. I would appreciate any help here. AI has not understood this and only does surface level work arounds that fix nothing.
0
0
44
5d
Accessibility Inspector Element Detection and contrast failures with SwiftUI sheets
I am investigating Accessibility Inspector/XCTest audit results in a SwiftUI app (Target Keeper), without suppressing warnings. Environment: Xcode 27.1 (27A9275), iPadOS 27.0 Simulator, macOS 27.0.1. Debug and Release builds pass. The app uses scalable text and labeled controls. Element Detection / native sheet Main-screen Element Detection passes when the sheet is closed. With a SwiftUI .sheet presented, the iPad audit reports “Potentially inaccessible text”; XCUIAccessibilityAuditIssue.element is nil. Exported Inspector HTML highlights background labels behind/outside the sheet, rather than a foreground control. The separate, data-free SwiftUI application below reproduces the modal-only warning; it links no application modules or persistence. Actual iPad Simulator VoiceOver testing using XCUIDevice.shared.voiceOverService passes forward/backward traversal of the real application's modal controls, without reaching the background labels. This is simulator evidence, not physical-device acceptance. A trial explicit modal container/.isModal trait did not clear the audit and was reverted; no warnings are filtered. Minimal independent app: import SwiftUI @main struct ModalRepro: App { @State private var showing=false private let names=["Vegetables","Protein","Fruit","Dairy","Grains","Healthy Fats"] var body:some Scene {WindowGroup { NavigationStack { VStack(spacing:24) { Button("Nutrition") {}.accessibilityLabel("Choose Page").accessibilityValue("Nutrition") LazyVGrid(columns:[GridItem(.flexible()),GridItem(.flexible()),GridItem(.flexible())],spacing:40) { ForEach(names,id:\.self) { name in Button {} label: { VStack(spacing:10) { Circle().fill(.blue.opacity(0.3)).frame(width:250,height:250) Text(name).font(.system(size:17)).accessibilityHidden(true) } }.buttonStyle(.plain).accessibilityLabel(name) } } Button("Show modal") {showing=true} }.padding(24).frame(maxWidth:.infinity,maxHeight:.infinity).background(Color.black) }.preferredColorScheme(.dark) .sheet(isPresented:$showing) { NavigationStack { VStack {Text("Foreground content");Button("Close") {showing=false}} .frame(maxWidth:.infinity,maxHeight:.infinity).background(Color.black) .navigationTitle("Modal flow") }.preferredColorScheme(.dark) } }} }In an Xcode UI-test target, launch this app, run try app.performAccessibilityAudit(for: [.elementDetection]), tap “Show modal”, then run the same audit again. The first passes and the second fails. No issue handler ignores failures. Contrast / scrolling — separate unresolved finding All four iPhone combined-audit configurations (portrait/landscape, normal/maximum Dynamic Type) pass in the tested picker state. However, iPad maximum-text combined audits and a separate scrolled iPhone maximum-text landscape contrast audit still fail; we are not calling these resolved. In the scrolled iPhone case, XCTest identifies a count label whose frame is entirely above the visible results viewport. Inspector's exported HTML reports 1.37:1 using #252526 versus #000000; its marked screenshot rectangle overlaps the dark search/header area, not visible count text. Visible sampled labels instead have white or light foregrounds on opaque dark fills (e.g. #FFFFFF/#1C1C1E = 17.01:1; #98989F/#1C1C1E = 5.94:1). These are screenshot core-pixel measurements, not proof every warning is false. We compare ordinary text against 4.5:1 and interactive non-text against 3:1. iPad maximum-text warnings have not yet been matched to an exact visible color pair. Original failures and HTML exports are preserved privately. Questions Is Element Detection expected to inspect background elements behind a presented native SwiftUI sheet? Is this a known tool limitation/framework issue, or does the sample need different semantics? What is the supported way to establish modal accessibility boundaries with SwiftUI sheets, and when should .isModal be added explicitly? How should we distinguish a real contrast defect from clipping, occlusion, translucency, or sampling of an offscreen element? Which Inspector export fields/diagnostics should establish the actual sampled text/background pair? What additional evidence/manual and physical-device tests does Apple recommend before qualifying accessibility when the minimal audit reproduction fails but actual VoiceOver modal focus behaves correctly? We are not asking to waive audits or declare full accessibility from a VoiceOver pass alone. I read Apple's audit guidance and modal trait documentation: https://developer.apple.com/documentation/accessibility/performing-accessibility-audits-for-your-app https://developer.apple.com/documentation/swiftui/accessibilitytraits/ismodal https://developer.apple.com/help/app-store-connect/manage-app-accessibility/sufficient-contrast-evaluation-criteria/ Related discussion https://developer.apple.com/forums/thread/823968 recommends Feedback for a different apparent Dynamic Type false positive; it does not answer these modal/contrast questions. A Feedback draft is prepared but not submitted, so I have no Feedback ID yet. No private data, identifiers, credentials, app containers or confidential application source are included.
1
0
810
6d
iPhone Duo: SwiftUI Layout Differs Between Simulator and Physical Device (Tab Bar Placement and Content Cropping)
Hi everyone, I'm experiencing a significant difference in SwiftUI layout behavior between the iPhone Duo simulator and a physical iPhone Duo. I've already adjusted my layout to work correctly in the simulator, but the same app behaves differently on the actual device. 1. Folded Simulator: The tab bar is positioned on the right side, as expected for iPhone Duo. The view respects the right-side layout, and scroll views extend naturally behind the tab bar, behaving as expected. Physical device: The tab bar appears at the bottom, like a regular iPhone, instead of on the right. The view is also cropped on the right side. 2. Unfolded Simulator: The tab bar and navigation view both appear correctly. Physical device: The tab bar remains at the bottom, even in landscape orientation, instead of using the expected Duo layout. The main content also starts from the bottom of the navigation view, resulting in an incorrect layout. The most confusing part is that the layout works correctly in the simulator but not on the physical device. Has anyone encountered this behavior on a physical iPhone Duo? Could this be related to the iOS version, SDK version, SwiftUI's automatic tab bar adaptation, or a device-specific bug? I'd appreciate any insights, especially from developers who have tested their SwiftUI apps on actual iPhone Duo hardware. Environment: Xcode version: 27.1 iOS SDK: 27.1 Physical device iOS version: 27.2 Thanks!
1
0
104
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
83
1w
Virtual keyboard in preview
Hello, When I click in the box to write a text (in preview) the virtual keyboard does not appear. On the other hand, when I want to write my script, the keyboard appears well. This one works perfectly in all my applications on the iPad. I could read on the internet that this would come from a problem with the Swift Playground application. I uninstalled and then reinstalled the application but the problem is still present. Thanks
2
0
121
1w
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
125
1w
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
98
1w
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
290
1w
requestReview() prompting repeatedly
We're getting user reports that the App Store rating prompt appears repeatedly — one user says they're prompted roughly every day, and that they still get the prompt after they've already left a rating. This contradicts the documented behavior, so I want to check whether others are seeing the same thing or whether there's a known regression. What the docs say should happen The system limits display to 3 occurrences per app within a 365-day period. For a user who has already rated/reviewed, StoreKit should only display again if the app version is new and more than 365 days have passed since their previous review. Has anyone else experience it?
4
2
1.3k
1w
.contactAccessPicker shows blank sheet on iOS 26.2.1 on device
Calling contactAccessPicker results in a blank sheet and a jetsam error, rather than the expected contact picker, using Apple’s sample code, only on device with iOS 26.2.1. This is happening on a iPhone 17 Pro Max running 26.2.1, and not on a simulator. I’m running Apple's sample project Accessing a person’s contact data using Contacts and ContactsUI Steps: Run the sample app on device running iOS 26.2.1. Use the flow to authorize .limited access with 1 contact: Tap request access, Continue, Select Contacts. Select a contact, Continue, Allow Selected Contact. This all works as expected. Tap the add contact button in the toolbar to add a second contact. Expected: This should show the Contact Access Picker UI. Actual: Sheet is shown with no contents. See screenshot of actual results on iOS device running 26.2.1. Reported as FB21812568 I see a similar (same?) error reported for 26.1. It seems strange that the feature is completely broken for multiple point releases. Is anyone else seeing this or are the two of us running into the same rare edge case? Expected Outcome, seen on simulator running 26.2 Actual outcome, seen on device running 26.2.1
11
3
2k
2w
visionOS : any non-nil preferredSurroundingsEffect enables a light-spill halo around VideoPlayerComponent video
Hi all — sharing a platform behavior I isolated while building a custom immersive video player, in case others hit it (and to ask whether it's intended). Finding On visionOS 27 (Xcode 27), an entity playing video via VideoPlayerComponent(videoRenderer:) gets a light-spill "screen glow" halo around its edges whenever the immersive space declares any non-nil preferredSurroundingsEffect. The halo follows the video's colors frame by frame. With no surroundings effect (nil), there is no halo. Quick repro Progressive immersive space + VideoPlayerComponent playing. Add .preferredSurroundingsEffect(.dim(intensity: 0.0)) → halo appears (even though the effect is visually a no-op). Remove it → halo disappears. Same with .colorMultiply(_:) and preset effects. Things I ruled out on device (Vision Pro) ImmersiveContentBrightness (.custom(1.0) vs .automatic): no difference. VideoPlayerComponent configuration (.stereo, spatial video mode, isPassthroughTintingEnabled) and component attach timing: no difference. Presenting the same video via VideoMaterial: no halo. Bright white SwiftUI content: no halo. Questions Is this coupling intended? The preferredSurroundingsEffect docs don't mention any effect on video playback. Is there a public way to keep a surroundings effect (e.g. room dimming) while avoiding the video light spill? I found none on VideoPlayerComponent. Current workaround: don't declare any surroundings effect in the modes where the halo is undesirable. Also filed via Feedback Assistant(FB25130748). Curious if anyone else has seen this or knows a switch.
2
1
3.0k
2w
Xcode 27.1 compilation error possibly due to swift versions discrepancy
Compiling my project using Xcode 27.1 ends with an error: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX27.0.sdk/System/Library/Frameworks/SwiftUI.framework/Modules/SwiftUI.swiftmodule/arm64e-apple-macos.swiftinterface:1:1: error: failed to build module 'SwiftUI'; this SDK is not supported by the compiler (the SDK is built with 'Apple Swift version 6.4 effective-5.10 (swiftlang-6.4.0.31.4 clang-2100.3.31.1)', while this compiler is 'Apple Swift version 6.4 effective-5.10 (swiftlang-6.4.0.34.1 clang-2100.3.34.1)'). Please select a toolchain which matches the SDK. 1 | // swift-interface-format-version: 1.0 | `- error: failed to build module 'SwiftUI'; this SDK is not supported by the compiler (the SDK is built with 'Apple Swift version 6.4 effective-5.10 (swiftlang-6.4.0.31.4 clang-2100.3.31.1)', while this compiler is 'Apple Swift version 6.4 effective-5.10 (swiftlang-6.4.0.34.1 clang-2100.3.34.1)'). Please select a toolchain which matches the SDK. 2 | // swift-compiler-version: Apple Swift version 6.4 effective-5.10 (swiftlang-6.4.0.31.4 clang-2100.3.31.1) 3 | // swift-module-flags: -target arm64e-apple-macos27.0 -enable-objc-interop -target-arch-variant arm64e.x1 -enable-library-evolution -language-mode 5 -O -library-level api -enable-experimental-feature AnyAppleOSAvailability -enable-upcoming-feature InferSendableFromCaptures -enable-experimental-feature DebugDescriptionMacro -enable-bare-slash-regex -user-module-version 8.0.84.1.406 -module-name SwiftUI -package-name SwiftUICompiling it with Xcode 27 ends without error. Do you see any other root cause than the one mentionned: Xcode 27.1 uses swiftlang-6.4.0.34.1 clang-2100.3.34.1 while internal sdk was compiled with swiftlang-6.4.0.31.4 clang-2100.3.31.1 ?
1
0
221
2w
iOS options in place of opening 2nd window like on mcOS
I have an app that shows data in a 3-column NavigationSplitView, the columns being collections, items in each collection, and item details. Column 2 shows a toolbar button to add a new item. On Mac, that brings up a window where the user can search an online database and choose the data for that new item. But on iOS, Windows aren't allowed (as it says in the debugger when I try running on iPad in the Simulator). I've seen many examples of putting a NavigationStack inside the detail section of the NavigationSplitView. I want that to happen as the result of tapping the toolbar button. When I try, it does slide a new view into place (although it appears to be empty instead of showing the content in my custom View that provides the content for the 2nd window on Mac), and it then immediately slides away to reveal the original detail view. I'm using the code model presented in a SwiftyPlace example. class NavigationStateManager: ObservableObject { @Published var navPath = NavigationPath() func popToRoot() { navPath = NavigationPath() } func goToSearch() { self.navPath.append("search"); } }The main ContentView contains the NavigationSplitView. Its detail contains this: NavigationStack(path:$nav.navPath) { if !selectionStore.selectedItems.isEmpty { DetailView() } else { Text("Select an item."); } } .navigationDestination(for:String.self) { textValue in if textValue == "search" { SearchWindow() .modelContext(modelContext) } }Column 2's view handles the toolbar button, which calls this in that same view: private func addNewIItem() { #if os(macOS) withAnimation { openWindow(id:"Search"); } #else nav.goToSearch(); #endif }I hope I've added enough of this growing-larger-all-the-time project to show the basic setup. Why is the search view sliding in and then back out? Is there a better way to present another view over the top of the main window/view on iPad and iPhone?
Topic: Design SubTopic: General Tags:
Replies
2
Boosts
0
Views
347
Activity
1d
iOS 27: SwiftUI TextField text invisible while typing when the app runs in Arabic (FB25410049)
Since iOS 27, if an app runs in Arabic (or, presumably, any right-to-left language), typing digits or Latin letters into a SwiftUI TextField makes the field look empty. The binding updates and the caret shows, but the text isn't drawn until editing ends. What I measured: The text's layout fragment is placed at about x = −39,655 pt in a 370 pt wide field, so it's drawn far outside the field. A plain TextField and one with .environment(\.layoutDirection, .leftToRight) (phone and card numbers) are both affected. A UIKit UITextField on the same screen isn't affected. The same build on iOS 18.0 works, and iOS 27 in English works. Minimal repro: one SwiftUI file with four fields. Run it with App Language set to Arabic, tap the first field and type 523. Launch with -autoProbe to have it type into each field and print where the text was laid out. PROBE iOS 27.0, language ar, layout RTL PROBE field 1 text="523" fieldWidth=370 fragmentX=[-39655] visible=false // SwiftUI TextField PROBE field 2 text="523" fieldWidth=370 fragmentX=[-39655] visible=false // SwiftUI, LTR pinned PROBE field 3 text="523" fieldWidth=370 fragmentX=[314] visible=true // UIKit UITextFieldWorkaround that works for us, installed once at launch: import UIKit enum TextFieldDirection { static func install() { for name in [UITextField.textDidBeginEditingNotification, UITextField.textDidChangeNotification] { NotificationCenter.default.addObserver(forName: name, object: nil, queue: .main) { note in guard let field = note.object as? UITextField else { return } MainActor.assumeIsolated { settle(field) } // SwiftUI rebuilds the paragraph style right after; settle again. DispatchQueue.main.async { MainActor.assumeIsolated { settle(field) } } } } } @MainActor static func settle(_ field: UITextField) { let direction: NSWritingDirection = field.effectiveUserInterfaceLayoutDirection == .rightToLeft ? .rightToLeft : .leftToRight if let whole = field.textRange(from: field.beginningOfDocument, to: field.endOfDocument) { field.setBaseWritingDirection(direction, for: whole) } func directed(_ attributes: [NSAttributedString.Key: Any]) -> [NSAttributedString.Key: Any] { var attributes = attributes let style = (attributes[.paragraphStyle] as? NSParagraphStyle)?.mutableCopy() as? NSMutableParagraphStyle ?? NSMutableParagraphStyle() style.baseWritingDirection = direction attributes[.paragraphStyle] = style return attributes } if let typing = field.typingAttributes { field.typingAttributes = directed(typing) } field.defaultTextAttributes = directed(field.defaultTextAttributes) field.setNeedsLayout() field.layoutIfNeeded() } }Don't pin textAlignment instead. SwiftUI puts .natural back on every keystroke and the caret jumps from side to side. If you see this too, please file a duplicate referencing FB25410049. Duplicates help Apple prioritise it.
Replies
1
Boosts
0
Views
48
Activity
1d
Thin border around VideoPlayer
A thin gray border appears around assets presented using VideoPlayer. It was tested on iPhone 8, iPhone 13 mini, and iPhone 15, and the border only appeared on the 13 mini. The iOS version didn't matter, we checked the 13 mini on both iOS 18 and iOS 26 and the border appeared on both. I created a minimal version of the app with just the VideoPlayer and the asset and the frame still appeared. We tried different assets and it was visible on all of them. import SwiftUI import AVKit struct ContentView: View { private let player = AVPlayer(url: Bundle.main.url(forResource: "sample", withExtension: "mp4")!) var body: some View { VideoPlayer(player: player) .frame(width: 300, height: 200) } }I found someone that had the same exact problem on Reddit and StackOverflow: https://www.reddit.com/r/swift/comments/8s87hm/weird_borders_around_avplayerviewcontroller/ https://stackoverflow.com/questions/50927561/weird-borders-around-avplayerviewcontroller and their solution included setting: playerLayer.shouldRasterize = true playerLayer.rasterizationScale = UIScreen.main.scaleThis fixed the issue but isn't suitable for our app due to offscreen rendering performance. They also found that issue on other devices, noting: "After testing this code on multiple devices (actual physical devices, not simulators), this bug appears to happen only on Plus devices (I tested it on i8 on iOS 11, i8+ on iOS 11, iX on iOS 11 and i6+ on iOS 10)." The bug doesn't appear on simulator, isn't visible on a screenshot, the frame disappears when using accessibility zoom. When we encoded the video file to Apple ProRes the border disappeared, but the size of the video bumped from 342 KB to 6.3 MB so we couldn't do that. I'm attaching photo from this person's post since our issue looked exactly the same. Has anyone had a similar issue and maybe found another workaround?
Replies
0
Boosts
0
Views
226
Activity
1d
How do deal with NavigationSplitView not saving selection on iPhone
I have a detail view that has a @Binding var Thing, which is passed to it from the parent. It has TextFields that need to use that bound object's fields. // Using this to pass the selection around @Observable class AppSelection { var selectedThings:Set<Thing> = Set(); } struct ContentView: View { @State private var selectionStore = AppSelection(); var body: some View { NavigationSplitView { ... } content: { ...list that sets the selectionStore.selectedThings... } detail: { if !selectionStore.selectedThings.isEmpty { DetailView(thing:Binding( get: { selectionStore.selectedThings.first! }, // Crashes here set: { selectionStore.selectedThings = [$0] } )) .frame(maxHeight:.infinity, alignment:.top) } else { Text("Select a thing."); } } } } struct DetailView:View { @Binding var thing:Thing; var body:some View { TextField("Blah", $thing.name); TextField("Blerg", $thing.stuff); } }A crash happens when I navigate back from the DetailView in the line commented as such. I assume the NavigationSplitView is resetting the selection back to an empty state. Why the Binding given to the DetailView is even trying to get its value at that point is beyond me (so much weirdness in SwiftUI). I've taken so many different stabs at trying to make things work differently, but I just don't understand enough about SwiftUI. Like can I make the DetailView take an optional binding? If the Thing is nil, then all the TextFields complain that they require a non-optional binding. I don't even want to show the Detail view if nothing is selected (hence the "Select a thing.").
Replies
1
Boosts
0
Views
852
Activity
2d
Multiseat Subscriptions: Pricing Flexibility and Enterprise Implementation
I have questions about pricing flexibility and technical implementation. In WWDC26 Session 391, you introduced up to five volume pricing bands that allow developers to offer lower per-seat subscription prices as organizations purchase more seats. For example: 1–20 seats: $39.99/month per seat 21–40 seats: $29.99/month per seat 41+ seats: $19.99/month per seat Volume purchasing and volume discounting provide different benefits. Volume purchasing makes it easier for organizations to buy, deploy, and manage subscriptions. This is valuable independently of discounts. Consider a productivity application deployed to 10,000 employees. Unlike AI services that charge separately for tokens or usage credits, an application offering unlimited, unmetered usage receives no additional revenue beyond its subscription fees. Supporting 10,000 deployments also introduces ongoing responsibilities. Major updates, new capabilities, and performance improvements may require additional testing, deployment coordination, compatibility checks, and technical support. Enterprise customers often have greater requirements for reliability, timely updates, and deployment management. Reducing the fixed subscription price per seat does not reduce these responsibilities or account for the additional value delivered across an organization. My questions for the StoreKit team: Business pricing: Can developers create a separate business subscription with a higher base price than their consumer offering, such as $39.99/month for individuals and $59.99/month per business seat, with independent volume pricing bands? Business-only distribution: Can this subscription be offered exclusively through Apple Business while maintaining the existing consumer subscription? Business features in the same app: Can StoreKit 2 identify whether a user has an individual subscription or an organization-assigned seat, allowing developers to unlock additional business capabilities within the same app binary? Onboarding and deployment: What is the recommended approach for adapting onboarding, subscription unlocking, and access management for organization-assigned users? Are there specific considerations for MDM deployment and managed app configurations? Implementation resources: Are there technical documentation or sample projects covering multiseat purchases, entitlement verification, seat reassignment, subscription changes, and ongoing management after release? The primary opportunity is simplifying organizational purchasing and deployment, while allowing developers to deliver additional business value and price subscriptions according to the ongoing requirements of supporting organizations at scale—not simply discounting additional seats. I’d appreciate clarification on the recommended pricing configuration and StoreKit 2 implementation. Thank you. REF: October 22 Announcement — Offer your subscriptions to businesses and schools
Replies
0
Boosts
0
Views
79
Activity
2d
NavigationSplitView, endless loop detail<->content
Hi, I already had a problem with the NavigationSplitView before, and I'm still working on it. The NavigationSplitView issue on the phone occurs when trying to navigate back from the detail view to the content view; the app automatically navigates straight back to the detail view. I reproduced the issue in a small program and identified the critical section. However, I do not know why the problem is occurring. I did the same thing again, but this time with @Query, and there was no problem. The categories, recipes and single recipe, all loaded by @Query and no side effects. Requirements for the content: A state variable used in the view, e.g., isLoading A task that loads the data from a ModelActor in a ViewModel, setting isLoading to true beforehand and back to false upon completion Subsequently, it is only possible to exit the detail view after many attempts, because the app immediately navigates back to the detail view automatically upon trying to leave it. One issue is changing the isLoading status variable from within the task. That in itself isn't the problem; the issue only arises when reading data via a ModelActor. If the status variable is changed and, for example, the list is modified manually, there is no problem. It only occurs when a ModelActor is used. I based it on the NavigationCookbook: This is the view I use for the content section (list): @State private var vm: RecipeListViewModel = .init() @State var isLoading: Bool = false if isLoading { ProgressView("Loading...") } else { List(selection: $selectedRecipe) { ForEach(vm.recipes) { recipe in NavigationLink(recipe.name, value: recipe) } } } .task { // bug, when used in UI, because of ModelActor isLoading = true await vm.list(context, categoryName: selectedCategory.name) isLoading = false } .task { // works, because manually modifying the list isLoading = true await vm.addRecipe(context, categoryName: selectedCategory.name) isLoading = false } inside ViewModel // bug func list(_ modelContext: ModelContext, categoryName: String) async { recipes.removeAll() let dh: RecipeDataHandler = .init(modelContainer: modelContext.container) let values = await dh.listByName(categoryName: categoryName) for v in values { recipes.append(.init(recipeId: v.recipeId, name: v.name)) } } // works func addRecipe(_ modelContext: ModelContext, categoryName: String) async { isLoading = true defer { isLoading = false } recipes.removeAll() recipes.append(.init(recipeId: "a", name: "Pambazo")) } ModelActor @ModelActor actor RecipeDataHandler { func listByName(categoryName: String) async -> [RecipeData] { var list: [RecipeData] = [] do { let fd = FetchDescriptor<Recipe>(predicate: #Predicate { $0.category.name == categoryName }, sortBy: [SortDescriptor(\Recipe.name)]) let data = try modelContext.fetch(fd) for item in data { let rec: RecipeData = await .init(recipeId: item.recipeId, name: item.name) list.append(rec) } } catch { print("error: \(error.localizedDescription)") } return list } } Recipe is a @Model and RecipeData just a struct. In principle, everything should run on the MainActor, but the inclusion of the ModelActor still leads to this strange behavior. Any idea what the problem might be? Christian
Replies
3
Boosts
0
Views
343
Activity
3d
Non-collapsing title
In the Photos app, the Collections title doesn't collapse into a small inline title when scrolling, unlike a standard inline large title display mode. How is this implemented?
Replies
2
Boosts
0
Views
176
Activity
3d
NavigationSplitView Binding to NavigationSplitViewColumn reset with every NavigationStack path change
I try to create a Navigation that works on iPhone, iPhone Duo and iPad. NavigationSplitView collapses for compact form factors and makes iPhone Duo support much simpler. The Problem is the semantic of the collapse. Switch from detail to sidebar on compact is not a 'back' action in my case. It should have my choosen Icon and has a meaning. So i wanted to control this using the NavigationSpliViewColumn Binding. This does work forward and backward as long as no NavigationStack was used before. But it stops working when you return to the detail root from a Navigation-Action. I left the Backbutton visible so you can test, that it continues to work, when no Navigation-Action preceeded the switch. Here is my Code: import SwiftUI @Observable final class Compass { var path: [Route] init() { self.path = [] } } enum Route: Hashable { case goal } struct ContentView: View { @Environment(\.horizontalSizeClass) private var hsize @State private var compass: Compass = Compass() @State var column: NavigationSplitViewColumn = .detail var body: some View { NavigationSplitView(preferredCompactColumn: $column) { OverviewScreen(column: $column) } detail: { TodayScreen() .toolbar { ToolbarItem(placement: .topBarLeading) { Button("overview", systemImage: "calendar") { self.column = .sidebar } } } } .environment(compass) .onChange(of: column) { old, new in print("column:", old, "→", new) } } } struct OverviewScreen: View { @Binding var column: NavigationSplitViewColumn @Environment(Compass.self) var compass var body: some View { @Bindable var compass = self.compass ScrollView { Text("Overview") .font(.largeTitle) .fontWeight(.heavy) Button("Switch") { self.column = .detail } } } } struct TodayScreen: View { @Environment(Compass.self) var compass var body: some View { @Bindable var compass = self.compass NavigationStack(path: $compass.path) { ScrollView { Text("Today") .font(.largeTitle) .fontWeight(.heavy) Button("Goals programtically", systemImage: "flag.fill") { self.compass.path = [.goal] } NavigationLink(value: Route.goal) { Label("Goal Link", systemImage: "flag.fill") } } .navigationDestination(for: Route.self, destination: self.screen) } } @ContentBuilder func screen(for route: Route) -> some View { switch route { case .goal: Text("Goals") } } } #Preview { ContentView() }This seems unexpected behaviour. If you ask AI the mental model is NavigationSplitViewColumn represents which column is currently visible for the user. That model would be wrong. Also i can't understand why a NavigationStack has to change the Binding? What am i missing here? Is my idea of the programmatic switch not supported? There are other ways to push from compact to your detail column again, but they all have trade-offs or run into other problems. I would appreciate any help here. AI has not understood this and only does surface level work arounds that fix nothing.
Replies
0
Boosts
0
Views
44
Activity
5d
Accessibility Inspector Element Detection and contrast failures with SwiftUI sheets
I am investigating Accessibility Inspector/XCTest audit results in a SwiftUI app (Target Keeper), without suppressing warnings. Environment: Xcode 27.1 (27A9275), iPadOS 27.0 Simulator, macOS 27.0.1. Debug and Release builds pass. The app uses scalable text and labeled controls. Element Detection / native sheet Main-screen Element Detection passes when the sheet is closed. With a SwiftUI .sheet presented, the iPad audit reports “Potentially inaccessible text”; XCUIAccessibilityAuditIssue.element is nil. Exported Inspector HTML highlights background labels behind/outside the sheet, rather than a foreground control. The separate, data-free SwiftUI application below reproduces the modal-only warning; it links no application modules or persistence. Actual iPad Simulator VoiceOver testing using XCUIDevice.shared.voiceOverService passes forward/backward traversal of the real application's modal controls, without reaching the background labels. This is simulator evidence, not physical-device acceptance. A trial explicit modal container/.isModal trait did not clear the audit and was reverted; no warnings are filtered. Minimal independent app: import SwiftUI @main struct ModalRepro: App { @State private var showing=false private let names=["Vegetables","Protein","Fruit","Dairy","Grains","Healthy Fats"] var body:some Scene {WindowGroup { NavigationStack { VStack(spacing:24) { Button("Nutrition") {}.accessibilityLabel("Choose Page").accessibilityValue("Nutrition") LazyVGrid(columns:[GridItem(.flexible()),GridItem(.flexible()),GridItem(.flexible())],spacing:40) { ForEach(names,id:\.self) { name in Button {} label: { VStack(spacing:10) { Circle().fill(.blue.opacity(0.3)).frame(width:250,height:250) Text(name).font(.system(size:17)).accessibilityHidden(true) } }.buttonStyle(.plain).accessibilityLabel(name) } } Button("Show modal") {showing=true} }.padding(24).frame(maxWidth:.infinity,maxHeight:.infinity).background(Color.black) }.preferredColorScheme(.dark) .sheet(isPresented:$showing) { NavigationStack { VStack {Text("Foreground content");Button("Close") {showing=false}} .frame(maxWidth:.infinity,maxHeight:.infinity).background(Color.black) .navigationTitle("Modal flow") }.preferredColorScheme(.dark) } }} }In an Xcode UI-test target, launch this app, run try app.performAccessibilityAudit(for: [.elementDetection]), tap “Show modal”, then run the same audit again. The first passes and the second fails. No issue handler ignores failures. Contrast / scrolling — separate unresolved finding All four iPhone combined-audit configurations (portrait/landscape, normal/maximum Dynamic Type) pass in the tested picker state. However, iPad maximum-text combined audits and a separate scrolled iPhone maximum-text landscape contrast audit still fail; we are not calling these resolved. In the scrolled iPhone case, XCTest identifies a count label whose frame is entirely above the visible results viewport. Inspector's exported HTML reports 1.37:1 using #252526 versus #000000; its marked screenshot rectangle overlaps the dark search/header area, not visible count text. Visible sampled labels instead have white or light foregrounds on opaque dark fills (e.g. #FFFFFF/#1C1C1E = 17.01:1; #98989F/#1C1C1E = 5.94:1). These are screenshot core-pixel measurements, not proof every warning is false. We compare ordinary text against 4.5:1 and interactive non-text against 3:1. iPad maximum-text warnings have not yet been matched to an exact visible color pair. Original failures and HTML exports are preserved privately. Questions Is Element Detection expected to inspect background elements behind a presented native SwiftUI sheet? Is this a known tool limitation/framework issue, or does the sample need different semantics? What is the supported way to establish modal accessibility boundaries with SwiftUI sheets, and when should .isModal be added explicitly? How should we distinguish a real contrast defect from clipping, occlusion, translucency, or sampling of an offscreen element? Which Inspector export fields/diagnostics should establish the actual sampled text/background pair? What additional evidence/manual and physical-device tests does Apple recommend before qualifying accessibility when the minimal audit reproduction fails but actual VoiceOver modal focus behaves correctly? We are not asking to waive audits or declare full accessibility from a VoiceOver pass alone. I read Apple's audit guidance and modal trait documentation: https://developer.apple.com/documentation/accessibility/performing-accessibility-audits-for-your-app https://developer.apple.com/documentation/swiftui/accessibilitytraits/ismodal https://developer.apple.com/help/app-store-connect/manage-app-accessibility/sufficient-contrast-evaluation-criteria/ Related discussion https://developer.apple.com/forums/thread/823968 recommends Feedback for a different apparent Dynamic Type false positive; it does not answer these modal/contrast questions. A Feedback draft is prepared but not submitted, so I have no Feedback ID yet. No private data, identifiers, credentials, app containers or confidential application source are included.
Replies
1
Boosts
0
Views
810
Activity
6d
iPhone Duo: SwiftUI Layout Differs Between Simulator and Physical Device (Tab Bar Placement and Content Cropping)
Hi everyone, I'm experiencing a significant difference in SwiftUI layout behavior between the iPhone Duo simulator and a physical iPhone Duo. I've already adjusted my layout to work correctly in the simulator, but the same app behaves differently on the actual device. 1. Folded Simulator: The tab bar is positioned on the right side, as expected for iPhone Duo. The view respects the right-side layout, and scroll views extend naturally behind the tab bar, behaving as expected. Physical device: The tab bar appears at the bottom, like a regular iPhone, instead of on the right. The view is also cropped on the right side. 2. Unfolded Simulator: The tab bar and navigation view both appear correctly. Physical device: The tab bar remains at the bottom, even in landscape orientation, instead of using the expected Duo layout. The main content also starts from the bottom of the navigation view, resulting in an incorrect layout. The most confusing part is that the layout works correctly in the simulator but not on the physical device. Has anyone encountered this behavior on a physical iPhone Duo? Could this be related to the iOS version, SDK version, SwiftUI's automatic tab bar adaptation, or a device-specific bug? I'd appreciate any insights, especially from developers who have tested their SwiftUI apps on actual iPhone Duo hardware. Environment: Xcode version: 27.1 iOS SDK: 27.1 Physical device iOS version: 27.2 Thanks!
Replies
1
Boosts
0
Views
104
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
83
Activity
1w
Virtual keyboard in preview
Hello, When I click in the box to write a text (in preview) the virtual keyboard does not appear. On the other hand, when I want to write my script, the keyboard appears well. This one works perfectly in all my applications on the iPad. I could read on the internet that this would come from a problem with the Swift Playground application. I uninstalled and then reinstalled the application but the problem is still present. Thanks
Replies
2
Boosts
0
Views
121
Activity
1w
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
125
Activity
1w
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
98
Activity
1w
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
290
Activity
1w
requestReview() prompting repeatedly
We're getting user reports that the App Store rating prompt appears repeatedly — one user says they're prompted roughly every day, and that they still get the prompt after they've already left a rating. This contradicts the documented behavior, so I want to check whether others are seeing the same thing or whether there's a known regression. What the docs say should happen The system limits display to 3 occurrences per app within a 365-day period. For a user who has already rated/reviewed, StoreKit should only display again if the app version is new and more than 365 days have passed since their previous review. Has anyone else experience it?
Replies
4
Boosts
2
Views
1.3k
Activity
1w
.contactAccessPicker shows blank sheet on iOS 26.2.1 on device
Calling contactAccessPicker results in a blank sheet and a jetsam error, rather than the expected contact picker, using Apple’s sample code, only on device with iOS 26.2.1. This is happening on a iPhone 17 Pro Max running 26.2.1, and not on a simulator. I’m running Apple's sample project Accessing a person’s contact data using Contacts and ContactsUI Steps: Run the sample app on device running iOS 26.2.1. Use the flow to authorize .limited access with 1 contact: Tap request access, Continue, Select Contacts. Select a contact, Continue, Allow Selected Contact. This all works as expected. Tap the add contact button in the toolbar to add a second contact. Expected: This should show the Contact Access Picker UI. Actual: Sheet is shown with no contents. See screenshot of actual results on iOS device running 26.2.1. Reported as FB21812568 I see a similar (same?) error reported for 26.1. It seems strange that the feature is completely broken for multiple point releases. Is anyone else seeing this or are the two of us running into the same rare edge case? Expected Outcome, seen on simulator running 26.2 Actual outcome, seen on device running 26.2.1
Replies
11
Boosts
3
Views
2k
Activity
2w
visionOS : any non-nil preferredSurroundingsEffect enables a light-spill halo around VideoPlayerComponent video
Hi all — sharing a platform behavior I isolated while building a custom immersive video player, in case others hit it (and to ask whether it's intended). Finding On visionOS 27 (Xcode 27), an entity playing video via VideoPlayerComponent(videoRenderer:) gets a light-spill "screen glow" halo around its edges whenever the immersive space declares any non-nil preferredSurroundingsEffect. The halo follows the video's colors frame by frame. With no surroundings effect (nil), there is no halo. Quick repro Progressive immersive space + VideoPlayerComponent playing. Add .preferredSurroundingsEffect(.dim(intensity: 0.0)) → halo appears (even though the effect is visually a no-op). Remove it → halo disappears. Same with .colorMultiply(_:) and preset effects. Things I ruled out on device (Vision Pro) ImmersiveContentBrightness (.custom(1.0) vs .automatic): no difference. VideoPlayerComponent configuration (.stereo, spatial video mode, isPassthroughTintingEnabled) and component attach timing: no difference. Presenting the same video via VideoMaterial: no halo. Bright white SwiftUI content: no halo. Questions Is this coupling intended? The preferredSurroundingsEffect docs don't mention any effect on video playback. Is there a public way to keep a surroundings effect (e.g. room dimming) while avoiding the video light spill? I found none on VideoPlayerComponent. Current workaround: don't declare any surroundings effect in the modes where the halo is undesirable. Also filed via Feedback Assistant(FB25130748). Curious if anyone else has seen this or knows a switch.
Replies
2
Boosts
1
Views
3.0k
Activity
2w
Xcode 27.1 compilation error possibly due to swift versions discrepancy
Compiling my project using Xcode 27.1 ends with an error: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX27.0.sdk/System/Library/Frameworks/SwiftUI.framework/Modules/SwiftUI.swiftmodule/arm64e-apple-macos.swiftinterface:1:1: error: failed to build module 'SwiftUI'; this SDK is not supported by the compiler (the SDK is built with 'Apple Swift version 6.4 effective-5.10 (swiftlang-6.4.0.31.4 clang-2100.3.31.1)', while this compiler is 'Apple Swift version 6.4 effective-5.10 (swiftlang-6.4.0.34.1 clang-2100.3.34.1)'). Please select a toolchain which matches the SDK. 1 | // swift-interface-format-version: 1.0 | `- error: failed to build module 'SwiftUI'; this SDK is not supported by the compiler (the SDK is built with 'Apple Swift version 6.4 effective-5.10 (swiftlang-6.4.0.31.4 clang-2100.3.31.1)', while this compiler is 'Apple Swift version 6.4 effective-5.10 (swiftlang-6.4.0.34.1 clang-2100.3.34.1)'). Please select a toolchain which matches the SDK. 2 | // swift-compiler-version: Apple Swift version 6.4 effective-5.10 (swiftlang-6.4.0.31.4 clang-2100.3.31.1) 3 | // swift-module-flags: -target arm64e-apple-macos27.0 -enable-objc-interop -target-arch-variant arm64e.x1 -enable-library-evolution -language-mode 5 -O -library-level api -enable-experimental-feature AnyAppleOSAvailability -enable-upcoming-feature InferSendableFromCaptures -enable-experimental-feature DebugDescriptionMacro -enable-bare-slash-regex -user-module-version 8.0.84.1.406 -module-name SwiftUI -package-name SwiftUICompiling it with Xcode 27 ends without error. Do you see any other root cause than the one mentionned: Xcode 27.1 uses swiftlang-6.4.0.34.1 clang-2100.3.34.1 while internal sdk was compiled with swiftlang-6.4.0.31.4 clang-2100.3.31.1 ?
Replies
1
Boosts
0
Views
221
Activity
2w