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

iOS 26: .tabViewBottomAccessory - How to open a new view on the tabViewBottomAccessory
If you are currently on the beta of iOS 26, open Apple Music and you'll see a tabViewBottomAccessory that is the mini NowPlayingView. When tapped, it opens the NowPlayingView. Is there a similar way to do this in SwiftUI? Looking through Apple's documentation, they do not specify any way to reproduce the same kind of view transition. This is the Apple Music app with the tabViewBottomAccessory. When clicked it opens the NowPlayingView
0
0
57
1w
FileExporter's action label always says "Move"
I would like to implement an "Export" dialog using the .fileExporter() view modifier. The following code works correctly, but the FileExporter's action label always says "Move", which is inappropriate for the context. I would like to change it to say "Export", "Save", "Save as", or anything semantically correct. Button("Browse") { showingExporter = true } .buttonStyle(.borderedProminent) .fileExporter( isPresented: $showingExporter, document: document, contentType: .data, defaultFilename: suggestedFilename ?? fileUrl.pathComponents.last ?? "Untitled" ) { result in switch result { case .success(let url): print("Saved to \(url)") onSuccess() case .failure(let error): print(error.localizedDescription) onError(error) } } "document" is a custom FileDocument with a fileWrapper() method implemented like this: func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper { return FileWrapper(regularFileWithContents: data) } This was tested on iOS 26 beta 3.
Topic: UI Frameworks SubTopic: SwiftUI
0
0
70
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
0
0
86
1w
Preview crashes when using ForEach with a Binding to an array and generics
The following repro case results in a previews crash on Xcode 26 beta 3 (report attached). FB18762054 import SwiftUI final class MyItem: Identifiable, Labelled { var label: String init(_ label: String) { self.label = label } } protocol Labelled { var label: String { get } } struct HelloView: View { let label: String var body: some View { Text(label) } } struct ListView<Element: Labelled & Identifiable>: View { @Binding var elements: [Element] var body: some View { List { ForEach($elements, id: \.id) { $element in HelloView(label: element.label) // crash // Replacing the above with a predefined view works correctly // Text(element.label) } } } } struct ForEachBindingRepro: View { @State var elements: [MyItem] = [ MyItem("hello"), MyItem("world"), ] var body: some View { ListView(elements: $elements) } } #Preview("ForEachBindingRepro") { ForEachBindingRepro() } foreachbindingrepro-2025-07-12-020628.ips
6
0
137
1w
SwiftUI .toolbar(.keyboard) Not Showing on First Appearance in fullScreenCover (iOS 18)
I’m encountering an issue in iOS 18.5 (and most probably across all iOS 18 versions) where the keyboard toolbar defined with .toolbar(.keyboard) does not appear immediately when a TextField becomes first responder inside a fullScreenCover. Here’s a minimal reproducible example: import SwiftUI struct ContentView: View { @State private var text: String = "" @State private var showSheet: Bool = false var body: some View { NavigationStack { Button("Show Sheet") { showSheet.toggle() } .fullScreenCover(isPresented: $showSheet) { NavigationStack { VStack { Button("Dismiss") { showSheet.toggle() } TextField("Enter text", text: .constant("Hello")) .autocorrectionDisabled() .textInputAutocapitalization(.never) } .padding() .toolbar { ToolbarItemGroup(placement: .keyboard) { toolBar } } } } } } private var toolBar: some View { HStack { Spacer() Button("Done") { UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) } } } } ✅ Expected Behavior: When the TextField becomes active and the keyboard appears, the custom keyboard toolbar with a “Done” button should also appear immediately. ❌ Actual Behavior: On first presentation of the sheet and focusing the TextField, the toolbar is missing. If I background the app and return, the toolbar appears as expected. Dismissing and re-opening the sheet leads to the same issue (toolbar missing again).
Topic: UI Frameworks SubTopic: SwiftUI
2
0
68
1w
Make a grid of `TextField`s in SwiftUI
Code that reproduces the issue import SwiftUI @main struct TextFieldsGridApp: App { @State private var controller = Controller() var body: some Scene { WindowGroup { GridView() .environment(controller) } } } struct GridView: View { @Environment(Controller.self) private var c var body: some View { VStack { ForEach(0..<c.strings.count, id: \.self) { r in HStack { ForEach(0..<4, id: \.self) { c in TextField( "", text: c.strings[r][c] ) .textFieldStyle(.roundedBorder) } } } } .padding() } } #Preview { GridView() .environment(Controller()) } @Observable class Controller { private(set) var strings: [[String]] = Array( repeating: Array(repeating: "A", count: 4), count: 4, ) } Error Cannot convert value of type 'Range<Int>' to expected argument type 'Binding<C>', caused by ForEach(0..<4, id: \.self) { c in. Which I do not get if I say, for example: struct GridView: View { @State private var text = "H" // ... TextField("", text: $text) Environment MacBook Air M1 8GB iOS Sequoia 15.5 Xcode 16.4 Preview: iPhone 16 Pro, iOS 18.5.
Topic: UI Frameworks SubTopic: SwiftUI
1
0
81
1w
PhaseAnimator without transition between phases
PhaseAnimator seems a good fit to play gifs in SwiftUI: struct ContentView: View { let frames = [UIImage(named: "frame-1")!, UIImage(named: "frame-2")!] var body: some View { PhaseAnimator(frames.indices) { index in Image(uiImage: frames[index]) } } } The problem is that by default, there's an opacity transition between phases. So I tried using transition(.identity): Image(uiImage: gif[index]) .transition(.identity) .id(index) It doesn't work. It stays frozen on the first frame. It does work if I set the transition to a small offset value: Image(uiImage: gif[index]) .transition(.offset(x: 0, y: 0.1)) .id(index) It does feel a bit hacky, though. Is this the expected behavior for .transition(.identity), or is it a bug?
1
0
76
1w
Different toolbar item placement for iPhone vs iPad
On iPhone, I would like to have a more button at the top right of the navigation bar, a search field in the bottom toolbar, and a plus button to the right of the search field. I've achieved this via the code below. But on iPad they should be in the navigation bar at the trailing edge from left to right: plus, more, search field. Just like the Shortcuts app, if there's not enough horizontal space, the search field should collapse into a button, and with even smaller space the search bar should become full-width under the navigation bar. Right now on iPad the search bar is full width under the navigation bar, more at top right, plus at bottom middle, no matter how big the window is. How can I achieve that? Any way to specify them for the system to more automatically do the right thing, or would I need to check specifically for iPhone vs iPad UIDevice to change the code? struct ContentView: View { @State private var searchText = "" var body: some View { NavigationStack { VStack { Text("Hello, world!") } .navigationTitle("Test App") .searchable(text: $searchText) .toolbar { ToolbarItem { Menu { //... } label: { Label("More", systemImage: "ellipsis") } } DefaultToolbarItem(kind: .search, placement: .bottomBar) ToolbarSpacer(.fixed, placement: .bottomBar) ToolbarItem(placement: .bottomBar) { Button { print("Add tapped") } label: { Label("Add", systemImage: "plus") } } } } } }
2
0
58
1w
UISearchBar .minimal no background when compiled on Xcode 26
When compiled on Xcode 16.4.0: When compiled on Xcode 26: The code: import SwiftUI struct SearchBarController: UIViewRepresentable { @Binding var text: String var placeholderText: String class Coordinator: NSObject, UISearchBarDelegate { @Binding var text: String init(text: Binding<String>) { _text = text } func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { text = searchText } } func makeUIView(context: Context) -> UISearchBar { let searchBar = UISearchBar(frame: .zero) searchBar.delegate = context.coordinator searchBar.placeholder = placeholderText searchBar.searchBarStyle = .minimal return searchBar } func updateUIView(_ uiView: UISearchBar, context: Context) { uiView.text = text } func makeCoordinator() -> SearchBarController.Coordinator { return Coordinator(text: $text) } }
2
0
52
1w
How to hide scroll edge effect until scroll down
I present a view in a sheet that consists of a navigation stack and a scroll view which has a photo pushed to the top by setting .ignoresSafeArea(edges: .top). The problem is the top of the photo is blurry due to the scroll edge effect. I would like to hide the scroll edge effect so the photo is fully visible when scrolled to the top but let the effect become visible upon scrolling down. Is that possible? struct ContentView: View { @State private var showingSheet = false var body: some View { VStack { Button("Present Sheet") { showingSheet = true } } .sheet(isPresented: $showingSheet) { SheetView() } } } struct SheetView: View { @Environment(\.dismiss) private var dismiss var body: some View { NavigationStack { ScrollView { VStack { Image("Photo") .resizable() .scaledToFill() } } .ignoresSafeArea(edges: .top) .toolbar { ToolbarItem(placement: .cancellationAction) { Button(role: .close) { dismiss() } } ToolbarItem { EditButton() } } } } }
1
0
68
1w
fullscreencover Problem
Hello Apple Developer Community: I have a problem with the fullscreencover. I can see the Things, that shouldn’t be visible behind it. I’m currently developing with iOS 26 and only there it happens. I hope you can help me :) Have a nice day
1
3
42
1w
Dynamic Presentation Sheet Heights
In my application, I have NavigationStack presented as a sheet, and I intend to dynamically adjust its height while pushing views within it. I'm utilizing a global observable variable to manage the height and everything works fine except that the height changes abruptly without any animation. It abruptly transitions from one height to another. The issue can be reproduced using the following code: #Preview { @Previewable @State var height: CGFloat = 200 Text("Parent View") .sheet(isPresented: .constant(true)) { NavigationStack { Form { NavigationLink("Button") { RoundedRectangle(cornerRadius: 20) .fill(Color.blue) .frame(height: 200) .navigationTitle("Child") .onAppear { withAnimation { height = 300 } } } } .navigationTitle("Parent") .navigationBarTitleDisplayMode(.inline) .presentationDetents([.height(height)]) .onAppear { withAnimation { height = 150 } } } } }
3
0
76
1w
Looking for a mechanism in iPadOS 26 to 'split a window' into two adjacent windows like it worked in iPadOS 18.
With the new multi-windowing design in iPadOS 26, the behavior of openWindow() has changed. In iPadOS 18, if I called openWindow(), I would go from a full-screen window to two side-by-side windows. That allowed my app to meet the goal of the user; keep some information on the screen while being able to navigate through the app in the other window. In iPadOS 26 (beta 3), this no longer works. Instead, a new Window opens ON top of the current window. I am looking for some mechanism to help the user see that two windows are now present and then easily move them on the screen (tiled, side-by-side) or whatever else they would prefer.
1
0
45
1w
Webkit dynamic linking failing on iPadOS 26 beta 3
I am using XCODE-BETA (Version 26.0 beta (17A5241e)) on a Mac (running Sequoia 15.5) to develop an app using FoundationModel. I am testing on an iPad (iPad Pro 11 in, 2nd Gen, running iPadOS 26 Beta 3). My app works fine when I run it in the simulator (iPad 26.0). So I upgraded my iPad Pro to iPadOS 26 beta 3 to try it on a real device. When I run it on the device, I get an error about symbols not found. [See details below] Any idea what I need to change in my development configuration to allow me to run/test my app on a real device running iPadOS 26 beta 3? Thanks in advance, Charlie dyld[1132]: Symbol not found: _$s6WebKit0A4PageC4loadyAC12NavigationIDVSg10Foundation10URLRequestVF Referenced from: <65E40738-6E3A-3F65-B39F-9FD9A695763C> /private/var/containers/Bundle/Application/34F9D5CE-3E54-4312-8574-10B506C713FA/Blossom.app/Blossom.debug.dylib Expected in: /System/Library/Frameworks/WebKit.framework/WebKit Symbol not found: _$s6WebKit0A4PageC4loadyAC12NavigationIDVSg10Foundation10URLRequestVF Referenced from: <65E40738-6E3A-3F65-B39F-9FD9A695763C> /private/var/containers/Bundle/Application/34F9D5CE-3E54-4312-8574-10B506C713FA/Blossom.app/Blossom.debug.dylib Expected in: /System/Library/Frameworks/WebKit.framework/WebKit dyld config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/usr/lib/libLogRedirect.dylib:/usr/lib/libBacktraceRecording.dylib:/usr/lib/libMainThreadChecker.dylib:/usr/lib/libRPAC.dylib:/usr/lib/libViewDebuggerSupport.dylib Symbol not found: _$s6WebKit0A4PageC4loadyAC12NavigationIDVSg10Foundation10URLRequestVF Referenced from: <65E40738-6E3A-3F65-B39F-9FD9A695763C> /private/var/containers/Bundle/Application/34F9D5CE-3E54-4312-8574-10B506C713FA/Blossom.app/Blossom.debug.dylib Expected in: /System/Library/Frameworks/WebKit.framework/WebKit dyld config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/usr/lib/libLogRedirect.dylib:/usr/lib/libBacktraceRecording.dylib:/usr/lib/libMainThreadChecker.dylib:/usr/lib/libRPAC.dylib:/usr/lib/libViewDebuggerSupport.dylib
1
0
84
1w
How to scale a SwiftUI view to fit its parent
Code that reproduces the issue import SwiftUI @main struct KeyboardLayoutProblemApp: App { var body: some Scene { WindowGroup { iOSTabView() } } } struct iOSTabView: View { var body: some View { TabView { GameView() .frame(maxWidth: UIScreen.main.bounds.width, maxHeight: UIScreen.main.bounds.height) .tabItem { Label("Play", systemImage: "gamecontroller.fill") } } } } struct GameView: View { var body: some View { VStack { Text("Play") Spacer() KeyboardView() } .padding() } } struct KeyboardView: View { let firstRowLetters = "qwertyuiop".map { $0 } let secondRowLetters = "asdfghjkl".map { $0 } let thirdRowLetters = "zxcvbnm".map { $0 } var body: some View { VStack { HStack { ForEach(firstRowLetters, id: \.self) { LetterKeyView(character: $0) } } HStack { ForEach(secondRowLetters, id: \.self) { LetterKeyView(character: $0) } } HStack { ForEach(thirdRowLetters, id: \.self) { LetterKeyView(character: $0) } } } .padding() } } struct LetterKeyView: View { let character: Character var width: CGFloat { height*0.8 } @ScaledMetric(relativeTo: .title3) private var height = 35 var body: some View { Button { print("\(character) pressed") } label: { Text(String(character).capitalized) .font(.title3) .frame(width: self.width, height: self.height) .background { RoundedRectangle(cornerRadius: min(width, height)/4, style: .continuous) .stroke(.gray) } } .buttonStyle(PlainButtonStyle()) } } Problem GameView doesn't fit its parent view: Question How do I make GameView be at most as big as its parent view? What I've tried and didn't work GameView() .frame(maxWidth: .infinity, maxHeight: .infinity) GeometryReader { geometry in GameView() .frame(maxWidth: geometry.size.width, maxHeight: geometry.size.height) } GameView() .clipped() GameView() .layoutPriority(1) GameView() .scaledToFit() GameView() .minimumScaleFactor(0.01) GameView() .scaledToFill() .minimumScaleFactor(0.5) I'm not using UIScreen.main.bounds.width because I'm trying to build a multi-platform app.
Topic: UI Frameworks SubTopic: SwiftUI
0
0
51
1w