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

NavigationSplitView no longer pops back to the root view when selection = nil in iOS 26.4 (with a nested TabView)
In iOS 26.4 (iPhone, not iPad), when a NavigationSplitView is combined with a nested TabView, it no longer pops back to the root sidebar view when the List selection is set to nil. This has been working fine for at least a few years, but has just stopped working in iOS 26.4. Here's a minimal working example: import SwiftUI struct ContentView: View { @State var articles: [Article] = [Article(articleTitle: "Dog"), Article(articleTitle: "Cat"), Article(articleTitle: "Mouse")] @State private var selectedArticle: Article? = nil var body: some View { NavigationSplitView { TabView { Tab { List(articles, selection: $selectedArticle) { article in Button { selectedArticle = article } label: { Text(article.title) } } } label: { Label("Explore", systemImage: "binoculars") } } } detail: { Group { if let selectedArticle { Text(selectedArticle.title) } else { Text("No selected article") } } .navigationBarBackButtonHidden(true) .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Close", systemImage: "xmark") { selectedArticle = nil } } } } } } struct Article: Identifiable, Hashable { let id: String let title: String init(articleTitle: String) { self.id = articleTitle self.title = articleTitle } } First, I'm aware that nesting a TabView inside a NavigationSplitView is frowned upon: Apple seems to prefer NavigationSplitView nested inside a Tab. However, for my app, that leads to a very confusing user experience. Users quickly get lost because they end up with different articles open in different tabs and it doesn't align well with my core distinction between two "modes": article selection mode and article reading mode. When the user is in article selection mode (sidebar view), they can pick between different ways of selecting an article (Explore, Bookmarks, History, Search), which are implemented as "tabs". When they pick an article from any tab they jump into article reading mode (the detail view). Second, I'm using .navigationBarBackButtonHidden(true) to remove the auto back button that pops back to the sidebar view. This button does still work in iOS 26.4, even with the nested TabView. However, I can't use the auto back button because my detail view is actually a WebView with its own back/forward logic and UI. Therefore, I need a separate close button to exit from the detail view. My close button sets selectedArticle to nil, which (pre-iOS 26.4) would trigger the NavigationSplitView to pop back to the sidebar view. For some reason, in iOS 26.4 the NavigationSplitView doesn't seem to bind correctly to the List's selection parameter, specifically when there's a TabView nested between them. Or, rather, it binds, but fails to pop back when selection becomes nil. One option is to replace NavigationSplitView with NavigationStack (on iPhone). NavigationStack still works with a nested TabView, but it creates other downstream issues for me (as well as forcing me to branch for iPhone and iPad), so I'd prefer to continue using NavigationSplitView. Does anyone have any ideas about how to work around this problem? Is there some way of explicitly telling NavigationSplitView to pop back to the sidebar view on iPhone? (I've tried setting the column visibility but nothing seems to work). Thanks for any help!
1
1
149
18h
Is it possible to focus a non-textField on iPadOS in SwiftUI?
I would like to implement a focus-based Menu-Bar command in my SwiftUI iPadOS app, or react to key command while certain elements are focused. Traditionally, this requires using @FocusedValue and focusable() and focused, however, it appears that setting a @FocusState on macOS will work, but setting a @FocusState on iPadOS will never work. How can this API work and support MenuBar commands and keyboard inputs? It kind of has an accessibility impact as well. Not all users are going to know, or want to turn on "full keyboard control" for basic interactions. Here's a small sample that doesn't appear to focus on iPadOS: struct FocusableTestView: View { @FocusState private var isRectFocused: Bool var body: some View { VStack { // This text field should focus the custom input when pressing return: TextField("Enter text", text: .constant("")) .textFieldStyle(.roundedBorder) .onSubmit { isRectFocused = true } .onKeyPress(.return) { isRectFocused = true return .handled } // This custom "input" should focus itself when tapped: Rectangle() .fill(isRectFocused ? Color.accentColor : Color.gray.opacity(0.3)) .frame(width: 100, height: 100) .overlay( Text(isRectFocused ? "Focused" : "Tap me") ) .focusable(true) .focused($isRectFocused) .onTapGesture { isRectFocused = true print("Focused rectangle") } // The focus should be able to be controlled externally: Button("Toggle Focus") { isRectFocused.toggle() } .buttonStyle(.bordered) } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) } }
0
0
134
3d
Focusable doesn't work on iPad with external keyboard
I have a custom input view in my app which is .focusable(). It behaves similar to a TextField, where it must be focused in order to be used. This works fine on all platforms including iPad, except when when an external keyboard is connected (magic keyboard), in which case it can't be focused anymore and becomes unusable. Is there a solution to this, or a workaround? My view is very complex, so simple solutions like replacing it with a native view isn't possible, and I must be able to pragmatically force it to focus. Here's a very basic example replicating my issue. Non of the functionality works when a keyboard is connected: struct FocusableTestView: View { @FocusState private var isRectFocused: Bool var body: some View { VStack { // This text field should focus the custom input when pressing return: TextField("Enter text", text: .constant("")) .textFieldStyle(.roundedBorder) .onSubmit { isRectFocused = true } .onKeyPress(.return) { isRectFocused = true return .handled } // This custom "input" should focus itself when tapped: Rectangle() .fill(isRectFocused ? Color.accentColor : Color.gray.opacity(0.3)) .frame(width: 100, height: 100) .overlay( Text(isRectFocused ? "Focused" : "Tap me") ) .focusable(true, interactions: .edit) .focused($isRectFocused) .onTapGesture { isRectFocused = true print("Focused rectangle") } // The focus should be able to be controlled externally: Button("Toggle Focus") { isRectFocused.toggle() } .buttonStyle(.bordered) } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) } }
2
0
277
3d
Is updateUIViewController always called immediately after makeUIViewController?
I'm in the unenviable position of needing the current UIViewController to keep an external library happy. Essentially, I need to do this in SwiftUI: import LibraryOutOfMyControl ViewControllerReader { viewController in Button("Action") { LibraryOutOfMyControl.action(with: viewController) } } My simple attempt below functions correctly but I'm relying on makeUIViewController always being immediately followed by updateUIViewController. Is the a reasonable assumption or should I set everything up assuming updateUIViewController might never be called? struct ViewControllerReader<Content>: UIViewControllerRepresentable where Content: View { @ViewBuilder var content: (UIViewController) -> Content func makeUIViewController(context: Context) -> UIHostingController<Content> { UIHostingController(rootView: content(UIViewController())) } func updateUIViewController(_ uiViewController: UIHostingController<Content>, context: Context) { uiViewController.rootView = content(uiViewController) uiViewController.view.isUserInteractionEnabled = context.environment.isEnabled } func sizeThatFits(_ proposal: ProposedViewSize, uiViewController: UIHostingController<Content>, context: Context) -> CGSize? { uiViewController.sizeThatFits(in: proposal.replacingUnspecifiedDimensions()) } }
0
0
95
4d
SwiftUI navigation bar button color changes depending on whether the root view is a ScrollView or VStack
I have a SwiftUI view inside a NavigationStack with a custom navigation bar background color. I want the navigation bar buttons to have a consistent color throughout the app. The issue is that the navigation bar button color changes depending on the first/root view in the body. When the root view is a ScrollView var body: some View { ScrollView { // content } .toolbarBackground(Color(red: 0.02, green: 0.27, blue: 0.13), for: .navigationBar) .toolbarBackground(.visible, for: .navigationBar) .toolbarColorScheme(.dark, for: .navigationBar) } The navigation bar buttons appear white. However, if I replace the ScrollView with a VStack, while keeping the same modifiers, the navigation bar buttons appear black: var body: some View { VStack { // content } .toolbarBackground(Color(red: 0.02, green: 0.27, blue: 0.13), for: .navigationBar) .toolbarBackground(.visible, for: .navigationBar) .toolbarColorScheme(.dark, for: .navigationBar) } The navigation bar buttons appear black. How can I make the navigation bar buttons stay the same colour in both cases?
1
0
176
4d
.disabled() doesn't VISUALLY disable buttons inside ToolbarItem on iOS 26 devices
[Also submitted as FB19313064] The .disabled() modifier doesn't visually disable buttons inside a ToolbarItem container on iOS 26.0 (23A5297i) devices. The button looks enabled, but tapping it doesn't trigger the action. When deployment target is lowered to iOS 18 and deployed to an iOS 18 device, it works correctly. It still fails on an iOS 26 device, even with an iOS 18-targeted build. This occurs in both the Simulator and on a physical device. Screen Recording Code struct ContentView: View { @State private var isButtonDisabled = false private var osTitle: String { let version = ProcessInfo.processInfo.operatingSystemVersion return "iOS \(version.majorVersion)" } var body: some View { NavigationStack { VStack { Button("Body Button") { print("Body button tapped") } .buttonStyle(.borderedProminent) .disabled(isButtonDisabled) Toggle("Disable buttons", isOn: $isButtonDisabled) Spacer() } .padding() .navigationTitle("Device: \(osTitle)") .navigationBarTitleDisplayMode(.large) .toolbar { ToolbarItem { Button("Toolbar") { print("Toolbar button tapped") } .buttonStyle(.borderedProminent) .disabled(isButtonDisabled) } } } } }
8
3
720
5d
SwiftData 'simple' migration failing
This is a long post, so let me start with a summary: I am attempting to implement what "ought to be" a simple SwiftData migration, and am receiving the following fatal error from the ModelContainer initializer: NSCocoaErrorDomain Code=134504 "Cannot use staged migration with an unknown model version." The crash occurs both in the Simulator and on a physical device. Both the original schema and the new schema load and run as expected if loaded from scratch — so I conclude the Models are OK; it is the migration from the original schema to the new schema which is the issue. I have reported this as FB22652791 and Technical Incident Case # 19893980. I have two model projects available — one contrived, the other using my actual SwiftData models. Now the Details I am developing a SwiftUI/SwiftData app. I am (currently) using Xcode 26.5-beta-3. I set up an alpha-test build using the following approach: public class DatabaseSchema { public let dbSchema: Schema = Schema([ Model1.self, ... , Model16.self ], version: Schema.Version(0, 9, 0)) public var modelContainer: ModelContainer { let container: ModelContainer let modelConfiguration = ModelConfiguration(schema: dbSchema, isStoredInMemoryOnly: false) do { container = try ModelContainer(for: dbSchema, migrationPlan: nil, configurations: [modelConfiguration]) } catch { fatalError("Failed to creae model conainer") } return container } This defines database version 0.9. For version 1.0, I made three changes to the database: added an attribute of type String to Model2. added three attributes of type [Struct], where Struct conforms to Codable, Equatable and Hashable to Model3, and added a new model (which I'll call Model17) I define two schemas: public enum Schema090: VersionedSchema { public static var versionIdentifier = Schema.Version(0, 9, 0) public static var models: [any PersistentModel.Type] = [ Model1.self, Schema090.Model2.self, Schema090.Model3.self, ... ] } and public enum Schema100: VersionedSchema { public static var versionIdentifier = Schema.Version(1, 0, 0) public static var models: [any PersistentModel.Type] = [ Model1.swift, Schema100.Model2.self, Schema100.Model3.self, ..., Model16.self, Schema100.Model17.self ] } For models that changed, I use the following approach: public typealias Model3 = Schema100.Model3 extension Schema090 { @Model final class Model3 { ... } public init() { ... } } extension Schema100 { @Model final class Model3 { ... <added attributes, initialized> } public init() { ... } } The DatabaseSchema class was modified as follows: public class DatabaseSchema { public let dbSchema: Schema = Schema([ Model1.self, Schema100.Model2.self, Schema100.Model3.self, ... , Model16.self, Schema100.Model17.self ], version: Schema.Version(1, 0, 0)) public var modelContainer: ModelContainer { let container: ModelContainer let modelConfiguration = ModelConfiguration(schema: dbSchema, isStoredInMemoryOnly: false) do { container = try ModelContainer(for: dbSchema, migrationPlan: MigrationPlan.self, configurations: [modelConfiguration]) } catch { fatalError("Failed to creae model conainer") } return container } where the migration plan is the trivial custom migration that makes sure that all added attributes of existing records are properly initialized. enum MigrationPlan: SchemaMigrationPlan { static var schemas: [any VersionedSchema.Type] = [ Schema090.self, Schema100.self ] static var stages: [MigrationStage] = [version090ToVersion100] static let version090ToVersion100 = MigrationStage(fromVersion: Schema090.self, toVersion: Schema100.self, willMigrate: { _ in }, didMigrate: { context in let models = try context.fetch( FetchDescriptor<Schema100.Model3>()) for model in models { < initial the added attributes > { try context.save() }) } This is all simple stuff. Nothing particularly fancy here. But running this code always crashes in the ModelContainer initializer. In my two sample projects, I get two different error messages — in the contrived example, the error message is Code=134110 "An error occurred during persistent store migration." reason=Cannot migrate store in-place: Validation error missing attribute values on mandatory destination attribute, ... and in the sample project that uses my actual data model, I get NSCocoaErrorDomain Code=134504 "Cannot use staged migration with an unknown model version." My Thoughts Since obviously most folks are doing SwiftData migrations without the problems I am experiencing, the obvious possibilities are I'm doing something stupid that I just don't see. There is a problem because the original schema was given a version value of Schema.Version(0, 9, 0). (i.e., major version number was 0) There is a problem because I am adding an attribute of type [Struct] where Struct is Codable, Hashable, and Equatable. I.e., migration isn't working properly with attributes which are stored as their codable representations. Or maybe something else? In any case, any help you can offer would be greatly appreciated.
5
0
494
5d
SwiftUI Button with Image view label has smaller hit target
[Also submitted as FB20213961] SwiftUI Button with a label: closure containing only an Image view has a smaller tap target than buttons created with a Label or the convenience initializer. The hit area shrinks to the image bounds instead of preserving the standard minimum tappable size. SCREEN RECORDING On a physical device, the difference is obvious—it’s easy to miss the button. Sometimes it even shows the button-tapped bounce animation but doesn’t trigger the action. SYSTEM INFO Xcode Version 26.0 (17A321) macOS 15.6.1 (24G90) iOS 26.0 (23A340) SAMPLE CODE The following snippet shows the difference in hit targets between the convenience initializer, a Label, and an Image (the latter two in a label: closure). // ✅ Hit target is entire button Button("Button 1", systemImage: "1.square.fill") { print("Button 1 tapped") } // ✅ Hit target is entire button Button { print("Button 2 tapped") } label: { Label("Button 2", systemImage: "2.square.fill") } // ❌ Hit target is smaller than button Button { print("Button 3 tapped") } label: { Image(systemName: "3.square.fill") }
6
4
465
5d
Changing systemImage value for Image, logs "fopen failed for data file".
I'm getting a log error and a slight delay in the UI when displaying a system image that changes at the end of a sequence. I'm using a ternary operator to determine the image; the fact that the image changes seem to be the issue, rather than the value itself. The issue only occurs for a newly installed app, and not when the app is rerun. (I'm using similar code to display an onboarding sequence after installation.) This happens on device (iphone 15 pro v25.6) and simulator (iphone 17 pro v25.6 and iphone 16 pro v18.5); xcode 26.5 (17F42). Console errors (device and iphone 17 simulator): fopen failed for data file: errno = 2 (No such file or directory) fopen failed for data file: errno = 2 (No such file or directory) Repro Code: import SwiftUI struct ContentView: View { // NOTE: error only occurs with new install. @State private var currentItem = 0 @State private var totalItems: Int = 4 var body: some View { VStack(spacing: 0) { Spacer() Text("totalItems: \(totalItems)") TabView(selection: $currentItem) { ForEach(0...totalItems, id: \.self) { item in Text("\(item) ~ \(currentItem)") .tag(item) } } //TV .tabViewStyle(.page(indexDisplayMode: .never)) .frame(height: 200) Button { if currentItem < totalItems { currentItem += 1 currentItem = min(totalItems, currentItem) } } label: { let imgString: String = (currentItem == totalItems ? "arrowshape.turn.up.right" : "arrowshape.right") // error // let imgString: String = ((currentItem == totalItems) ? "x.circle" : "smallcircle.filled.circle") // error // let imgString: String = "smallcircle.filled.circle" // no error // let imgString: String = "x.circle" // no error Text("\(imgString)") // if only print text, no error, so issue seems to be with Image. Image(systemName: imgString) } Spacer() } } } Click through the button sequence to see issue at end of sequence. Uncomment the various imgString lines to see indicated differences in behavior. Need to delete app each time to repro issue. Running in simulator on iphone 16 Pro iOS 18.5 has slightly different error messages: fopen failed for data file: errno = 2 (No such file or directory) Errors found! Invalidating cache... fopen failed for data file: errno = 2 (No such file or directory) Errors found! Invalidating cache...
1
0
56
5d
iOS 26 rendering gap on scroll surfaces — lower scroll view does not render
On iOS 26 (26.0–26.5), a rectangular region in the lower half of the screen sometimes does not render while the content underneath remains laid out and interactive — scrolling works, hit testing succeeds, and rows visibly emerge from behind the floating tab bar as you scroll. This is a render-server / compositor gap, not a layout or safe-area issue. We see it on both UIKit and SwiftUI scroll surfaces inside the same UITabBarController: UIKit: UICollectionView with UICollectionViewFlowLayout (sectionInsetReference = .fromSafeArea) SwiftUI: List(.plain) nested in TabView(.page) inside a UIHostingController Confirmed on iPhone 16 Pro, iPhone 17 Pro, iPhone 13 Pro Max. Community threads (linked below) report the same symptom in Messages, Notes, Safari, Mail, and the App Store. Questions for Apple Is this acknowledged as an OS-level regression, and is a fix targeted for an upcoming iOS 26.x release? Is there a deterministic repro? We've tried background/foreground cycles, push notifications mid-scroll, tab switches during inertia, lock/unlock, orientation flips, simulated memory warnings, layout-invalidation storms, and trait-collection cycles — none reliably trigger it on our test devices. Is there a developer-side mitigation (e.g. avoiding specific UIVisualEffectView / Glass configurations, opting out of a rendering optimization) until a system fix lands? Is there a runtime signal on CALayer or UIScrollView we can inspect to detect this gap state and force a recovery (tile redraw, backing-store discard, etc.)? Notes We cannot reproduce locally. Affected users hit it organically; once it appears it persists across re-layout until the view controller is torn down. Community reports consistently mention Reduce Transparency being enabled on affected devices, and toggling it off clears the issue for many. In our own testing, RT alone is not sufficient to trigger the bug — it appears to be a contributing condition rather than the trigger. References: Apple Discussions: https://discussions.apple.com/thread/256182149 Reddit r/ios (multiple system apps): https://www.reddit.com/r/ios/comments/1nlzn7f/some_apps_cutting_off_half_the_display/ https://www.idownloadblog.com/2026/03/23/webpage-content-cutting-off-safari/
2
2
253
1w
Application Hangs with Nested LazyVStack When Accessibility Inspector is Active
Description I've encountered a consistent hang/freeze issue in SwiftUI applications when using nested LazyVStack containers with Accessibility Inspector (simulator) or VoiceOver (physical device) enabled. The application becomes completely unresponsive and must be force-quit. Importantly, this hang occurs in a minimal SwiftUI project with no third-party dependencies, suggesting this is a framework-level issue with the interaction between SwiftUI's lazy view lifecycle and the accessibility system. Reproduction Steps I've created a minimal reproduction project available here: https://github.com/pendo-io/SwiftUI_Hang_Reproduction To Reproduce: Create a SwiftUI view with the following nested LazyVStack structure: struct NestedLazyVStackView: View { @State private var outerSections: [Int] = [] @State private var innerRows: [Int: [Int]] = [:] var body: some View { ScrollView { LazyVStack(alignment: .leading, spacing: 24) { ForEach(outerSections, id: \.self) { section in VStack(alignment: .leading, spacing: 8) { Text("Section #\(section)") // Nested LazyVStack LazyVStack(alignment: .leading, spacing: 2) { ForEach(innerRows[section] ?? [], id: \.self) { row in Text("Section #\(section) - Row #\(row)") .onAppear { // Load more data when row appears loadMoreInner(section: section) } } } } .onAppear { // Load more sections when section appears loadMoreOuter() } } } } } } Enable Accessibility Inspector in iOS Simulator: Xcode → Open Developer Tool → Accessibility Inspector Select your running simulator Enable Inspection mode (eye icon) Navigate to the view and start scrolling Result: The application hangs and becomes unresponsive within a few seconds of scrolling Expected Behavior The application should remain responsive when Accessibility Inspector or VoiceOver is enabled, allowing users to scroll through nested lazy containers without freezing. Actual Behavior The application freezes/hangs completely CPU usage may spike The app must be force-quit to recover The hang occurs consistently and is reproducible Workaround 1: Replace inner LazyVStack with VStack LazyVStack { ForEach(...) { section in VStack { // ← Changed from LazyVStack ForEach(...) { row in ... } } } } Workaround 2: Embed in TabView TabView { NavigationStack { NestedLazyVStackView() // ← Same nested structure, but no hang } .tabItem { ... } } Interestingly, wrapping the entire navigation stack in a TabView prevents the hang entirely, even with the nested LazyVStack structure intact. Questions for Apple Is there a known issue with nested LazyVStack containers and accessibility traversal? Why does wrapping the view in a TabView prevent the hang? Are there recommended patterns for using nested lazy containers with accessibility support? Is this a timing issue, a deadlock, or an infinite loop in the accessibility system? Why that happens? Reproduction Project A complete, minimal reproduction project is available at: https://github.com/pendo-io/SwiftUI_Hang_Reproduction
5
0
482
1w
Tab button's ax identifier is missing when using `.sidebarAdaptable` TabViewStyle
Hello, I found that if you apply the new .sidebarAdaptable tab view style, the accessibility identifiers of tab bar buttons are missing. import SwiftUI struct ContentView: View { var body: some View { TabView { Tab("Received", systemImage: "tray.and.arrow.down.fill") { Text("Received") } .accessibilityIdentifier("tab.received") // 👀 Tab("Sent", systemImage: "tray.and.arrow.up.fill") { Text("Sent") } .accessibilityIdentifier("tab.sent") // 👀 Tab("Account", systemImage: "person.crop.circle.fill") { Text("Account") } .accessibilityIdentifier("tab.account") // 👀 } .tabViewStyle(.sidebarAdaptable) // 👈 if remove this, ax identifiers are ok } } #Preview { ContentView() } The identifiers automatically appear after a few seconds. But this behaviour breaks a lot of the UI test cases.
3
0
651
1w
Popover in Toolbar Causes Crash in Catalyst App on macOS 26
Hi everyone, I’ve encountered an issue where using a popover inside the toolbar of a Catalyst app causes a crash on macOS 26 beta 5 with Xcode 26 beta 5. Here’s a simplified code snippet: import SwiftUI struct ContentView: View { @State private var isPresentingPopover = false var body: some View { NavigationStack { VStack { } .padding() .toolbar { ToolbarItem { Button(action: { isPresentingPopover.toggle() }) { Image(systemName: "bubble") } .popover(isPresented: $isPresentingPopover) { Text("Hello") .font(.largeTitle) .padding() } } } } } } Steps to reproduce: Create a new iOS app using Xcode 26 beta 5. Enable Mac Catalyst (Match iPad). Add the above code to show a Popover from a toolbar button. Run the app on macOS 26, then click the toolbar button. The app crashes immediately upon clicking the toolbar button. Has anyone else run into this? Any workarounds or suggestions would be appreciated! Thanks!
6
2
611
1w
Glass effect interactive effect issue when used with concentric shapes
Using .glassEffect(.clear.interactive(), in: shape), where shape is some concentric shape that adapts to corner radius of the device, results in appearing of highlighted capsule shape. Code to reproduce this behavior import SwiftUI struct HelloLiquidGlass: View { var body: some View { if #available(iOS 26.0, *) { Text("Hello, World!") .frame(maxWidth: .infinity, maxHeight: .infinity) // .glassEffect(.clear.interactive(), in: .rect(corners: .concentric)) // .glassEffect(.clear.interactive(), in: ConcentricRectangle(uniformTopCorners: .fixed(80))) .padding(36) .ignoresSafeArea() .preferredColorScheme(.dark) } } } #Preview { HelloLiquidGlass() } Either of both commented-out modifiers produces the same result when user interacts with Liquid Glass pane (revealing of capsule shape that is not relative to actual shape of liquid glass effect modifier) iOS 26.5 (23F73) SDK + iOS 26.5 (23F77) Simulator
3
0
300
1w
SwiftUI template in Instruments 26.4.1 shows empty channels on iOS 26.4.2 device — even with a minimal TimelineView repro
Hi all, I've hit a reproducible issue where the presence of the SwiftUI instrument in a template prevents any data from being recorded, including from the other instruments in the same template. Removing the SwiftUI instrument immediately restores normal recording. Environment Host: macOS 26.4.1 (25E253), Mac mini Xcode / Instruments 26.4.1 (17E202) Device: iPhone 17, iOS 26.4.2 (23E261) (physical device, USB-attached) Symptom Recording the same app, same device, same session, only varying the template contents: SwiftUI template (as-is) => All lanes empty across the entire recording Same template with the SwiftUI instrument removed => Data collected normally (Time Profiler samples, Hangs, etc.) So it seems not an issue with the SwiftUI lanes specifically being empty — including the SwiftUI instrument appears to silence the entire recording. Steps to reproduce Open Instruments → pick the SwiftUI template (or build a custom template that includes the SwiftUI instrument alongside, e.g., Time Profiler). Target the device, attach to the running app. Record for ~10s, interact with the app. Stop. Result: every lane is empty. Edit the template, remove the SwiftUI instrument, re-record with no other changes. Result: normal data appears in the remaining instruments. Questions Is this a known regression in Instruments 26.4.1 on iOS 26.4.x? Is there a workaround to use the SwiftUI instrument on this OS combo (different Xcode build, runtime flag, entitlement)? Does it work for anyone on iOS 26.4.x + Xcode 26.4.1, or is everyone seeing this? I can file a Feedback if confirmed as a bug — wanted to check here first in case I'm missing a setup step. Thanks!
2
1
145
2w
Textfield with both a formatter and axis
Hi, is there any textfield init with both formatter and axis for multiline? I notice the there are both an init to include a formatter like so: init(_:value:formatter:prompt:) and another one to include an axis for multiline like so: init(_:text:prompt:axis:). Is there any that can be used to set both of them? If not, is there any workaround? Because I happen to need both of them. Thank you.
1
0
122
2w
SwiftUI Canvas ring animation briefly rotates backward after app returns from background
Hi, I have a SwiftUI "work time" screen with a rotating ring (60 tick marks, Canvas-based). While the app stays in foreground, rotation is fine. After the app is in background for a while and comes back to foreground, I consistently see one visual glitch: the ring makes one very short step in the opposite direction once then continues rotating clockwise normally So this is not a crash, only a visual reverse tick on resume. What I expect: no direction change after foreground resume continuous clockwise motion What I already tried: withAnimation(.linear(...).repeatForever(...)) + restart on scenePhase TimelineView (.animation and .periodic) with time-based angle angle with and without modulo wrapping wall-clock and monotonic time sources rotation via rotationEffect and also via Canvas geometry warmup delays after resume restoring original ring visuals (long/short tick marks) The effect is still reproducible. Question: What is the correct SwiftUI approach to implement a continuously rotating ring that stays direction-stable across background/foreground transitions, with no one-frame reverse step on resume? Any pattern that is robust on current iOS versions and avoids visual artifacts on scene phase changes would be appreciated. Minimal repro: import SwiftUI struct ReproClockView: View { @Environment(\.scenePhase) private var scenePhase private let tickCount = 60 private let rotationDuration: Double = 120 @State private var rotationDegrees: Double = 0 @State private var hasAppeared = false var body: some View { ZStack { Canvas { context, size in let center = CGPoint(x: size.width / 2, y: size.height / 2) let radius = min(size.width, size.height) / 2 - 8 for index in 0..<tickCount { let angle = Double(index) * (360.0 / Double(tickCount)) - 90 let radians = angle * .pi / 180 let isLongTick = index % 5 == 0 let length: CGFloat = isLongTick ? 22 : 14 let outerRadius = radius let innerRadius = radius - length let startPoint = CGPoint( x: center.x + cos(radians) * outerRadius, y: center.y + sin(radians) * outerRadius ) let endPoint = CGPoint( x: center.x + cos(radians) * innerRadius, y: center.y + sin(radians) * innerRadius ) var path = Path() path.move(to: startPoint) path.addLine(to: endPoint) context.stroke( path, with: .color(.red), style: StrokeStyle(lineWidth: 2.5, lineCap: .round) ) } } .rotationEffect(.degrees(rotationDegrees)) .drawingGroup() } .frame(width: 340, height: 340) .onAppear { guard !hasAppeared else { return } hasAppeared = true startRotation() } .onChange(of: scenePhase) { oldPhase, newPhase in if oldPhase == .background && newPhase == .active { withAnimation(.linear(duration: 0)) { rotationDegrees = 0 } DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { startRotation() } } } } private func startRotation() { rotationDegrees = 0 withAnimation(.linear(duration: rotationDuration).repeatForever(autoreverses: false)) { rotationDegrees = 360 } } }
0
0
181
2w
Update build number automatically
In SwiftUI 6 when developing for MacOS in Xcode 26, there does not seem to be a way to provide an automatic increment of the current build number, i.e. "Current Project Version" in settings. Does anyone have a solution that works in the latest version of Xcode. i.e. 26? All the solutions that I have tried are based on older versions that involve running scripts to update the build file, (.xcconfig) or the .info.plist file which simply will not work in the current configuration.
0
0
421
2w
NavigationSplitView no longer pops back to the root view when selection = nil in iOS 26.4 (with a nested TabView)
In iOS 26.4 (iPhone, not iPad), when a NavigationSplitView is combined with a nested TabView, it no longer pops back to the root sidebar view when the List selection is set to nil. This has been working fine for at least a few years, but has just stopped working in iOS 26.4. Here's a minimal working example: import SwiftUI struct ContentView: View { @State var articles: [Article] = [Article(articleTitle: "Dog"), Article(articleTitle: "Cat"), Article(articleTitle: "Mouse")] @State private var selectedArticle: Article? = nil var body: some View { NavigationSplitView { TabView { Tab { List(articles, selection: $selectedArticle) { article in Button { selectedArticle = article } label: { Text(article.title) } } } label: { Label("Explore", systemImage: "binoculars") } } } detail: { Group { if let selectedArticle { Text(selectedArticle.title) } else { Text("No selected article") } } .navigationBarBackButtonHidden(true) .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Close", systemImage: "xmark") { selectedArticle = nil } } } } } } struct Article: Identifiable, Hashable { let id: String let title: String init(articleTitle: String) { self.id = articleTitle self.title = articleTitle } } First, I'm aware that nesting a TabView inside a NavigationSplitView is frowned upon: Apple seems to prefer NavigationSplitView nested inside a Tab. However, for my app, that leads to a very confusing user experience. Users quickly get lost because they end up with different articles open in different tabs and it doesn't align well with my core distinction between two "modes": article selection mode and article reading mode. When the user is in article selection mode (sidebar view), they can pick between different ways of selecting an article (Explore, Bookmarks, History, Search), which are implemented as "tabs". When they pick an article from any tab they jump into article reading mode (the detail view). Second, I'm using .navigationBarBackButtonHidden(true) to remove the auto back button that pops back to the sidebar view. This button does still work in iOS 26.4, even with the nested TabView. However, I can't use the auto back button because my detail view is actually a WebView with its own back/forward logic and UI. Therefore, I need a separate close button to exit from the detail view. My close button sets selectedArticle to nil, which (pre-iOS 26.4) would trigger the NavigationSplitView to pop back to the sidebar view. For some reason, in iOS 26.4 the NavigationSplitView doesn't seem to bind correctly to the List's selection parameter, specifically when there's a TabView nested between them. Or, rather, it binds, but fails to pop back when selection becomes nil. One option is to replace NavigationSplitView with NavigationStack (on iPhone). NavigationStack still works with a nested TabView, but it creates other downstream issues for me (as well as forcing me to branch for iPhone and iPad), so I'd prefer to continue using NavigationSplitView. Does anyone have any ideas about how to work around this problem? Is there some way of explicitly telling NavigationSplitView to pop back to the sidebar view on iPhone? (I've tried setting the column visibility but nothing seems to work). Thanks for any help!
Replies
1
Boosts
1
Views
149
Activity
18h
Is it possible to focus a non-textField on iPadOS in SwiftUI?
I would like to implement a focus-based Menu-Bar command in my SwiftUI iPadOS app, or react to key command while certain elements are focused. Traditionally, this requires using @FocusedValue and focusable() and focused, however, it appears that setting a @FocusState on macOS will work, but setting a @FocusState on iPadOS will never work. How can this API work and support MenuBar commands and keyboard inputs? It kind of has an accessibility impact as well. Not all users are going to know, or want to turn on "full keyboard control" for basic interactions. Here's a small sample that doesn't appear to focus on iPadOS: struct FocusableTestView: View { @FocusState private var isRectFocused: Bool var body: some View { VStack { // This text field should focus the custom input when pressing return: TextField("Enter text", text: .constant("")) .textFieldStyle(.roundedBorder) .onSubmit { isRectFocused = true } .onKeyPress(.return) { isRectFocused = true return .handled } // This custom "input" should focus itself when tapped: Rectangle() .fill(isRectFocused ? Color.accentColor : Color.gray.opacity(0.3)) .frame(width: 100, height: 100) .overlay( Text(isRectFocused ? "Focused" : "Tap me") ) .focusable(true) .focused($isRectFocused) .onTapGesture { isRectFocused = true print("Focused rectangle") } // The focus should be able to be controlled externally: Button("Toggle Focus") { isRectFocused.toggle() } .buttonStyle(.bordered) } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) } }
Replies
0
Boosts
0
Views
134
Activity
3d
Focusable doesn't work on iPad with external keyboard
I have a custom input view in my app which is .focusable(). It behaves similar to a TextField, where it must be focused in order to be used. This works fine on all platforms including iPad, except when when an external keyboard is connected (magic keyboard), in which case it can't be focused anymore and becomes unusable. Is there a solution to this, or a workaround? My view is very complex, so simple solutions like replacing it with a native view isn't possible, and I must be able to pragmatically force it to focus. Here's a very basic example replicating my issue. Non of the functionality works when a keyboard is connected: struct FocusableTestView: View { @FocusState private var isRectFocused: Bool var body: some View { VStack { // This text field should focus the custom input when pressing return: TextField("Enter text", text: .constant("")) .textFieldStyle(.roundedBorder) .onSubmit { isRectFocused = true } .onKeyPress(.return) { isRectFocused = true return .handled } // This custom "input" should focus itself when tapped: Rectangle() .fill(isRectFocused ? Color.accentColor : Color.gray.opacity(0.3)) .frame(width: 100, height: 100) .overlay( Text(isRectFocused ? "Focused" : "Tap me") ) .focusable(true, interactions: .edit) .focused($isRectFocused) .onTapGesture { isRectFocused = true print("Focused rectangle") } // The focus should be able to be controlled externally: Button("Toggle Focus") { isRectFocused.toggle() } .buttonStyle(.bordered) } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) } }
Replies
2
Boosts
0
Views
277
Activity
3d
Is updateUIViewController always called immediately after makeUIViewController?
I'm in the unenviable position of needing the current UIViewController to keep an external library happy. Essentially, I need to do this in SwiftUI: import LibraryOutOfMyControl ViewControllerReader { viewController in Button("Action") { LibraryOutOfMyControl.action(with: viewController) } } My simple attempt below functions correctly but I'm relying on makeUIViewController always being immediately followed by updateUIViewController. Is the a reasonable assumption or should I set everything up assuming updateUIViewController might never be called? struct ViewControllerReader<Content>: UIViewControllerRepresentable where Content: View { @ViewBuilder var content: (UIViewController) -> Content func makeUIViewController(context: Context) -> UIHostingController<Content> { UIHostingController(rootView: content(UIViewController())) } func updateUIViewController(_ uiViewController: UIHostingController<Content>, context: Context) { uiViewController.rootView = content(uiViewController) uiViewController.view.isUserInteractionEnabled = context.environment.isEnabled } func sizeThatFits(_ proposal: ProposedViewSize, uiViewController: UIHostingController<Content>, context: Context) -> CGSize? { uiViewController.sizeThatFits(in: proposal.replacingUnspecifiedDimensions()) } }
Replies
0
Boosts
0
Views
95
Activity
4d
SwiftUI navigation bar button color changes depending on whether the root view is a ScrollView or VStack
I have a SwiftUI view inside a NavigationStack with a custom navigation bar background color. I want the navigation bar buttons to have a consistent color throughout the app. The issue is that the navigation bar button color changes depending on the first/root view in the body. When the root view is a ScrollView var body: some View { ScrollView { // content } .toolbarBackground(Color(red: 0.02, green: 0.27, blue: 0.13), for: .navigationBar) .toolbarBackground(.visible, for: .navigationBar) .toolbarColorScheme(.dark, for: .navigationBar) } The navigation bar buttons appear white. However, if I replace the ScrollView with a VStack, while keeping the same modifiers, the navigation bar buttons appear black: var body: some View { VStack { // content } .toolbarBackground(Color(red: 0.02, green: 0.27, blue: 0.13), for: .navigationBar) .toolbarBackground(.visible, for: .navigationBar) .toolbarColorScheme(.dark, for: .navigationBar) } The navigation bar buttons appear black. How can I make the navigation bar buttons stay the same colour in both cases?
Replies
1
Boosts
0
Views
176
Activity
4d
.disabled() doesn't VISUALLY disable buttons inside ToolbarItem on iOS 26 devices
[Also submitted as FB19313064] The .disabled() modifier doesn't visually disable buttons inside a ToolbarItem container on iOS 26.0 (23A5297i) devices. The button looks enabled, but tapping it doesn't trigger the action. When deployment target is lowered to iOS 18 and deployed to an iOS 18 device, it works correctly. It still fails on an iOS 26 device, even with an iOS 18-targeted build. This occurs in both the Simulator and on a physical device. Screen Recording Code struct ContentView: View { @State private var isButtonDisabled = false private var osTitle: String { let version = ProcessInfo.processInfo.operatingSystemVersion return "iOS \(version.majorVersion)" } var body: some View { NavigationStack { VStack { Button("Body Button") { print("Body button tapped") } .buttonStyle(.borderedProminent) .disabled(isButtonDisabled) Toggle("Disable buttons", isOn: $isButtonDisabled) Spacer() } .padding() .navigationTitle("Device: \(osTitle)") .navigationBarTitleDisplayMode(.large) .toolbar { ToolbarItem { Button("Toolbar") { print("Toolbar button tapped") } .buttonStyle(.borderedProminent) .disabled(isButtonDisabled) } } } } }
Replies
8
Boosts
3
Views
720
Activity
5d
SwiftData 'simple' migration failing
This is a long post, so let me start with a summary: I am attempting to implement what "ought to be" a simple SwiftData migration, and am receiving the following fatal error from the ModelContainer initializer: NSCocoaErrorDomain Code=134504 "Cannot use staged migration with an unknown model version." The crash occurs both in the Simulator and on a physical device. Both the original schema and the new schema load and run as expected if loaded from scratch — so I conclude the Models are OK; it is the migration from the original schema to the new schema which is the issue. I have reported this as FB22652791 and Technical Incident Case # 19893980. I have two model projects available — one contrived, the other using my actual SwiftData models. Now the Details I am developing a SwiftUI/SwiftData app. I am (currently) using Xcode 26.5-beta-3. I set up an alpha-test build using the following approach: public class DatabaseSchema { public let dbSchema: Schema = Schema([ Model1.self, ... , Model16.self ], version: Schema.Version(0, 9, 0)) public var modelContainer: ModelContainer { let container: ModelContainer let modelConfiguration = ModelConfiguration(schema: dbSchema, isStoredInMemoryOnly: false) do { container = try ModelContainer(for: dbSchema, migrationPlan: nil, configurations: [modelConfiguration]) } catch { fatalError("Failed to creae model conainer") } return container } This defines database version 0.9. For version 1.0, I made three changes to the database: added an attribute of type String to Model2. added three attributes of type [Struct], where Struct conforms to Codable, Equatable and Hashable to Model3, and added a new model (which I'll call Model17) I define two schemas: public enum Schema090: VersionedSchema { public static var versionIdentifier = Schema.Version(0, 9, 0) public static var models: [any PersistentModel.Type] = [ Model1.self, Schema090.Model2.self, Schema090.Model3.self, ... ] } and public enum Schema100: VersionedSchema { public static var versionIdentifier = Schema.Version(1, 0, 0) public static var models: [any PersistentModel.Type] = [ Model1.swift, Schema100.Model2.self, Schema100.Model3.self, ..., Model16.self, Schema100.Model17.self ] } For models that changed, I use the following approach: public typealias Model3 = Schema100.Model3 extension Schema090 { @Model final class Model3 { ... } public init() { ... } } extension Schema100 { @Model final class Model3 { ... <added attributes, initialized> } public init() { ... } } The DatabaseSchema class was modified as follows: public class DatabaseSchema { public let dbSchema: Schema = Schema([ Model1.self, Schema100.Model2.self, Schema100.Model3.self, ... , Model16.self, Schema100.Model17.self ], version: Schema.Version(1, 0, 0)) public var modelContainer: ModelContainer { let container: ModelContainer let modelConfiguration = ModelConfiguration(schema: dbSchema, isStoredInMemoryOnly: false) do { container = try ModelContainer(for: dbSchema, migrationPlan: MigrationPlan.self, configurations: [modelConfiguration]) } catch { fatalError("Failed to creae model conainer") } return container } where the migration plan is the trivial custom migration that makes sure that all added attributes of existing records are properly initialized. enum MigrationPlan: SchemaMigrationPlan { static var schemas: [any VersionedSchema.Type] = [ Schema090.self, Schema100.self ] static var stages: [MigrationStage] = [version090ToVersion100] static let version090ToVersion100 = MigrationStage(fromVersion: Schema090.self, toVersion: Schema100.self, willMigrate: { _ in }, didMigrate: { context in let models = try context.fetch( FetchDescriptor<Schema100.Model3>()) for model in models { < initial the added attributes > { try context.save() }) } This is all simple stuff. Nothing particularly fancy here. But running this code always crashes in the ModelContainer initializer. In my two sample projects, I get two different error messages — in the contrived example, the error message is Code=134110 "An error occurred during persistent store migration." reason=Cannot migrate store in-place: Validation error missing attribute values on mandatory destination attribute, ... and in the sample project that uses my actual data model, I get NSCocoaErrorDomain Code=134504 "Cannot use staged migration with an unknown model version." My Thoughts Since obviously most folks are doing SwiftData migrations without the problems I am experiencing, the obvious possibilities are I'm doing something stupid that I just don't see. There is a problem because the original schema was given a version value of Schema.Version(0, 9, 0). (i.e., major version number was 0) There is a problem because I am adding an attribute of type [Struct] where Struct is Codable, Hashable, and Equatable. I.e., migration isn't working properly with attributes which are stored as their codable representations. Or maybe something else? In any case, any help you can offer would be greatly appreciated.
Replies
5
Boosts
0
Views
494
Activity
5d
SwiftUI Button with Image view label has smaller hit target
[Also submitted as FB20213961] SwiftUI Button with a label: closure containing only an Image view has a smaller tap target than buttons created with a Label or the convenience initializer. The hit area shrinks to the image bounds instead of preserving the standard minimum tappable size. SCREEN RECORDING On a physical device, the difference is obvious—it’s easy to miss the button. Sometimes it even shows the button-tapped bounce animation but doesn’t trigger the action. SYSTEM INFO Xcode Version 26.0 (17A321) macOS 15.6.1 (24G90) iOS 26.0 (23A340) SAMPLE CODE The following snippet shows the difference in hit targets between the convenience initializer, a Label, and an Image (the latter two in a label: closure). // ✅ Hit target is entire button Button("Button 1", systemImage: "1.square.fill") { print("Button 1 tapped") } // ✅ Hit target is entire button Button { print("Button 2 tapped") } label: { Label("Button 2", systemImage: "2.square.fill") } // ❌ Hit target is smaller than button Button { print("Button 3 tapped") } label: { Image(systemName: "3.square.fill") }
Replies
6
Boosts
4
Views
465
Activity
5d
Changing systemImage value for Image, logs "fopen failed for data file".
I'm getting a log error and a slight delay in the UI when displaying a system image that changes at the end of a sequence. I'm using a ternary operator to determine the image; the fact that the image changes seem to be the issue, rather than the value itself. The issue only occurs for a newly installed app, and not when the app is rerun. (I'm using similar code to display an onboarding sequence after installation.) This happens on device (iphone 15 pro v25.6) and simulator (iphone 17 pro v25.6 and iphone 16 pro v18.5); xcode 26.5 (17F42). Console errors (device and iphone 17 simulator): fopen failed for data file: errno = 2 (No such file or directory) fopen failed for data file: errno = 2 (No such file or directory) Repro Code: import SwiftUI struct ContentView: View { // NOTE: error only occurs with new install. @State private var currentItem = 0 @State private var totalItems: Int = 4 var body: some View { VStack(spacing: 0) { Spacer() Text("totalItems: \(totalItems)") TabView(selection: $currentItem) { ForEach(0...totalItems, id: \.self) { item in Text("\(item) ~ \(currentItem)") .tag(item) } } //TV .tabViewStyle(.page(indexDisplayMode: .never)) .frame(height: 200) Button { if currentItem < totalItems { currentItem += 1 currentItem = min(totalItems, currentItem) } } label: { let imgString: String = (currentItem == totalItems ? "arrowshape.turn.up.right" : "arrowshape.right") // error // let imgString: String = ((currentItem == totalItems) ? "x.circle" : "smallcircle.filled.circle") // error // let imgString: String = "smallcircle.filled.circle" // no error // let imgString: String = "x.circle" // no error Text("\(imgString)") // if only print text, no error, so issue seems to be with Image. Image(systemName: imgString) } Spacer() } } } Click through the button sequence to see issue at end of sequence. Uncomment the various imgString lines to see indicated differences in behavior. Need to delete app each time to repro issue. Running in simulator on iphone 16 Pro iOS 18.5 has slightly different error messages: fopen failed for data file: errno = 2 (No such file or directory) Errors found! Invalidating cache... fopen failed for data file: errno = 2 (No such file or directory) Errors found! Invalidating cache...
Replies
1
Boosts
0
Views
56
Activity
5d
iOS 26 rendering gap on scroll surfaces — lower scroll view does not render
On iOS 26 (26.0–26.5), a rectangular region in the lower half of the screen sometimes does not render while the content underneath remains laid out and interactive — scrolling works, hit testing succeeds, and rows visibly emerge from behind the floating tab bar as you scroll. This is a render-server / compositor gap, not a layout or safe-area issue. We see it on both UIKit and SwiftUI scroll surfaces inside the same UITabBarController: UIKit: UICollectionView with UICollectionViewFlowLayout (sectionInsetReference = .fromSafeArea) SwiftUI: List(.plain) nested in TabView(.page) inside a UIHostingController Confirmed on iPhone 16 Pro, iPhone 17 Pro, iPhone 13 Pro Max. Community threads (linked below) report the same symptom in Messages, Notes, Safari, Mail, and the App Store. Questions for Apple Is this acknowledged as an OS-level regression, and is a fix targeted for an upcoming iOS 26.x release? Is there a deterministic repro? We've tried background/foreground cycles, push notifications mid-scroll, tab switches during inertia, lock/unlock, orientation flips, simulated memory warnings, layout-invalidation storms, and trait-collection cycles — none reliably trigger it on our test devices. Is there a developer-side mitigation (e.g. avoiding specific UIVisualEffectView / Glass configurations, opting out of a rendering optimization) until a system fix lands? Is there a runtime signal on CALayer or UIScrollView we can inspect to detect this gap state and force a recovery (tile redraw, backing-store discard, etc.)? Notes We cannot reproduce locally. Affected users hit it organically; once it appears it persists across re-layout until the view controller is torn down. Community reports consistently mention Reduce Transparency being enabled on affected devices, and toggling it off clears the issue for many. In our own testing, RT alone is not sufficient to trigger the bug — it appears to be a contributing condition rather than the trigger. References: Apple Discussions: https://discussions.apple.com/thread/256182149 Reddit r/ios (multiple system apps): https://www.reddit.com/r/ios/comments/1nlzn7f/some_apps_cutting_off_half_the_display/ https://www.idownloadblog.com/2026/03/23/webpage-content-cutting-off-safari/
Replies
2
Boosts
2
Views
253
Activity
1w
Application Hangs with Nested LazyVStack When Accessibility Inspector is Active
Description I've encountered a consistent hang/freeze issue in SwiftUI applications when using nested LazyVStack containers with Accessibility Inspector (simulator) or VoiceOver (physical device) enabled. The application becomes completely unresponsive and must be force-quit. Importantly, this hang occurs in a minimal SwiftUI project with no third-party dependencies, suggesting this is a framework-level issue with the interaction between SwiftUI's lazy view lifecycle and the accessibility system. Reproduction Steps I've created a minimal reproduction project available here: https://github.com/pendo-io/SwiftUI_Hang_Reproduction To Reproduce: Create a SwiftUI view with the following nested LazyVStack structure: struct NestedLazyVStackView: View { @State private var outerSections: [Int] = [] @State private var innerRows: [Int: [Int]] = [:] var body: some View { ScrollView { LazyVStack(alignment: .leading, spacing: 24) { ForEach(outerSections, id: \.self) { section in VStack(alignment: .leading, spacing: 8) { Text("Section #\(section)") // Nested LazyVStack LazyVStack(alignment: .leading, spacing: 2) { ForEach(innerRows[section] ?? [], id: \.self) { row in Text("Section #\(section) - Row #\(row)") .onAppear { // Load more data when row appears loadMoreInner(section: section) } } } } .onAppear { // Load more sections when section appears loadMoreOuter() } } } } } } Enable Accessibility Inspector in iOS Simulator: Xcode → Open Developer Tool → Accessibility Inspector Select your running simulator Enable Inspection mode (eye icon) Navigate to the view and start scrolling Result: The application hangs and becomes unresponsive within a few seconds of scrolling Expected Behavior The application should remain responsive when Accessibility Inspector or VoiceOver is enabled, allowing users to scroll through nested lazy containers without freezing. Actual Behavior The application freezes/hangs completely CPU usage may spike The app must be force-quit to recover The hang occurs consistently and is reproducible Workaround 1: Replace inner LazyVStack with VStack LazyVStack { ForEach(...) { section in VStack { // ← Changed from LazyVStack ForEach(...) { row in ... } } } } Workaround 2: Embed in TabView TabView { NavigationStack { NestedLazyVStackView() // ← Same nested structure, but no hang } .tabItem { ... } } Interestingly, wrapping the entire navigation stack in a TabView prevents the hang entirely, even with the nested LazyVStack structure intact. Questions for Apple Is there a known issue with nested LazyVStack containers and accessibility traversal? Why does wrapping the view in a TabView prevent the hang? Are there recommended patterns for using nested lazy containers with accessibility support? Is this a timing issue, a deadlock, or an infinite loop in the accessibility system? Why that happens? Reproduction Project A complete, minimal reproduction project is available at: https://github.com/pendo-io/SwiftUI_Hang_Reproduction
Replies
5
Boosts
0
Views
482
Activity
1w
Need behaviour of iOS 26 tab bar view and sheet view similar to Preview app.
Hi all, I was trying to have a UI similar to Preview app which we have in iPhone. We have a tab bar view and behind it, we have a sheet view. I was trying to achieve that, but the .sheet modifier covers the bottom tab bar view.
Replies
1
Boosts
0
Views
60
Activity
1w
Tab button's ax identifier is missing when using `.sidebarAdaptable` TabViewStyle
Hello, I found that if you apply the new .sidebarAdaptable tab view style, the accessibility identifiers of tab bar buttons are missing. import SwiftUI struct ContentView: View { var body: some View { TabView { Tab("Received", systemImage: "tray.and.arrow.down.fill") { Text("Received") } .accessibilityIdentifier("tab.received") // 👀 Tab("Sent", systemImage: "tray.and.arrow.up.fill") { Text("Sent") } .accessibilityIdentifier("tab.sent") // 👀 Tab("Account", systemImage: "person.crop.circle.fill") { Text("Account") } .accessibilityIdentifier("tab.account") // 👀 } .tabViewStyle(.sidebarAdaptable) // 👈 if remove this, ax identifiers are ok } } #Preview { ContentView() } The identifiers automatically appear after a few seconds. But this behaviour breaks a lot of the UI test cases.
Replies
3
Boosts
0
Views
651
Activity
1w
Popover in Toolbar Causes Crash in Catalyst App on macOS 26
Hi everyone, I’ve encountered an issue where using a popover inside the toolbar of a Catalyst app causes a crash on macOS 26 beta 5 with Xcode 26 beta 5. Here’s a simplified code snippet: import SwiftUI struct ContentView: View { @State private var isPresentingPopover = false var body: some View { NavigationStack { VStack { } .padding() .toolbar { ToolbarItem { Button(action: { isPresentingPopover.toggle() }) { Image(systemName: "bubble") } .popover(isPresented: $isPresentingPopover) { Text("Hello") .font(.largeTitle) .padding() } } } } } } Steps to reproduce: Create a new iOS app using Xcode 26 beta 5. Enable Mac Catalyst (Match iPad). Add the above code to show a Popover from a toolbar button. Run the app on macOS 26, then click the toolbar button. The app crashes immediately upon clicking the toolbar button. Has anyone else run into this? Any workarounds or suggestions would be appreciated! Thanks!
Replies
6
Boosts
2
Views
611
Activity
1w
Glass effect interactive effect issue when used with concentric shapes
Using .glassEffect(.clear.interactive(), in: shape), where shape is some concentric shape that adapts to corner radius of the device, results in appearing of highlighted capsule shape. Code to reproduce this behavior import SwiftUI struct HelloLiquidGlass: View { var body: some View { if #available(iOS 26.0, *) { Text("Hello, World!") .frame(maxWidth: .infinity, maxHeight: .infinity) // .glassEffect(.clear.interactive(), in: .rect(corners: .concentric)) // .glassEffect(.clear.interactive(), in: ConcentricRectangle(uniformTopCorners: .fixed(80))) .padding(36) .ignoresSafeArea() .preferredColorScheme(.dark) } } } #Preview { HelloLiquidGlass() } Either of both commented-out modifiers produces the same result when user interacts with Liquid Glass pane (revealing of capsule shape that is not relative to actual shape of liquid glass effect modifier) iOS 26.5 (23F73) SDK + iOS 26.5 (23F77) Simulator
Replies
3
Boosts
0
Views
300
Activity
1w
SwiftUI template in Instruments 26.4.1 shows empty channels on iOS 26.4.2 device — even with a minimal TimelineView repro
Hi all, I've hit a reproducible issue where the presence of the SwiftUI instrument in a template prevents any data from being recorded, including from the other instruments in the same template. Removing the SwiftUI instrument immediately restores normal recording. Environment Host: macOS 26.4.1 (25E253), Mac mini Xcode / Instruments 26.4.1 (17E202) Device: iPhone 17, iOS 26.4.2 (23E261) (physical device, USB-attached) Symptom Recording the same app, same device, same session, only varying the template contents: SwiftUI template (as-is) => All lanes empty across the entire recording Same template with the SwiftUI instrument removed => Data collected normally (Time Profiler samples, Hangs, etc.) So it seems not an issue with the SwiftUI lanes specifically being empty — including the SwiftUI instrument appears to silence the entire recording. Steps to reproduce Open Instruments → pick the SwiftUI template (or build a custom template that includes the SwiftUI instrument alongside, e.g., Time Profiler). Target the device, attach to the running app. Record for ~10s, interact with the app. Stop. Result: every lane is empty. Edit the template, remove the SwiftUI instrument, re-record with no other changes. Result: normal data appears in the remaining instruments. Questions Is this a known regression in Instruments 26.4.1 on iOS 26.4.x? Is there a workaround to use the SwiftUI instrument on this OS combo (different Xcode build, runtime flag, entitlement)? Does it work for anyone on iOS 26.4.x + Xcode 26.4.1, or is everyone seeing this? I can file a Feedback if confirmed as a bug — wanted to check here first in case I'm missing a setup step. Thanks!
Replies
2
Boosts
1
Views
145
Activity
2w
Textfield with both a formatter and axis
Hi, is there any textfield init with both formatter and axis for multiline? I notice the there are both an init to include a formatter like so: init(_:value:formatter:prompt:) and another one to include an axis for multiline like so: init(_:text:prompt:axis:). Is there any that can be used to set both of them? If not, is there any workaround? Because I happen to need both of them. Thank you.
Replies
1
Boosts
0
Views
122
Activity
2w
How to disable multiple windows feature of my App on iPadOS?
My app is a SwiftUI lifecycle app. I want to disable its multiple windows feature on iPadOS . I have tried to set the Enable Multiple Scenes option to false in Application Scene Manifest, but it doesn't work.
Replies
0
Boosts
0
Views
158
Activity
2w
SwiftUI Canvas ring animation briefly rotates backward after app returns from background
Hi, I have a SwiftUI "work time" screen with a rotating ring (60 tick marks, Canvas-based). While the app stays in foreground, rotation is fine. After the app is in background for a while and comes back to foreground, I consistently see one visual glitch: the ring makes one very short step in the opposite direction once then continues rotating clockwise normally So this is not a crash, only a visual reverse tick on resume. What I expect: no direction change after foreground resume continuous clockwise motion What I already tried: withAnimation(.linear(...).repeatForever(...)) + restart on scenePhase TimelineView (.animation and .periodic) with time-based angle angle with and without modulo wrapping wall-clock and monotonic time sources rotation via rotationEffect and also via Canvas geometry warmup delays after resume restoring original ring visuals (long/short tick marks) The effect is still reproducible. Question: What is the correct SwiftUI approach to implement a continuously rotating ring that stays direction-stable across background/foreground transitions, with no one-frame reverse step on resume? Any pattern that is robust on current iOS versions and avoids visual artifacts on scene phase changes would be appreciated. Minimal repro: import SwiftUI struct ReproClockView: View { @Environment(\.scenePhase) private var scenePhase private let tickCount = 60 private let rotationDuration: Double = 120 @State private var rotationDegrees: Double = 0 @State private var hasAppeared = false var body: some View { ZStack { Canvas { context, size in let center = CGPoint(x: size.width / 2, y: size.height / 2) let radius = min(size.width, size.height) / 2 - 8 for index in 0..<tickCount { let angle = Double(index) * (360.0 / Double(tickCount)) - 90 let radians = angle * .pi / 180 let isLongTick = index % 5 == 0 let length: CGFloat = isLongTick ? 22 : 14 let outerRadius = radius let innerRadius = radius - length let startPoint = CGPoint( x: center.x + cos(radians) * outerRadius, y: center.y + sin(radians) * outerRadius ) let endPoint = CGPoint( x: center.x + cos(radians) * innerRadius, y: center.y + sin(radians) * innerRadius ) var path = Path() path.move(to: startPoint) path.addLine(to: endPoint) context.stroke( path, with: .color(.red), style: StrokeStyle(lineWidth: 2.5, lineCap: .round) ) } } .rotationEffect(.degrees(rotationDegrees)) .drawingGroup() } .frame(width: 340, height: 340) .onAppear { guard !hasAppeared else { return } hasAppeared = true startRotation() } .onChange(of: scenePhase) { oldPhase, newPhase in if oldPhase == .background && newPhase == .active { withAnimation(.linear(duration: 0)) { rotationDegrees = 0 } DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { startRotation() } } } } private func startRotation() { rotationDegrees = 0 withAnimation(.linear(duration: rotationDuration).repeatForever(autoreverses: false)) { rotationDegrees = 360 } } }
Replies
0
Boosts
0
Views
181
Activity
2w
Update build number automatically
In SwiftUI 6 when developing for MacOS in Xcode 26, there does not seem to be a way to provide an automatic increment of the current build number, i.e. "Current Project Version" in settings. Does anyone have a solution that works in the latest version of Xcode. i.e. 26? All the solutions that I have tried are based on older versions that involve running scripts to update the build file, (.xcconfig) or the .info.plist file which simply will not work in the current configuration.
Replies
0
Boosts
0
Views
421
Activity
2w