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

Prevent SwiftUI to stop rendering UI when window loses focus.
Hello, I am writing an audio utility, with a typical audio track player, in SwiftUI for macos 26. My current problem is that the SwiftUI stops rendering the main window UI when the window loses focus. This is a problem since even clicking on the app menu bar has the window loose focus, and the timer, time cursor and all animations of the audio piece stop. All baground services, audio, timers and model continue running (even tho with some crackling on the switch). Once the window focus is re-obtained the animations continue and skip to current state. I have read that SwiftUI optimizes macos like ios, and disables the ui run loop, but there must be a way to disable, since this obviously not the case for most mac app. Is there a solution with either SwiftUI or involving AppKit?
1
0
91
2d
Picker using SwiftData
I am attempting to impliment a a Picker that uses SwiftData to fill in the choices. I am missing something because I can get the picker to appear with the proper selections but the picker does not register my choice (no check mark appears and the text in the picker window is blank after I move to the next field. The model import Foundation import SwiftData //Model one: type of contract, i.e. Firm Fixed Price, etc @Model final class TypeOfContract { var contracts: [Contract] @Attribute(.unique) var typeName: String @Attribute(.unique) var typeCode: String var typeDescription: String init(contracts: [Contract], typeName: String = "", typeCode: String = "", typeDescription: String = "") { self.contracts = contracts self.typeName = typeName self.typeCode = typeCode self.typeDescription = typeDescription } } //Model two: the Contract @Model final class Contract { var contractType: TypeOfContract? var costReports: [CostReport] @Attribute(.unique) var contractNumber: String @Attribute(.unique) var contractName: String var startDate: Date var endDate: Date var contractValue: Decimal var contractCompany: String var contractContact: String var contactEmail: String var contactPhone: String var contractNotes: String init(contractType: TypeOfContract? = nil, costReports: [CostReport], contractNumber: String = "", contractName: String = "", startDate: Date = .now, endDate: Date = .now, contractValue: Decimal = 0.00, contractCompany: String = "", contractContact: String = "", contactEmail: String = "", contactPhone: String = "", contractNotes: String = "") { self.contractType = contractType self.costReports = costReports self.contractNumber = contractNumber self.contractName = contractName self.startDate = startDate self.endDate = endDate self.contractValue = contractValue self.contractCompany = contractCompany self.contractContact = contractContact self.contactEmail = contactEmail self.contactPhone = contactPhone self.contractNotes = contractNotes } } //Model Three: The Cost Reports @Model final class CostReport { var contract: Contract? var periodStartDate: Date var periodEndDate: Date var bCWP: Double //Budgeted Cost Work Performed var aCWP: Double //Actual Cost Work Performed var bCWS: Double //Budgeted Cost Work Scheduled //Calculated fields init(contract: Contract? = nil, periodStartDate: Date = .now, periodEndDate: Date = .now, bCWP: Double = 0.0, aCWP: Double = 0.0, bCWS: Double = 0.0) { self.contract = contract self.periodStartDate = periodStartDate self.periodEndDate = periodEndDate self.bCWP = bCWP self.aCWP = aCWP self.bCWS = bCWS } } The Swift Code for the input form import SwiftData struct EnterNewContract: View { @Environment(\.modelContext) var modelContext @Query(sort: \TypeOfContract.typeCode) private var typeOfContracts: [TypeOfContract] @Query private var contracts: [Contract] @State private var costReports: [CostReport] = [] @State private var contractType: [TypeOfContract] = [] @State private var contractNumber: String = "" @State private var contractName: String = "" @State private var startDate: Date = Date() @State private var endDate: Date = Date() @State private var contractValue: Decimal = 0 @State private var contractCompany: String = "" @State private var contractContact: String = "" @State private var contactEmail: String = "" @State private var contactPhone: String = "" @State private var contractNotes: String = "" var body: some View { Form { VStack { Section(header: Text("Enter New Contract") .foregroundStyle(.green) .font(.headline)){ Picker("Select a type of contract", selection: $contractType) { ForEach(typeOfContracts, id: \.self) { typeOfContracts in Text(typeOfContracts.typeCode) .tag(contractType) } } TextField("Contract Number", text: $contractNumber) .frame(width: 800, height: 40) TextField("Contract Name", text: $contractName) .frame(width: 800, height: 40) DatePicker("Contract Start Date", selection: $startDate, displayedComponents: [.date]) DatePicker("Contract End Date", selection: $endDate, displayedComponents: [.date]) } } } } }
3
0
142
3d
List jumps back to the top
Following on from this thread: https://developer.apple.com/forums/thread/805037 my list of items is now correctly maintaining state (no more disappearing rows), but I'm now hitting a really annoying issue: Every time something changes - even just changing the dark mode of the device - the entire list of items is refreshed, and the list jumps back to the top. A simple representation: // modelData.filteredItems is either all items or some items, depending on whether the user is searching List { ForEach(modelData.filteredItems) { item in ItemRow(item: item) } } When the user isn't searching, filteredItems has everything in it. When they turn on search, I filter and sort the data in place: // Called when the user turns on search, or when the searchString or searchType changes func sortAndFilterItemsInModelData() { modelData.filteredItems.removeAll() // Remove all items from the filtered array modelData.filteredItems.append(contentsOf: modelData.allItems) // Add all items back in let searchString: String = modelData.searchString.lowercased() switch(modelData.searchType) { case 1: // Remove all items from the filtered array that don't match the search string modelData.filteredItems.removeAll(where: { !$0.name.lowercased().contains(searchString) }) ... } // Sorting switch(modelData.sortKey) { case sortKeyDate: modelData.sortAscending ? modelData.filteredItems.sort { $0.date < $1.date } : modelData.filteredItems.sort { $0.date > $1.date } // Sorts in place ... } } The method doesn't return anything because all the actions are done in place on the data, and the view should display the contents of modelData.filteredItems. If you're searching and there are, say 10 items in the list and you're at the bottom of the list, then you change the search so there are now 11 items, it jumps back to the top rather than just adding the extra ItemRow to the bottom. Yes, the data is different, but it hasn't been replaced; it has been altered in place. The biggest issue here is that you can simply change the device to/from Dark Mode - which can happen automatically at a certain time of day - and you're thrown back to the top of the list. The array of data hasn't changed, but SwiftUI treats it as though it has. There's also a section in the List that can be expanded and contracted. It shows or hides items of a certain type. When I expand it, I expect the list to stay in the same place and just show the extra rows, but again, it jumps to the top. It's a really poor user experience. Am I doing something wrong (probably, yes), or is there some other way to retain the scroll position in a List? The internet suggests switching to a LazyVStack, but I lose left/right swipe buttons and the platform-specific styling. Thanks.
9
0
181
3d
Navigation Bar Occupies Too Much Space in iOS 26 Landscape Orientation
I’m really frustrated with iOS 26. It was supposed to make better use of screen space, but when you combine the navigation bar, tab bar, and search bar, they eat up way too much room. Apple actually did a great job with the new tab bar — it’s smaller, smooth, and looks great when expanding or collapsing while scrolling. The way the search bar appears above the keyboard is also really nice. But why did they keep the navigation bar the same height in both portrait and landscape? In landscape it takes up too much space and just looks bad. It was way better in iOS 18.
2
0
107
3d
How to display a toast view above both main content and FullScreenCover in SwiftUI?
I'm using a ZStack with viewA() and a toast viewB(). I present a FullScreenView() using .fullScreenCover(isPresented:). ZStack { viewA() viewB() // toast view } .fullScreenCover(isPresented: $isPresented) { FullScreenView() } I want viewB (the toast) to appear above both viewA and the FullScreenView. I only found this approach works but it has duplicate code. ZStack { viewA() viewB() // toast view } .fullScreenCover(isPresented: $isPresented) { ZStack { FullScreenModalView() viewB() // toast view } } What are all possible approaches to achieve this in SwiftUI? Any advice or code samples would be appreciated!
Topic: UI Frameworks SubTopic: SwiftUI
1
0
58
3d
Focusable doesn't work on iPad with external keyboard
I have a custom input view in my app which is .focusable(). It behaves similar to a TextField, where it must be focused in order to be used. This works fine on all platforms including iPad, except when when an external keyboard is connected (magic keyboard), in which case it can't be focused anymore and becomes unusable. Is there a solution to this, or a workaround? My view is very complex, so simple solutions like replacing it with a native view isn't possible, and I must be able to pragmatically force it to focus. Here's a very basic example replicating my issue. Non of the functionality works when a keyboard is connected: struct FocusableTestView: View { @FocusState private var isRectFocused: Bool var body: some View { VStack { // This text field should focus the custom input when pressing return: TextField("Enter text", text: .constant("")) .textFieldStyle(.roundedBorder) .onSubmit { isRectFocused = true } .onKeyPress(.return) { isRectFocused = true return .handled } // This custom "input" should focus itself when tapped: Rectangle() .fill(isRectFocused ? Color.accentColor : Color.gray.opacity(0.3)) .frame(width: 100, height: 100) .overlay( Text(isRectFocused ? "Focused" : "Tap me") ) .focusable(true, interactions: .edit) .focused($isRectFocused) .onTapGesture { isRectFocused = true print("Focused rectangle") } // The focus should be able to be controlled externally: Button("Toggle Focus") { isRectFocused.toggle() } .buttonStyle(.bordered) } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) } }
1
0
106
3d
Symbol Effects Cause Crash When Switching Between Conditional `.fill` SF Symbols
I am reporting a consistent EXC_BAD_ACCESS (SIGSEGV) crash when using the .contentTransition(.symbolEffect(.replace.byLayer)) modifier on a conditional $SF$ Symbol, but only under very specific conditions: Both Symbols must be .fill variants (e.g., arrow.up.circle.fill $\leftrightarrow$ plus.circle.fill). The crash only occurs when the state changes and the view attempts to transition back to the original symbol (the one present when the view was first rendered). For example, if the initial state displays arrow.up.circle.fill, the app successfully transitions to plus.circle.fill. However, the app crashes when the state changes again, attempting to transition from plus.circle.fill back to arrow.up.circle.fill.This crash is fully reproducible in the iOS Simulator and is not limited to Xcode Previews. Commenting out the .contentTransition modifier resolves the crash immediately. The crash is a KERN_INVALID_ADDRESS at 0x0000000000000060, pointing to a null pointer dereference deep within the graphics rendering pipeline in the RenderBox framework. It appears to be a failure in handling the layer data during the reverse transition of two filled-variant symbols. Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000060 Thread 0 Crashed: 0 RenderBox 0x1cc692a0c RB::Symbol::Glyph::Layer::resolve_draw_transforms(...) + 292 1 RenderBox 0x1cc692730 RB::Symbol::Glyph::Layer::append_path(...) + 392 ... 7 SwiftUICore 0x1d9d5f824 specialized _ShapeStyle_RenderedShape.renderVectorGlyph(...) + 1444 The code below crashes on the second tap (transitioning back to arrow.up.circle.fill): struct QuickAddButtonTest: View { @State private var isTextFieldFocused: Bool = false // Both symbols use the .fill variant var body: some View { Button(action: { isTextFieldFocused.toggle() }) { Image(systemName: isTextFieldFocused ? "arrow.up.circle.fill" : "plus.circle.fill") .foregroundColor(.primary) .font(.system(size: 30)) .contentTransition(.symbolEffect(.replace.byLayer)) // <-- CRASH SOURCE } } } The crash can be avoided by: Removing the .contentTransition(.symbolEffect(.replace.byLayer)) modifier, or Switching one or both symbols to a non-filled variant (e.g., plus.circle instead of plus.circle.fill).
1
0
45
3d
Menu List Error
Hi, I'm trying to have a menu at the trailing edge of a list but when I do so I am getting UIKit errors. I pasted my sample code below. Not exactly sure how to fix this. ForEach(0..<100) { i in HStack { Text("\(i)") Spacer() Menu { Text("Test") } label: { Image(systemName: "ellipsis") } } } } Adding '_UIReparentingView' as a subview of UIHostingController.view is not supported and may result in a broken view hierarchy. Add your view above UIHostingController.view in a common superview or insert it into your SwiftUI content in a UIViewRepresentable instead.
Topic: UI Frameworks SubTopic: SwiftUI
2
0
104
3d
How to prevent VoiceOver from reading text INSIDE an image?
In the example below, VoiceOver (in both iOS 18 and 26) reads the text contained within the image after the .accessibilityLabel, introduced by a “beep.” VoiceOver: Purple rounded square with the word 'Foo' in white letters. Image [beep] foo. I’d like it to only read the accessibility label. As a developer focused on accessibility, I make sure every image already has an appropriate label, so having iOS read the image text is redundant. Sample Code import SwiftUI struct ContentView: View { var body: some View { Image("TextInImage") .resizable() .scaledToFit() .frame(width: 64, height: 64) .accessibilityLabel("Purple rounded square with the word 'Foo' in white letters.") } } Sample Image Drop this image in to Assets.xcassets and confirm it's named TextInImage.
4
0
159
5d
List rows disappearing when scrolling
I have a List containing ItemRow views based on an ItemDetails object. The content is provided by a model which pulls it from Core Data. When I scroll through the list one or two of the rows will disappear and reappear when I scroll back up. I have a feeling it's because the state is being lost? Here's some relevant info (only necessary parts of the files are provided): -- ModelData.swift: @Observable class ModelData { var allItems: [ItemDetails] = coreData.getAllItems() ... } -- ItemDetails.swift: struct ItemDetails: Identifiable, Hashable, Equatable { public let id: UUID = UUID() public var itemId: String // Also unique, but used for a different reason ... } -- MainApp.swift: let modelData: ModelData = ModelData() // Created as a global class SceneDelegate: UIResponder, UIWindowSceneDelegate { // Methods in here (and in lots of other places) use `modelData`, which is why it's a global } @main struct MainApp: App { var body: some Scene { WindowGroup { MainView() } } ... } -- MainView.swift: struct MainView: View { var body: some View { List { ForEach(modelData.allItems, id: \.id) { item in ItemRow(item) } } } } struct ItemRow: View, Equatable { var item: ItemDetails var body: some View { ... } static func == (lhs: Self, rhs: Self) -> Bool { lhs.item == rhs.item } } There's obviously more code in the app than that, but it's not relevant to the issue. I've tried: ItemRow(item).equatable() Wrapping ItemRow in an EquatableView Giving the List a unique id Using class ModelData: ObservableObject and @StateObject for modelData None made any difference. I'm using iOS/iPadOS 26.0.1, and I see it on my physical iPhone 17 Pro Max and iPad Pro 11-inch M4, but I don't see it in the equivalent simulators on those versions. The Simulator also doesn't exhibit this for versions 17.5 and 18.5, and I have no physical devices on 17.5/18.5 to check. Should I be doing as I currently am, where I create modelData as a global let so I can access it everywhere, or should I pass it through the view hierarchy as an Environment variable, like @Environment(ModelData.self) var modelData: ModelData? Bear in mind that some functions are outside of the view hierarchy and cannot access modelData if I do this. Various things like controllers that need access to values in modelData cannot get to it. Any ideas? Thanks.
2
0
90
5d
Prevent default file selector in a SwiftUI DocumentGroup app and show a custom welcome window on launch
I’m building a macOS document based app using SwiftUI’s DocumentGroup API. By default, when a document based app launches, macOS automatically shows a file open panel or creates a new untitled document window. However, I want to suppress this default behavior and instead show a custom welcome window when the app starts — something similar to how Xcode or Final Cut Pro shows a “Welcome” or “Start Project” screen first. So basically, when the user opens the app normally, it should not open the document selector or create a document automatically. Instead, it should show my custom SwiftUI or AppKit window. Here is my Code :- //MyApp.swift import SwiftUI import AppKit @main struct PhiaApp: App { @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate var body: some Scene { DocumentGroup(newDocument: MyDocumentModel()) { file in EditorView(document: file.document, filePath: file.fileURL) } Settings { EmptyView() } } } Current I have this code setup for my MainApp.swift, where I am using the AppDelegate to create a custom recording window using appkit and also defining the DocumentGroup to handle the custom .myapp file opens. However, when I launch the app, its showing my appkit window as well as the macOs native file Selector to select the file I want to open. I want when the user opens the app normally, it should not open the document selector or create a document automatically. Instead, it should show my custom SwiftUI or AppKit window. However, the app should still fully support opening .myapp documents by double clicking from Finder, using the standard File → Open and File → New menu options, also having multiple document windows open at once. This is my AppDelegate.swift file :- import AppKit import SwiftUI class AppDelegate: NSObject, NSApplicationDelegate { var panel: Panel? private var statusItem: NSStatusItem? func applicationDidFinishLaunching(_ notification: Notification) { showWindow() } // MARK: - Window control func showWindow() { if panel == nil { let root = RecordingViewMain() let newPanel = Panel(rootView: root) if let screen = NSScreen.main { let size = NSSize(width: 360, height: 240) let origin = NSPoint( x: screen.visibleFrame.midX - size.width / 2, y: screen.visibleFrame.midY - size.height / 2 ) newPanel.setFrame(NSRect(origin: origin, size: size), display: true) } panel = newPanel } panel?.makeKeyAndOrderFront(nil) } func hideWindow() { panel?.orderOut(nil) } @objc private func showPanelAction() { showWindow() } @objc private func quitAction() { NSApp.terminate(nil) } }
2
0
151
6d
onContinueUserActivity(CSSearchableItemActionType, perform) does not work on a SwiftUI macOS app
onContinueUserActivity(CSSearchableItemActionType, perform) works as expected on iOS when we search and select an item from Spotlight, but nothing happens when we do the same on a SwiftUI macOS app. var body: some Scene { WindowGroup { MyView() .onContinueUserActivity(CSSearchableItemActionType, perform: handleSpotlight) } } func handleSpotlight(_ userActivity: NSUserActivity) { // Is not called... } How can we respond to a user clicking a Spotlight result from our apps on macOS?
3
1
826
6d
Customizable Toolbar on iPadOS26 seems not customizable
Hi, I have started app development fairly recently and I decided to develop for Apple due to the fact that my school uses iPads and they were so convincing that I decided to buy more Apple products adding to the experience with the iPad such as a Mac where I learned Xcode, Swift and SwiftUI as far as I could comprehend. I am working on a document based app for my school and I want to implement a toolbar that’s user customizable. There seems to be no way to get a customizable toolbar running on iPadOS26 though iPadOS16 has supported this feature and it has been till 18, I believe. I have set up a doc-based app in Xcode and that and all of its views do work except the toolbar that I added to my NavigationSplitView. The items show, when their defaultCustomization isn’t set to .hidden. The toolbar is given an id and the items are all wrapped in the ToolbarItem structure that also is given an id and the placement of .secondaryAction. The items show up and behave as expected in terms of grouping and making space if there isn’t enough room for all items so some appear in the overflow menu. From apps like Preview, Reminders and MindNode I know that the customization is supposed to still be available but it lives in the menu bar, where I haven’t seen it under view. It seems like there is a thing that my toolbar does not conform to or that there is a method that‘s called, when the user wants to customize the toolbar that I don’t know about. I would much appreciate a quick fix, solution or suggestion.
1
0
105
6d
Need help with attribute inspector in Xcode 26
I am trying to learn Xcode and swift ui for a class project but the attribute inspector just does not show up, I can have the simulator open or closed I click on it nothing works. I feel so stupid. I suppose you don't need it but it helps a lot. anyone have any trouble shooting that could help?
Topic: UI Frameworks SubTopic: SwiftUI
3
2
139
1w
SwiftUI resultBuilder foreach
'm trying to write my own stack, and the issue I'm encountering is how to get the child content of a ForEach. // // ContentView.swift // test // // Created by cnsinda on 2025/10/18. // import SwiftUI public struct MyStack<Content: View>: View { var content: [Content] public init(@MyStackBuilder<Content> content: @escaping () -> [Content]) { self.content = content() } public var body: some View { VStack { // I expect to get 9, but it always returns 1. Text("count:\(content.count)") } } } @resultBuilder public enum MyStackBuilder<Value: View> { static func buildBlock() -> [Value] { [] } public static func buildBlock(_ components: Value...) -> [Value] { components } public static func buildBlock(_ components: [Value]...) -> [Value] { components.flatMap { $0 } } // hit public static func buildExpression(_ expression: Value) -> [Value] { [expression] } public static func buildArray(_ components: [[Value]]) -> [Value] { components.flatMap { $0 } } static func buildFinalResult(_ components: [Value]) -> [Value] { components } public static func buildExpression(_ expression: ForEach<[Int], Int, Value>) -> [Value] { expression.data.flatMap { index in [expression.content(index)] } } public static func buildEither(first: [Value]) -> [Value] { return first } public static func buildEither(second: [Value]) -> [Value] { return second } public static func buildIf(_ element: [Value]?) -> [Value] { return element ?? [] } } struct ContentView: View { var body: some View { ZStack { MyStack { ForEach([100, 110, 120, 130, 140, 150, 160, 170, 180], id: \.self) { item in Rectangle().frame(width: item, height: 20).padding(10) } } } .frame(width: 600, height: 600) } } My expectation is to get each individual Rectangle(), but the actual result is that the entire ForEach is treated as a single View. What should I do?
1
0
327
1w
Multiline Text not possible in accessoryRectangular widget on lock screen
Filed as FB20766506 I have a very simple use case for a rectangular widget on the iPhone lock screen: One Text element which should fill as much space as possible. However, it only ever does 2 per default and then eclipses the rest of the string. Three separate Text elements work fine, so does a fixedSize modifier hack (with that even four lines are possible!). Am I completely misunderstanding something or why is this not possible per default? Other apps' widgets like Health do it as well. My attempt (background added for emphasis) Health app widget var body: some View { VStack(alignment: .leading) { /// This should span three lines, but only spans 2 which eclipsed text. Text("This is a very long text which should span multiple lines.") // .fixedSize(horizontal: false, vertical: true) /// Using this fixes it as well, but that does not seem like a good default solution. /// Three separate `Text` elements work fine. // Text("This is a very long") // Text("text which should") // Text("span multiple lines.") } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading) .background(Color.black) /// Added for emphasis of the widget frame }
2
0
84
1w
'tabViewBottomAccessory' leaves an empty accessory area when conditionally hidden
We use SwiftUI's .tabViewBottomAccessory in our iOS apps for displaying an Audio MiniPlayer View (like in the Apple Music App). TabView(selection: $viewModel.selectedTab) { // Tabs here } .tabViewBottomAccessory { if viewModel.showAudioMiniPlayer { MiniPlayerView() } } The Problem This code works perfectly on iOS 26.0. When viewModel.showAudioMiniPlayer is false, the accessory is completely hidden. However, on iOS 26.1 (23B5059e), when 'viewModel.showAudioMiniPlayer' becomes false, the MiniPlayerView disappears, but an empty container remains, leaving a blank space above the tab bar. Is this a known Bug in iOS 26.1 and are there any effective workarounds?
Topic: UI Frameworks SubTopic: SwiftUI
4
1
196
1w
AlarmKit alarms only showing on lock screen
I am using AlarmKit to schedule alarms in an app I am working on, however my scheduled alarms only show up on the lock screen. If I am on the home screen or elsewhere I only hear the sound of the alarm, but no UI shows up. Environment: iOS 26 beta 3 Xcode 26 beta 3
Topic: UI Frameworks SubTopic: SwiftUI
3
3
221
1w