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

SwiftUI Documentation

Posts under SwiftUI subtopic

Post

Replies

Boosts

Views

Activity

ProgressView(timerInterval:countsDown:) bar never reaches zero
Consider the following code on iOS: struct ContentView: View { @State private var timerInterval = Date(timeIntervalSince1970: 0) ... Date(timeIntervalSince1970: 0) var body: some View { VStack { ProgressView( timerInterval: timerInterval, countsDown: true ) Button { let now = Date() let then = now.addingTimeInterval(5) timerInterval = now ... then } label: { Text("Start") } } .padding() } } When I tap on the Start button, the progress view starts animating as expected, and its label is displaying the remaining time. However, at the very end, when the countdown reaches zero, the blue bar of the progress view doesn't reach zero and still has some progress left forever. Is this the expected behavior or a bug? Is there a way to make the bar reach zero without implementing my own custom view? Thanks in advance!
Topic: UI Frameworks SubTopic: SwiftUI
0
0
27
Feb ’26
Driving NavigationSplitView with something other than List?
Is it possible to drive NavigationSplitView navigation with a view in sidebar (left column) that is not a List? All examples that I have seen from this year only contain List in sidebar. I ask this because I would like to have a more complex layout in sidebar (or first view on iOS) that contains a mix of elements, some of them non-interactive and not targeting navigation. Here’s what I would like to do: import SwiftUI struct Thing: Identifiable, Hashable {     let id: UUID     let name: String } struct ContentView: View {     let things: [Thing]     @State private var selectedThingId: UUID?          var body: some View {         NavigationSplitView {             ScrollView(.vertical) {                 VStack {                     ForEach(things) { thing in                         Button("Thing: \(thing.name) \( selectedThingId == thing.id ? "selected" : "" )") {                             selectedThingId = thing.id                         }                     } SomeOtherViewHere() Button("Navigate to something else") { selectedThingId = someSpecificId }                 }             }         } detail: {             // ZStack is workaround for known SDK bug             ZStack {                 if let selectedThingId {                     Text("There is a thing ID: \(selectedThingId)")                 } else {                     Text("There is no thing.")                 }             }         }     } } This actually works as expected on iPadOS and macOS, but not iOS (iPhone). Tapping changes the selection as I see in the button label, but does not push anything to navigation stack, I remain stuck at home screen. Also filed as FB10332749.
14
5
7.2k
Feb ’26
SwiftUI .toolbar(placement: .keyboard) item not exposed to accessibility on iOS 26.1 (affects VoiceOver + XCUITest)
Description On iOS 26.1, a ToolbarItem placed in .keyboard is no longer exposed to the accessibility hierarchy. As a result: VoiceOver cannot focus or activate the toolbar button XCUITest cannot discover the element, making the UI impossible to test TextEditor() .toolbar { ToolbarItem(placement: .keyboard) { Button("Done") { /* action */ } } } This worked correctly on previous iOS versions. The button appears visually but is missing from both VoiceOver navigation and XCUI accessibility queries. Steps to Reproduce Create a new SwiftUI project. Use a simple text field with a keyboard toolbar button. Run on an iOS 26.1 device or simulator. Focus the text field to show the keyboard. Turn on VoiceOver and attempt to navigate to the toolbar button. Run an XCUITest attempting to locate the button
2
1
202
Feb ’26
SwiftUI view state resetting after alert is shown
Seeing an issue in iOS 26.2 iPhone 17 simulator (haven't been able to reproduce on device or other simulators), where a view's state is reset after an alert is shown. In this example the first LibraryView has the issue when alert is shown, the second LibraryView maintains state as expected. struct ContentView: View { var body: some View { NavigationStack { List { VStack { LibraryView(title: "Show view (Loss of state)") } LibraryView(title: "Show view (Works as expected)") } } } } /// This view is from a package dependency and wants to control the presentation of the sheet internally public struct LibraryView: View { @State private var isPresented: Bool = false let title: String public init(title: String) { self.title = title } public var body: some View { Button(self.title) { self.isPresented = true } .sheet(isPresented: self.$isPresented) { ViewWithAlert() } } } private struct ViewWithAlert: View { @State private var isPresented: Bool = false @State private var presentedCount = 0 var body: some View { Button("Show Alert, count: \(presentedCount)") { isPresented = true presentedCount += 1 } .alert("Hello", isPresented: self.$isPresented) { Button("OK") { } } } } Any ideas? The issue can be corrected by moving the .sheet to a higher level within the layout (i.e. on the NavigationStack). However, the library wants to control that presentation and not require the integration to present the sheet.
Topic: UI Frameworks SubTopic: SwiftUI
11
1
435
Feb ’26
iPadOS 26 – SwiftUI Menu in ToolbarItem shifts during pointer hover when view is presented as sheet
I am observing inconsistent pointer hover behavior for a SwiftUI Menu placed inside a ToolbarItem on iPadOS 26.2 (real device). Scenario: • Screen A is pushed inside a NavigationStack. • Screen B is presented as a sheet (with its own NavigationStack). • Both screens contain the same toolbar Menu item using an SF Symbol (arrow.up.arrow.down). Observed behavior: In the pushed view, hover is mostly stable. In the sheet-presented view, the SF Symbol visibly shifts/jumps when pointer hover activates. The hover highlight shape differs from the native navigation back button. Label-level hoverEffect modifiers do not stabilize the behavior. Minimal example: import SwiftUI struct ContentView: View { @State private var showSheet = false var body: some View { NavigationStack { VStack { Button("Open Sheet") { showSheet = true } } .navigationTitle("Home") .toolbar { ToolbarItem(placement: .topBarTrailing) { Menu { Button("Option A") { } Button("Option B") { } } label: { Image(systemName: "arrow.up.arrow.down") } } } .sheet(isPresented: $showSheet) { SheetView() } } } } struct SheetView: View { var body: some View { NavigationStack { Text("Sheet View") .navigationTitle("Sheet") .toolbar { ToolbarItem(placement: .topBarTrailing) { Menu { Button("Option A") { } Button("Option B") { } } label: { Image(systemName: "arrow.up.arrow.down") } } } } } } This behavior is reproducible 100% on device. Is this expected behavior for Menu inside ToolbarItem when presented as a sheet, or a regression in pointer interaction rendering?
Topic: UI Frameworks SubTopic: SwiftUI
0
0
38
Feb ’26
.edgesIgnoringSafeArea(.vertical) combined with .tabViewStyle(.page(indexDisplayMode: .never)) causes "Out of Bounds" layout in Xcode 26 / iOS 26 SDK
I am reporting a regression/behavioral change in the SwiftUI layout engine when building with Xcode 26 (iOS 26 SDK). In previous versions (Xcode 15/16 and iOS 17/18 SDKs), a TabView using .tabViewStyle(.page(indexDisplayMode: .never)) correctly respected the coordinate space when combined with .edgesIgnoringSafeArea(.vertical). However, when compiling with the iOS 26 SDK, the internal views of the TabView render "out of bounds," pushing content vertically beyond the intended safe area boundaries and causing UI overlapping/clipping - an abnormal behavior. TabView(selection: $selectedIndex) { ForEach(0..<data.count, id: \.self) { index in nextPreviousHandlerView(id: data[index]) .tag(index) } } .tabViewStyle(.page(indexDisplayMode: .never)) .edgesIgnoringSafeArea(.vertical) // Causes vertical "jump" out of bounds in Xcode 26
0
0
56
Feb ’26
TabView inside NavigationStack is abnormal when using Xcode 26
TabView inside NavigationStack is abnormal when using Xcode 26. The y deviation is about 14. But it is right when using Xcode 16.4. It is also right without NavigationStack. import SwiftUI struct ContentView: View { private enum Tab: Hashable, CaseIterable { case a case b } @State private var currentTab: Tab = .a @State private var path: NavigationPath = NavigationPath() var body: some View { NavigationStack(path: $path) { TabView(selection: $currentTab) { ForEach(Tab.allCases, id: \.self) { tab in switch tab { case .a: Color.blue // .offset(y: -14) case .b: Color.yellow } } } .tabViewStyle(.page(indexDisplayMode: .never)) .ignoresSafeArea(.all) } } }
Topic: UI Frameworks SubTopic: SwiftUI
0
0
60
Feb ’26
Smooth appearance switching
Hello every developers. I need your help. Do you know how to attach animation to appearance, like a smooth transition from dark to light and vise versa. My code here: @main struct The_Library_of_BabelonApp: App { @AppStorage("selectedAppearance") private var selectedAppearance = 0 @StateObject private var router = AppRouter() var scheme: ColorScheme? { if selectedAppearance == 1 { return .light } if selectedAppearance == 2 { return .dark } return nil } var body: some Scene { WindowGroup { RootView() .preferredColorScheme(scheme) .environmentObject(router) // this is doesn't work correctly .animation(.smooth(duration: 2), value: selectedAppearance) } } } And my appearance switching looks: struct SettingsView: View { @AppStorage("selectedAppearance") private var selectedAppearance = 0 var body: some View { List { Section(header: Text("Appearance")) { HStack(spacing: 20) { ThemePreview(title: "Light", imageName: "lightTheme", tag: 1, selection: $selectedAppearance) ThemePreview(title: "Dark", imageName: "darkTheme", tag: 2, selection: $selectedAppearance) ThemePreview(title: "System", imageName: "systemMode", tag: 0, selection: $selectedAppearance) } .padding(.vertical, 10) .frame(maxWidth: .infinity) } } } } struct ThemePreview: View { let title: String let imageName: String let tag: Int @Binding var selection: Int var body: some View { Button { selection = tag } label: { VStack { Image(imageName) .resizable() .aspectRatio(contentMode: .fill) .frame(width: 120, height: 80) .clipShape(RoundedRectangle(cornerRadius: 12)) .overlay( RoundedRectangle(cornerRadius: 12) .stroke(selection == tag ? Color.blue : Color.clear, lineWidth: 3) ) Text(title) .font(.caption) .foregroundColor(selection == tag ? .blue : .primary) } } .buttonStyle(.plain) } } I guess my code works but animation working another way, its turn my Section, I don't know.... Thank you in advance
1
0
78
Feb ’26
Swipe to go back still broken with Zoom navigation transition.
When you use .navigationTransition(.zoom(sourceID: "placeholder", in: placehoder)) for navigation animation, going back using the swipe gesture is still very buggy on IOS26. I know it has been mentioned in other places like here: https://developer.apple.com/forums/thread/796805?answerId=856846022#856846022 but nothing seems to have been done to fix this issue. Here is a video showing the bug comparing when the back button is used vs swipe to go back: https://imgur.com/a/JgEusRH I wish there was a way to at least disable the swipe back gesture until this bug is fixed.
8
2
593
Feb ’26
Basics - Dice Demo, calculate total score
I've worked through Apple's dice demo for SwiftUI, so far so good. I've got a single Die view with a button to "roll" the die. This works perfectly using the code below: struct DieView: View { init(dieType: DieType) { self.dieValue = Int.random(in: 1...dieType.rawValue) self.dieType = dieType } @State private var dieValue: Int @State private var dieType: DieType var body: some View { VStack { if self.dieType == DieType.D6 { Image(systemName: "die.face.\(dieValue)") .resizable() .frame(width: 100, height: 100) .padding() } else {//self.dieType == DieType.D12{ Text("\(self.dieValue)") .font(.largeTitle) } Button("Roll"){ withAnimation{ dieValue = Int.random(in: 1...dieType.rawValue) } } .buttonStyle(.bordered) } Spacer() } } Now I want to do a DiceSetView with an arbitrary number of dice. I've got the UI working with the following; struct DiceSetView: View { @State private var totalScore: Int = 0 var body: some View { ScrollView(.horizontal) { HStack{ DieView(dieType: DieType.D6) DieView(dieType: DieType.D6) DieView(dieType: DieType.D6) } } HStack{ Button("Roll All"){} .buttonStyle(.bordered) Text("Score \(totalScore)") .font(.callout) } Spacer() } } Where I'm struggling is how to get the total of all the dice in a set and to roll all the dice in a set on a button click. I can't iterate through the dice, and just "click" the buttons in the child views from their parents, and I can't think how it should be structured to achieve this (I'm new to this style of programming!) - can anyone point me in the right direction for how to achieve what I want? I realise that I'm probably missing something fundamentally conceptual here....
Topic: UI Frameworks SubTopic: SwiftUI
0
0
31
Feb ’26
Basic question - dice demo project - get all values / roll all
I'm sure this is a basic question, but I'm new to this style of development, so thought Id ask... I've worked through Apple's dice roller demo, so far so good - I'm using the code below to render and roll a single die; struct DieView: View { init(dieType: DieType) { self.dieValue = Int.random(in: 1...dieType.rawValue) self.dieType = dieType } @State private var dieValue: Int @State private var dieType: DieType var body: some View { VStack { if self.dieType == DieType.D6 { Image(systemName: "die.face.\(dieValue)") .resizable() .frame(width: 100, height: 100) .padding() } else { Text("\(self.dieValue)") .font(.largeTitle) } } Button("Roll"){ withAnimation{ dieValue = Int.random(in: 1...dieType.rawValue) } } .buttonStyle(.bordered) Spacer() } } Again, so far so good - works as I'd expect. I can now also add multiple DieViews to a DiceSetView and they display as I'd expect. Where I'm stuck is in the DiceSetView, I want to both determine the total score across the dice, and also offer the ability to Roll All the dice in a set. (Ultimately I want another level above the set, so I'll be looking to roll all dice in all sets) I can't simply call a func / method on the child view (i.e. iterate through them and sum their values, and roll each), I suspect I need to change how it's all structured, but not sure where to go from here... Can anyone point me in the right direction?
Topic: UI Frameworks SubTopic: SwiftUI
0
0
30
Feb ’26
Image not rendering on some devices
Hi, new developer here. I have an issue where an image I have on app is not showing up on some devices. The image is: Resources/Assets/logo: I am using it in my app like: ZStack { Color.white .ignoresSafeArea() VStack { Spacer() Image("logo") Spacer() Text(dateString) .font(.custom("LinLibertine", size: 17)) .fontWeight(.bold) .tracking(5) .padding(.bottom, 50) } } The image appears fine on all simulators. And also on my real device iPad with A14. But when I run it on iPhone 8 or iPad Air M4, it shows empty space in place of image. I tried many different options like: Image("logo") .renderingMode(.original) .resizable() .scaledToFit() frame(width: 300) .background(Color.red.opacity(0.3)) But nothing works. What can be the issue?
2
1
130
Feb ’26
SwiftUI mysterious behavior
Hello dear developers! Recently, I stumbled upon some really strange behavior of SwiftUI and I’m very curious why it works this way struct ContentView: View { @State private var title: String? @State private var isSheetPresented: Bool = false var body: some View { Button("Hello, world!") { title = "Sheet title" isSheetPresented = true } .sheet(isPresented: $isSheetPresented, content: { if let title { Text(title) } else { EmptyView() } }) } } Why in this case when we tap the button and sheet comes in we go to the branch else even though we set title before isSheetPresented but it still somehow nil But what really drive me crazy is that if we change a little bit code to this: I just added another @State property 'number' and use it as the Button's title. In this scenario it works 😃 and Text in the sheet view appearing struct ContentView: View { @State private var title: String? @State private var number = 0 @State private var isSheetPresented = false var body: some View { Button("\(number)") { title = "Sheet title" number += 0 isSheetPresented = true } .sheet(isPresented: $isSheetPresented, content: { if let title { Text(title) } else { EmptyView() } }) } } Is this somehow related to what happens under the hood like View Tree and Render Tree (Attribute Graph)? Maybe because ContentView’s body doesn't capture title it cannot be stored in the Render Tree so it always would have the initial value of nil? if there are any well-informed folks here, please help me figure out this mystery, I’d appreciate it!!! p.s. Don’t get me wrong. Im not interested in how to make it work. I’m interested in why this doesn’t work and what really happens under the hood that led to this result
2
0
145
Feb ’26
Menu in the bottom bar flies to the top of the screen
I have a Menu in a Toolbar (specifically, the .bottomBar). If I open the menu quickly after it appears (within a few seconds), it flies to the top of the screen. I've created a minimum woking example below. This appears to be a pretty glaring iOS 26 bug that has been present since the early betas, but I can't seem to find much discussion about it (apart from this post from 8 months ago), so I'm wondering if I might be doing something wrong. Or maybe someone managed to figure out a workaround. If the Menu is very simple (just Text items), it seems to be okay. But if the Menu is even slightly complex (e.g. includes icons), then it exhibits the flying behavior. I've also been able to reproduce this bug under different types of navigation component (e.g. NavigationSplitView). I'm seeing this behavior in the current version of iOS (26.2.1), both on device and in the simulator. MWE struct ContentView: View { var body: some View { NavigationStack { VStack { NavigationLink("Go to Detail") { DetailView() } } .navigationTitle("Root") } } } struct DetailView: View { var body: some View { VStack { Text("Detail View") } .navigationTitle("Detail") .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .bottomBar) { Menu { Button { } label: { Label("Delete", systemImage: "trash") } } label: { Image(systemName: "ellipsis.circle") } } } } }
Topic: UI Frameworks SubTopic: SwiftUI
2
1
107
Feb ’26
safeArea access in XCode 26, iOS 26
Hi. In my project, I use the following property to access the safe area via UIApplication: UIApplication .shared .connectedScenes .flatMap { ($0 as? UIWindowScene)?.windows ?? [] } .first { $0.isKeyWindow }?.safeAreaInsets However, in Xcode 26 and iOS 26, this no longer works, and in some cases the app crashes. Views that rely on this property stop behaving as expected. For example, if it’s a sheet, it does not appear. The same app built with Xcode 16 and distributed via TestFlight runs on iOS 26 without any issues. What is the correct and safe way to obtain safeAreaInsets outside of a View now?
Topic: UI Frameworks SubTopic: SwiftUI
0
1
105
Feb ’26
SwiftUI toolbar items clip DocumentGroup rename affordance
Hi — I’m seeing the DocumentGroup rename/title affordance get clipped on iPad when I populate the navigation bar with SwiftUI toolbar items in .topBarLeading, .principal, and .topBarTrailing (trailing is an HStack of controls). Example: .toolbar { ToolbarItem(placement: .topBarLeading) { UndoRedoControlsView(...) } ToolbarItem(placement: .principal) { Text(canvasInfoTitle).lineLimit(1) } ToolbarItem(placement: .topBarTrailing) { HStack { ... } } } .navigationBarTitleDisplayMode(.inline) Is there a recommended way to structure toolbar content so the system’s document title/rename control always has space (or a way to reserve space / avoid clipping), short of removing .principal or moving items into menus?
Topic: UI Frameworks SubTopic: SwiftUI
0
0
36
Feb ’26
How to align views in a LazyVGrid to a common base-line?
I have the following snippet (but you can see my entire code in GitHub, if you want): LazyVGrid(columns: columns) { ForEach(books) { book in BookView(book: book) .draggable(Book.BookTransferable(persistanceIdentifier: book.id)) } } and BookView is: VStack { Image(nsImage: book.image) .resizable() .frame(width: 150, height: 200) .scaledToFill() Text(book.title) .lineLimit(1) .font(.headline) HStack { ForEach(book.tags.sorted(), id: \.self) { tag in TagView(tag: tag, showText: false) } } } .padding() This will render each BookView on a different base-line because of the fact that the Text view sometimes takes 1, 2 or even 3 lines (as shown). How can I have all BookViews alligned at a common base-line (as it would if Text would only take one line, for example)?
0
0
49
Feb ’26
Vision OS Persona
I’m seeing a camera/capture routing issue on visionOS when multiple WindowGroups are open at the same time. I have a SwiftUI view that starts an AVCaptureSession on onAppear and stops it on onDisappear. The camera feed is displayed in a subview that only exists inside one window. However, when I open additional windows (other WindowGroups) in the same app, the camera perspective/route changes unexpectedly — it looks like the capture is being re-associated with a different scene/window, even though the camera view never moved and no other view starts capture. Expected behavior Opening additional windows should not affect the active capture session or camera routing for the existing camera view. The camera feed should remain stable and tied to the window hosting. Actual behavior When multiple windows are open, the camera feed “switches perspective” / appears to re-route, as if the system changes which scene is considered active for capture. This happens without any explicit code calling startSession() again and without the camera view being present in the other windows. Additional context This app is running in an unbounded scene and uses Unity PolySpatial.
0
0
59
Feb ’26
How to accept CloudKit shares with the new SwiftUI app lifecycle?
In the iOS 13 world, I had code like this: class SceneDelegate: UIResponder, UIWindowSceneDelegate { &#9;&#9;func windowScene(_ windowScene: UIWindowScene, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata) { &#9;&#9;&#9;&#9;// do stuff with the metadata, eventually call CKAcceptSharesOperation &#9;&#9;} } I am migrating my app to the new SwiftUI app lifecycle, and can’t figure out where to put this method. It used to live in AppDelegate pre-iOS13, and I tried going back to that, but the AppDelegate version never gets called. There doesn’t seem to be a SceneDelegateAdaptor akin to UIApplicationDelegateAdaptor available, which would provide a bridge to the old code. So, I’m lost. How do I accept CloudKit shares with SwiftUI app lifecycle? 🙈
4
0
1.4k
Feb ’26
ProgressView(timerInterval:countsDown:) bar never reaches zero
Consider the following code on iOS: struct ContentView: View { @State private var timerInterval = Date(timeIntervalSince1970: 0) ... Date(timeIntervalSince1970: 0) var body: some View { VStack { ProgressView( timerInterval: timerInterval, countsDown: true ) Button { let now = Date() let then = now.addingTimeInterval(5) timerInterval = now ... then } label: { Text("Start") } } .padding() } } When I tap on the Start button, the progress view starts animating as expected, and its label is displaying the remaining time. However, at the very end, when the countdown reaches zero, the blue bar of the progress view doesn't reach zero and still has some progress left forever. Is this the expected behavior or a bug? Is there a way to make the bar reach zero without implementing my own custom view? Thanks in advance!
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
0
Views
27
Activity
Feb ’26
Driving NavigationSplitView with something other than List?
Is it possible to drive NavigationSplitView navigation with a view in sidebar (left column) that is not a List? All examples that I have seen from this year only contain List in sidebar. I ask this because I would like to have a more complex layout in sidebar (or first view on iOS) that contains a mix of elements, some of them non-interactive and not targeting navigation. Here’s what I would like to do: import SwiftUI struct Thing: Identifiable, Hashable {     let id: UUID     let name: String } struct ContentView: View {     let things: [Thing]     @State private var selectedThingId: UUID?          var body: some View {         NavigationSplitView {             ScrollView(.vertical) {                 VStack {                     ForEach(things) { thing in                         Button("Thing: \(thing.name) \( selectedThingId == thing.id ? "selected" : "" )") {                             selectedThingId = thing.id                         }                     } SomeOtherViewHere() Button("Navigate to something else") { selectedThingId = someSpecificId }                 }             }         } detail: {             // ZStack is workaround for known SDK bug             ZStack {                 if let selectedThingId {                     Text("There is a thing ID: \(selectedThingId)")                 } else {                     Text("There is no thing.")                 }             }         }     } } This actually works as expected on iPadOS and macOS, but not iOS (iPhone). Tapping changes the selection as I see in the button label, but does not push anything to navigation stack, I remain stuck at home screen. Also filed as FB10332749.
Replies
14
Boosts
5
Views
7.2k
Activity
Feb ’26
SwiftUI .toolbar(placement: .keyboard) item not exposed to accessibility on iOS 26.1 (affects VoiceOver + XCUITest)
Description On iOS 26.1, a ToolbarItem placed in .keyboard is no longer exposed to the accessibility hierarchy. As a result: VoiceOver cannot focus or activate the toolbar button XCUITest cannot discover the element, making the UI impossible to test TextEditor() .toolbar { ToolbarItem(placement: .keyboard) { Button("Done") { /* action */ } } } This worked correctly on previous iOS versions. The button appears visually but is missing from both VoiceOver navigation and XCUI accessibility queries. Steps to Reproduce Create a new SwiftUI project. Use a simple text field with a keyboard toolbar button. Run on an iOS 26.1 device or simulator. Focus the text field to show the keyboard. Turn on VoiceOver and attempt to navigate to the toolbar button. Run an XCUITest attempting to locate the button
Replies
2
Boosts
1
Views
202
Activity
Feb ’26
SwiftUI view state resetting after alert is shown
Seeing an issue in iOS 26.2 iPhone 17 simulator (haven't been able to reproduce on device or other simulators), where a view's state is reset after an alert is shown. In this example the first LibraryView has the issue when alert is shown, the second LibraryView maintains state as expected. struct ContentView: View { var body: some View { NavigationStack { List { VStack { LibraryView(title: "Show view (Loss of state)") } LibraryView(title: "Show view (Works as expected)") } } } } /// This view is from a package dependency and wants to control the presentation of the sheet internally public struct LibraryView: View { @State private var isPresented: Bool = false let title: String public init(title: String) { self.title = title } public var body: some View { Button(self.title) { self.isPresented = true } .sheet(isPresented: self.$isPresented) { ViewWithAlert() } } } private struct ViewWithAlert: View { @State private var isPresented: Bool = false @State private var presentedCount = 0 var body: some View { Button("Show Alert, count: \(presentedCount)") { isPresented = true presentedCount += 1 } .alert("Hello", isPresented: self.$isPresented) { Button("OK") { } } } } Any ideas? The issue can be corrected by moving the .sheet to a higher level within the layout (i.e. on the NavigationStack). However, the library wants to control that presentation and not require the integration to present the sheet.
Topic: UI Frameworks SubTopic: SwiftUI
Replies
11
Boosts
1
Views
435
Activity
Feb ’26
iPadOS 26 – SwiftUI Menu in ToolbarItem shifts during pointer hover when view is presented as sheet
I am observing inconsistent pointer hover behavior for a SwiftUI Menu placed inside a ToolbarItem on iPadOS 26.2 (real device). Scenario: • Screen A is pushed inside a NavigationStack. • Screen B is presented as a sheet (with its own NavigationStack). • Both screens contain the same toolbar Menu item using an SF Symbol (arrow.up.arrow.down). Observed behavior: In the pushed view, hover is mostly stable. In the sheet-presented view, the SF Symbol visibly shifts/jumps when pointer hover activates. The hover highlight shape differs from the native navigation back button. Label-level hoverEffect modifiers do not stabilize the behavior. Minimal example: import SwiftUI struct ContentView: View { @State private var showSheet = false var body: some View { NavigationStack { VStack { Button("Open Sheet") { showSheet = true } } .navigationTitle("Home") .toolbar { ToolbarItem(placement: .topBarTrailing) { Menu { Button("Option A") { } Button("Option B") { } } label: { Image(systemName: "arrow.up.arrow.down") } } } .sheet(isPresented: $showSheet) { SheetView() } } } } struct SheetView: View { var body: some View { NavigationStack { Text("Sheet View") .navigationTitle("Sheet") .toolbar { ToolbarItem(placement: .topBarTrailing) { Menu { Button("Option A") { } Button("Option B") { } } label: { Image(systemName: "arrow.up.arrow.down") } } } } } } This behavior is reproducible 100% on device. Is this expected behavior for Menu inside ToolbarItem when presented as a sheet, or a regression in pointer interaction rendering?
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
0
Views
38
Activity
Feb ’26
How to Create a Full-Width Container (Edge-to-Edge Layout) Above a List View
I’m trying to add a container view above a list view that stretches edge-to-edge across the device. What’s the recommended approach to achieve this layout with Swift UI? Example
Topic: UI Frameworks SubTopic: SwiftUI
Replies
3
Boosts
0
Views
188
Activity
Feb ’26
.edgesIgnoringSafeArea(.vertical) combined with .tabViewStyle(.page(indexDisplayMode: .never)) causes "Out of Bounds" layout in Xcode 26 / iOS 26 SDK
I am reporting a regression/behavioral change in the SwiftUI layout engine when building with Xcode 26 (iOS 26 SDK). In previous versions (Xcode 15/16 and iOS 17/18 SDKs), a TabView using .tabViewStyle(.page(indexDisplayMode: .never)) correctly respected the coordinate space when combined with .edgesIgnoringSafeArea(.vertical). However, when compiling with the iOS 26 SDK, the internal views of the TabView render "out of bounds," pushing content vertically beyond the intended safe area boundaries and causing UI overlapping/clipping - an abnormal behavior. TabView(selection: $selectedIndex) { ForEach(0..<data.count, id: \.self) { index in nextPreviousHandlerView(id: data[index]) .tag(index) } } .tabViewStyle(.page(indexDisplayMode: .never)) .edgesIgnoringSafeArea(.vertical) // Causes vertical "jump" out of bounds in Xcode 26
Replies
0
Boosts
0
Views
56
Activity
Feb ’26
TabView inside NavigationStack is abnormal when using Xcode 26
TabView inside NavigationStack is abnormal when using Xcode 26. The y deviation is about 14. But it is right when using Xcode 16.4. It is also right without NavigationStack. import SwiftUI struct ContentView: View { private enum Tab: Hashable, CaseIterable { case a case b } @State private var currentTab: Tab = .a @State private var path: NavigationPath = NavigationPath() var body: some View { NavigationStack(path: $path) { TabView(selection: $currentTab) { ForEach(Tab.allCases, id: \.self) { tab in switch tab { case .a: Color.blue // .offset(y: -14) case .b: Color.yellow } } } .tabViewStyle(.page(indexDisplayMode: .never)) .ignoresSafeArea(.all) } } }
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
0
Views
60
Activity
Feb ’26
Smooth appearance switching
Hello every developers. I need your help. Do you know how to attach animation to appearance, like a smooth transition from dark to light and vise versa. My code here: @main struct The_Library_of_BabelonApp: App { @AppStorage("selectedAppearance") private var selectedAppearance = 0 @StateObject private var router = AppRouter() var scheme: ColorScheme? { if selectedAppearance == 1 { return .light } if selectedAppearance == 2 { return .dark } return nil } var body: some Scene { WindowGroup { RootView() .preferredColorScheme(scheme) .environmentObject(router) // this is doesn't work correctly .animation(.smooth(duration: 2), value: selectedAppearance) } } } And my appearance switching looks: struct SettingsView: View { @AppStorage("selectedAppearance") private var selectedAppearance = 0 var body: some View { List { Section(header: Text("Appearance")) { HStack(spacing: 20) { ThemePreview(title: "Light", imageName: "lightTheme", tag: 1, selection: $selectedAppearance) ThemePreview(title: "Dark", imageName: "darkTheme", tag: 2, selection: $selectedAppearance) ThemePreview(title: "System", imageName: "systemMode", tag: 0, selection: $selectedAppearance) } .padding(.vertical, 10) .frame(maxWidth: .infinity) } } } } struct ThemePreview: View { let title: String let imageName: String let tag: Int @Binding var selection: Int var body: some View { Button { selection = tag } label: { VStack { Image(imageName) .resizable() .aspectRatio(contentMode: .fill) .frame(width: 120, height: 80) .clipShape(RoundedRectangle(cornerRadius: 12)) .overlay( RoundedRectangle(cornerRadius: 12) .stroke(selection == tag ? Color.blue : Color.clear, lineWidth: 3) ) Text(title) .font(.caption) .foregroundColor(selection == tag ? .blue : .primary) } } .buttonStyle(.plain) } } I guess my code works but animation working another way, its turn my Section, I don't know.... Thank you in advance
Replies
1
Boosts
0
Views
78
Activity
Feb ’26
Swipe to go back still broken with Zoom navigation transition.
When you use .navigationTransition(.zoom(sourceID: "placeholder", in: placehoder)) for navigation animation, going back using the swipe gesture is still very buggy on IOS26. I know it has been mentioned in other places like here: https://developer.apple.com/forums/thread/796805?answerId=856846022#856846022 but nothing seems to have been done to fix this issue. Here is a video showing the bug comparing when the back button is used vs swipe to go back: https://imgur.com/a/JgEusRH I wish there was a way to at least disable the swipe back gesture until this bug is fixed.
Replies
8
Boosts
2
Views
593
Activity
Feb ’26
Basics - Dice Demo, calculate total score
I've worked through Apple's dice demo for SwiftUI, so far so good. I've got a single Die view with a button to "roll" the die. This works perfectly using the code below: struct DieView: View { init(dieType: DieType) { self.dieValue = Int.random(in: 1...dieType.rawValue) self.dieType = dieType } @State private var dieValue: Int @State private var dieType: DieType var body: some View { VStack { if self.dieType == DieType.D6 { Image(systemName: "die.face.\(dieValue)") .resizable() .frame(width: 100, height: 100) .padding() } else {//self.dieType == DieType.D12{ Text("\(self.dieValue)") .font(.largeTitle) } Button("Roll"){ withAnimation{ dieValue = Int.random(in: 1...dieType.rawValue) } } .buttonStyle(.bordered) } Spacer() } } Now I want to do a DiceSetView with an arbitrary number of dice. I've got the UI working with the following; struct DiceSetView: View { @State private var totalScore: Int = 0 var body: some View { ScrollView(.horizontal) { HStack{ DieView(dieType: DieType.D6) DieView(dieType: DieType.D6) DieView(dieType: DieType.D6) } } HStack{ Button("Roll All"){} .buttonStyle(.bordered) Text("Score \(totalScore)") .font(.callout) } Spacer() } } Where I'm struggling is how to get the total of all the dice in a set and to roll all the dice in a set on a button click. I can't iterate through the dice, and just "click" the buttons in the child views from their parents, and I can't think how it should be structured to achieve this (I'm new to this style of programming!) - can anyone point me in the right direction for how to achieve what I want? I realise that I'm probably missing something fundamentally conceptual here....
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
0
Views
31
Activity
Feb ’26
Basic question - dice demo project - get all values / roll all
I'm sure this is a basic question, but I'm new to this style of development, so thought Id ask... I've worked through Apple's dice roller demo, so far so good - I'm using the code below to render and roll a single die; struct DieView: View { init(dieType: DieType) { self.dieValue = Int.random(in: 1...dieType.rawValue) self.dieType = dieType } @State private var dieValue: Int @State private var dieType: DieType var body: some View { VStack { if self.dieType == DieType.D6 { Image(systemName: "die.face.\(dieValue)") .resizable() .frame(width: 100, height: 100) .padding() } else { Text("\(self.dieValue)") .font(.largeTitle) } } Button("Roll"){ withAnimation{ dieValue = Int.random(in: 1...dieType.rawValue) } } .buttonStyle(.bordered) Spacer() } } Again, so far so good - works as I'd expect. I can now also add multiple DieViews to a DiceSetView and they display as I'd expect. Where I'm stuck is in the DiceSetView, I want to both determine the total score across the dice, and also offer the ability to Roll All the dice in a set. (Ultimately I want another level above the set, so I'll be looking to roll all dice in all sets) I can't simply call a func / method on the child view (i.e. iterate through them and sum their values, and roll each), I suspect I need to change how it's all structured, but not sure where to go from here... Can anyone point me in the right direction?
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
0
Views
30
Activity
Feb ’26
Image not rendering on some devices
Hi, new developer here. I have an issue where an image I have on app is not showing up on some devices. The image is: Resources/Assets/logo: I am using it in my app like: ZStack { Color.white .ignoresSafeArea() VStack { Spacer() Image("logo") Spacer() Text(dateString) .font(.custom("LinLibertine", size: 17)) .fontWeight(.bold) .tracking(5) .padding(.bottom, 50) } } The image appears fine on all simulators. And also on my real device iPad with A14. But when I run it on iPhone 8 or iPad Air M4, it shows empty space in place of image. I tried many different options like: Image("logo") .renderingMode(.original) .resizable() .scaledToFit() frame(width: 300) .background(Color.red.opacity(0.3)) But nothing works. What can be the issue?
Replies
2
Boosts
1
Views
130
Activity
Feb ’26
SwiftUI mysterious behavior
Hello dear developers! Recently, I stumbled upon some really strange behavior of SwiftUI and I’m very curious why it works this way struct ContentView: View { @State private var title: String? @State private var isSheetPresented: Bool = false var body: some View { Button("Hello, world!") { title = "Sheet title" isSheetPresented = true } .sheet(isPresented: $isSheetPresented, content: { if let title { Text(title) } else { EmptyView() } }) } } Why in this case when we tap the button and sheet comes in we go to the branch else even though we set title before isSheetPresented but it still somehow nil But what really drive me crazy is that if we change a little bit code to this: I just added another @State property 'number' and use it as the Button's title. In this scenario it works 😃 and Text in the sheet view appearing struct ContentView: View { @State private var title: String? @State private var number = 0 @State private var isSheetPresented = false var body: some View { Button("\(number)") { title = "Sheet title" number += 0 isSheetPresented = true } .sheet(isPresented: $isSheetPresented, content: { if let title { Text(title) } else { EmptyView() } }) } } Is this somehow related to what happens under the hood like View Tree and Render Tree (Attribute Graph)? Maybe because ContentView’s body doesn't capture title it cannot be stored in the Render Tree so it always would have the initial value of nil? if there are any well-informed folks here, please help me figure out this mystery, I’d appreciate it!!! p.s. Don’t get me wrong. Im not interested in how to make it work. I’m interested in why this doesn’t work and what really happens under the hood that led to this result
Replies
2
Boosts
0
Views
145
Activity
Feb ’26
Menu in the bottom bar flies to the top of the screen
I have a Menu in a Toolbar (specifically, the .bottomBar). If I open the menu quickly after it appears (within a few seconds), it flies to the top of the screen. I've created a minimum woking example below. This appears to be a pretty glaring iOS 26 bug that has been present since the early betas, but I can't seem to find much discussion about it (apart from this post from 8 months ago), so I'm wondering if I might be doing something wrong. Or maybe someone managed to figure out a workaround. If the Menu is very simple (just Text items), it seems to be okay. But if the Menu is even slightly complex (e.g. includes icons), then it exhibits the flying behavior. I've also been able to reproduce this bug under different types of navigation component (e.g. NavigationSplitView). I'm seeing this behavior in the current version of iOS (26.2.1), both on device and in the simulator. MWE struct ContentView: View { var body: some View { NavigationStack { VStack { NavigationLink("Go to Detail") { DetailView() } } .navigationTitle("Root") } } } struct DetailView: View { var body: some View { VStack { Text("Detail View") } .navigationTitle("Detail") .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .bottomBar) { Menu { Button { } label: { Label("Delete", systemImage: "trash") } } label: { Image(systemName: "ellipsis.circle") } } } } }
Topic: UI Frameworks SubTopic: SwiftUI
Replies
2
Boosts
1
Views
107
Activity
Feb ’26
safeArea access in XCode 26, iOS 26
Hi. In my project, I use the following property to access the safe area via UIApplication: UIApplication .shared .connectedScenes .flatMap { ($0 as? UIWindowScene)?.windows ?? [] } .first { $0.isKeyWindow }?.safeAreaInsets However, in Xcode 26 and iOS 26, this no longer works, and in some cases the app crashes. Views that rely on this property stop behaving as expected. For example, if it’s a sheet, it does not appear. The same app built with Xcode 16 and distributed via TestFlight runs on iOS 26 without any issues. What is the correct and safe way to obtain safeAreaInsets outside of a View now?
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
1
Views
105
Activity
Feb ’26
SwiftUI toolbar items clip DocumentGroup rename affordance
Hi — I’m seeing the DocumentGroup rename/title affordance get clipped on iPad when I populate the navigation bar with SwiftUI toolbar items in .topBarLeading, .principal, and .topBarTrailing (trailing is an HStack of controls). Example: .toolbar { ToolbarItem(placement: .topBarLeading) { UndoRedoControlsView(...) } ToolbarItem(placement: .principal) { Text(canvasInfoTitle).lineLimit(1) } ToolbarItem(placement: .topBarTrailing) { HStack { ... } } } .navigationBarTitleDisplayMode(.inline) Is there a recommended way to structure toolbar content so the system’s document title/rename control always has space (or a way to reserve space / avoid clipping), short of removing .principal or moving items into menus?
Topic: UI Frameworks SubTopic: SwiftUI
Replies
0
Boosts
0
Views
36
Activity
Feb ’26
How to align views in a LazyVGrid to a common base-line?
I have the following snippet (but you can see my entire code in GitHub, if you want): LazyVGrid(columns: columns) { ForEach(books) { book in BookView(book: book) .draggable(Book.BookTransferable(persistanceIdentifier: book.id)) } } and BookView is: VStack { Image(nsImage: book.image) .resizable() .frame(width: 150, height: 200) .scaledToFill() Text(book.title) .lineLimit(1) .font(.headline) HStack { ForEach(book.tags.sorted(), id: \.self) { tag in TagView(tag: tag, showText: false) } } } .padding() This will render each BookView on a different base-line because of the fact that the Text view sometimes takes 1, 2 or even 3 lines (as shown). How can I have all BookViews alligned at a common base-line (as it would if Text would only take one line, for example)?
Replies
0
Boosts
0
Views
49
Activity
Feb ’26
Vision OS Persona
I’m seeing a camera/capture routing issue on visionOS when multiple WindowGroups are open at the same time. I have a SwiftUI view that starts an AVCaptureSession on onAppear and stops it on onDisappear. The camera feed is displayed in a subview that only exists inside one window. However, when I open additional windows (other WindowGroups) in the same app, the camera perspective/route changes unexpectedly — it looks like the capture is being re-associated with a different scene/window, even though the camera view never moved and no other view starts capture. Expected behavior Opening additional windows should not affect the active capture session or camera routing for the existing camera view. The camera feed should remain stable and tied to the window hosting. Actual behavior When multiple windows are open, the camera feed “switches perspective” / appears to re-route, as if the system changes which scene is considered active for capture. This happens without any explicit code calling startSession() again and without the camera view being present in the other windows. Additional context This app is running in an unbounded scene and uses Unity PolySpatial.
Replies
0
Boosts
0
Views
59
Activity
Feb ’26
How to accept CloudKit shares with the new SwiftUI app lifecycle?
In the iOS 13 world, I had code like this: class SceneDelegate: UIResponder, UIWindowSceneDelegate { &#9;&#9;func windowScene(_ windowScene: UIWindowScene, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata) { &#9;&#9;&#9;&#9;// do stuff with the metadata, eventually call CKAcceptSharesOperation &#9;&#9;} } I am migrating my app to the new SwiftUI app lifecycle, and can’t figure out where to put this method. It used to live in AppDelegate pre-iOS13, and I tried going back to that, but the AppDelegate version never gets called. There doesn’t seem to be a SceneDelegateAdaptor akin to UIApplicationDelegateAdaptor available, which would provide a bridge to the old code. So, I’m lost. How do I accept CloudKit shares with SwiftUI app lifecycle? 🙈
Replies
4
Boosts
0
Views
1.4k
Activity
Feb ’26