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

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
60
8h
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
258
9h
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
85
1d
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
166
1d
.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
705
2d
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
476
2d
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
454
2d
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
43
2d
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
229
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
473
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
641
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
597
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
291
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
126
1w
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
107
1w
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
175
1w
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
392
1w
Programatically adding to a TextField and moving the TextSelection point in SwiftUI
Hi! I am trying to create a simple SwiftUI TextField, with an external button to add text to the field at the current insertion point (the cursor in the TextField). When I add the text, the cursor (I-Beam) remains at the original insertion point, so I want it to move over to the end of what I added. The trouble is, it sometimes moves further forward or to the end (visibly) but works as if it is still at the point I moved it to. This seems to possibly be due to emojis in the TextField (because, I assume, they are composed of more bytes). Further, sometimes the addition of the text can cause an emoji to appear unexpectedly, I assume because it is combining the bytes in an odd way. So moving the cursor seems to sometimes introduce weird behaviour. This comes from a much larger project, but I have distilled this down to the smallest example project I could. And I have a video to show how it behaves. Here's the main part of the code, and I'll attach an Xcode project: import SwiftUI struct ContentView: View { @State private var text: String = "abcdef🧁🧁🧁🧁ghijkl" @State private var selectedText: TextSelection? var body: some View { VStack { TextField("", text: $text, selection: $selectedText) .font(.title) Button("Add Z at Insertion Point in TextField") { // Get indices of any selection in the text field let from: String.Index, to: String.Index if let selectedText = selectedText { let indices = selectedText.indices switch indices { case .selection(let range): from = range.lowerBound to = range.upperBound case .multiSelection(let rangeSet): from = rangeSet.ranges.first!.lowerBound to = rangeSet.ranges.first!.upperBound default: from = self.text.endIndex to = self.text.endIndex } } else { from = self.text.endIndex to = self.text.endIndex } guard from <= to && from <= self.text.endIndex else { return } // Insert and update the cursor position self.text.replaceSubrange(from..<to, with: "Z") // Move cursor after the inserted character let newIndex = self.text.index(after: from) selectedText = TextSelection(insertionPoint: newIndex) } } .padding() } } STEPS TO REPRODUCE Run the app. Also view the video as it shows the steps. Put insertion point between c and d. Press the "Add Z" button. Note that Z is placed between c and d. This is great. Put insertion point between h and i. Press the "Add Z" button. Note that Z is placed between h and i. BUT, the insertion point I-beam moves to the end of the string. Press the "Add Z" button again. Z is added where you would have expected based on where the TextSelection insertion point was put, but the flashing I-Beam is still at the end. Press the "Add Z" button again. Same issue. insertion point is being shown at end, but to the button it is between Z and i. OF NOTE, if you use the keyboard and press delete, it deletes from end (where the I-beam is). Now put insertion point between the 4 cupcakes. Press "Add Z" two times. It behaves correctly. Press "Add Z" a third time. It adds a fairy emoji. So, any idea what I am doing wrong? I thought it might be an issue requiring me to update in a background thread, but I tried that, even delaying the update in the thread, but the issue remains. Thanks in advance. Here's a video: https://curmi.name/temp/SimpleTextField%20showing%20issues.mp4 And if it helps, here is the Xcode project: https://curmi.name/temp/SimpleTextfield.zip
2
0
450
2w
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
60
Activity
8h
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
258
Activity
9h
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
85
Activity
1d
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
166
Activity
1d
.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
705
Activity
2d
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
476
Activity
2d
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
454
Activity
2d
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
43
Activity
2d
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
229
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
473
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
55
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
641
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
597
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
291
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
126
Activity
1w
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
107
Activity
1w
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
149
Activity
1w
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
175
Activity
1w
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
392
Activity
1w
Programatically adding to a TextField and moving the TextSelection point in SwiftUI
Hi! I am trying to create a simple SwiftUI TextField, with an external button to add text to the field at the current insertion point (the cursor in the TextField). When I add the text, the cursor (I-Beam) remains at the original insertion point, so I want it to move over to the end of what I added. The trouble is, it sometimes moves further forward or to the end (visibly) but works as if it is still at the point I moved it to. This seems to possibly be due to emojis in the TextField (because, I assume, they are composed of more bytes). Further, sometimes the addition of the text can cause an emoji to appear unexpectedly, I assume because it is combining the bytes in an odd way. So moving the cursor seems to sometimes introduce weird behaviour. This comes from a much larger project, but I have distilled this down to the smallest example project I could. And I have a video to show how it behaves. Here's the main part of the code, and I'll attach an Xcode project: import SwiftUI struct ContentView: View { @State private var text: String = "abcdef🧁🧁🧁🧁ghijkl" @State private var selectedText: TextSelection? var body: some View { VStack { TextField("", text: $text, selection: $selectedText) .font(.title) Button("Add Z at Insertion Point in TextField") { // Get indices of any selection in the text field let from: String.Index, to: String.Index if let selectedText = selectedText { let indices = selectedText.indices switch indices { case .selection(let range): from = range.lowerBound to = range.upperBound case .multiSelection(let rangeSet): from = rangeSet.ranges.first!.lowerBound to = rangeSet.ranges.first!.upperBound default: from = self.text.endIndex to = self.text.endIndex } } else { from = self.text.endIndex to = self.text.endIndex } guard from <= to && from <= self.text.endIndex else { return } // Insert and update the cursor position self.text.replaceSubrange(from..<to, with: "Z") // Move cursor after the inserted character let newIndex = self.text.index(after: from) selectedText = TextSelection(insertionPoint: newIndex) } } .padding() } } STEPS TO REPRODUCE Run the app. Also view the video as it shows the steps. Put insertion point between c and d. Press the "Add Z" button. Note that Z is placed between c and d. This is great. Put insertion point between h and i. Press the "Add Z" button. Note that Z is placed between h and i. BUT, the insertion point I-beam moves to the end of the string. Press the "Add Z" button again. Z is added where you would have expected based on where the TextSelection insertion point was put, but the flashing I-Beam is still at the end. Press the "Add Z" button again. Same issue. insertion point is being shown at end, but to the button it is between Z and i. OF NOTE, if you use the keyboard and press delete, it deletes from end (where the I-beam is). Now put insertion point between the 4 cupcakes. Press "Add Z" two times. It behaves correctly. Press "Add Z" a third time. It adds a fairy emoji. So, any idea what I am doing wrong? I thought it might be an issue requiring me to update in a background thread, but I tried that, even delaying the update in the thread, but the issue remains. Thanks in advance. Here's a video: https://curmi.name/temp/SimpleTextField%20showing%20issues.mp4 And if it helps, here is the Xcode project: https://curmi.name/temp/SimpleTextfield.zip
Replies
2
Boosts
0
Views
450
Activity
2w