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

Blurred selected button on tvOS
The following code shows that a selected button in a list gots blurred if a glass effect is applied to the list. This happens if the button style is plain or glass. It does not happen if the button style is bordered. Is this a wanted documented behavior or is this a bug? struct ContentView: View { @State private var items = [ "Item 1", "Item 2", "Item 3", "Item 4"] var body: some View { ZStack { Image(systemName: "globe") .resizable() List(items, id: \.self) { item in Button(action: {}, label: { Text(item) }) } .padding() .glassEffect(in: Rectangle()) } } }
2
0
51
3d
Text with Liquid Glass effect
I'm looking for a way to implement Liquid Glass effect in a Text, and I have issues. If I want to do gradient effect in a Text, no problem, like below. Text("Liquid Glass") .font(Font.system(size: 30, weight: .bold)) .multilineTextAlignment(.center) .foregroundStyle( LinearGradient( colors: [.blue, .mint, .green], startPoint: .leading, endPoint: .trailing ) ) But I cannot make sure that I can apply the .glassEffect with .mask or .foregroundStyle. The Glass type and Shape type argument looks like not compatible with the Text shape itself. Any solution to do this effect on Text ? Thanks in advance for your answers.
0
0
153
3d
List reordering animation broken in iOS 26
just opened a iOS18 project in latest Xcode 26 (beta 7) and the list reordering animation is broken and jerky. on iOS 18 a change to one of the list items would smoothly move it to its correct place but in iOS 26 the items jerk around, disappear then pop up in the correct order in the list. I am using this to filter and sort the "events" if searchQuery.isEmpty { return events.sort(on: selectedSortOption) } else { let filteredEvents = events.compactMap { event in // Check if the event title contains the search query (case-insensitive). let titleContainsQuery = event.title.range(of: searchQuery, options: .caseInsensitive) != nil return titleContainsQuery ? event : nil } return filteredEvents.sort(on: selectedSortOption) } } is there a better way for iOS 26?
Topic: UI Frameworks SubTopic: SwiftUI
0
0
152
3d
Menu's primaryAction:{} is broken on latest iOS 26 beta
The following shows minimal example to reproduce the issue: Menu { Button("Test"){} } label: { Text("Menu") } primaryAction: { // Some action } primaryAction modifier will not be called when pressing the menu button/view on iOS 26 beta, long pressing it will open the menu. Was tested on latest iOS 26 beta 8
Topic: UI Frameworks SubTopic: SwiftUI
3
0
152
3d
Liquid Glass clear variant isn't clear
I've been experimenting with Liquid Glass quite a bit and watched all the WWDC videos. I'm trying to create a glassy segmented picker, like the one used in Camera: however, it seems that no matter what I do there's no way to recreate a truly clear (passthrough) bubble that just warps the light underneath around the edges. Both Glass.regular and Glass.clear seem to add a blur that can not be evaded, which is counter to what clear ought to mean. Here are my results: I've used SwiftUI for my experiment but I went through the UIKit APIs and there doesn't seem to be anything that suggests full transparency. Here is my test SwiftUI code: struct GlassPicker: View { @State private var selected: Int? var body: some View { ScrollView([.horizontal], showsIndicators: false) { HStack(spacing: 0) { ForEach(0..<20) { i in Text("Row \(i)") .id(i) .padding() } } .scrollTargetLayout() } .contentMargins(.horizontal, 161) .scrollTargetBehavior(.viewAligned) .scrollPosition(id: $selected, anchor: .center) .background(.foreground.opacity(0.2)) .clipShape(.capsule) .overlay { DefaultGlassEffectShape() .fill(.clear) // Removes a semi-transparent foreground fill .frame(width: 110, height: 50) .glassEffect(.clear) } } } Is there any way to achieve the above result or does Apple not trust us devs with more granular control over these liquid glass elements?
2
3
82
4d
SwiftUI TextField with optional value working for @State but not @Binding properties
I've encountered a potential bug where a TextField connected to an optional value (not a string) works as expected when bound to a @State property, but won't update a @Binding property. Here is some example code import SwiftUI struct ContentView: View { @Binding var boundValue: Double? @State private var stateValue: Double? = 55 var body: some View { TextField("Bound value", value: $boundValue, format: .number) Text("\(boundValue ?? .nan)") TextField("State value", value: $stateValue, format: .number) Text("\(stateValue ?? .nan)") } } #Preview { ContentView(boundValue: .constant(42.00)) } It's as though the optional value stored externally is preventing the value updating. Can anyone confirm whether this is intentional, or a bug? This is in Xcode 26b6, on macOS Tahoe 26b8, but from this query it looks like the problem has existed for years.
Topic: UI Frameworks SubTopic: SwiftUI
8
0
310
4d
Inconsistent subviews redrawing in LazyVStack
Hello Apple forum ! I spotted a weird behaviour with LazyVStack in a ScrollView. I understand that it loads its views only once upon appearance unlinke VStack that loads everything in one shot. What I noticed also, it seems to reload its views sometimes when scrolling back up to earlier loaded views. The thing is, it isn't always the case. struct LazyVStackTest: View { var body: some View { ScrollView { LazyVStack { ForEach(0..<1000, id: \.self) { _ in // if true { MyText() // } } } } } struct MyText: View { var body: some View { let _ = Self._printChanges() HStack { Text("hello") } } } } If we consider the code above on XCode 26 beta 7 on an iOS 26 or iOS 18.2 simulator. Scroll to the bottom : you'll see one "LazyVStackTest.MyText: @self changed" for each row. Then scroll back up to the top, we'll see again the same message printed multiple times. --> So I gather from this that LazyVStack not only loads lazily but also removes old rows from memory & recreates them upon reappearance. What I don't get however is that if you uncomment the "if true" statement, you won't see the reloading happening. And I have absolutely no clue as to why 😅 If someone could help shed some light on this weird behaviour, it would be greatly appreciated ^^ PS : the issue is also present with XCode 16.2 but at a deeper lever (ex: if we embed another custom View "MyText2" inside "MyText", the reloading is in "MyText2" & not "MyText")
0
0
130
4d
iOS 26 Beta - AppStore.showManageSubscriptions() Shows Empty View Before StoreKit Sheet
Environment iOS Version: iOS 26 Beta 8 Xcode Version: iOS 26 Beta 6 StoreKit: StoreKit 2 Description When calling AppStore.showManageSubscriptions(in:) on iOS 26 beta, I'm experiencing an unusual presentation behavior that wasn't present in earlier versions. An empty/blank view appears first Then the actual StoreKit manage subscriptions sheet appears on top When dismissing the StoreKit sheet, it closes properly But then I have to dismiss the empty view underneath as well This creates a poor user experience showing double sheets. Code Sample @MainActor func showManageSubscriptions() { guard let scene = UIApplication.shared.connectedScenes .first(where: { $0 is UIWindowScene }) as? UIWindowScene else { return } Task { do { try await AppStore.showManageSubscriptions(in: scene) } catch { // Handle error } } } Expected Behavior The StoreKit manage subscriptions sheet should present directly without any intermediate empty view, as it did in previous iOS versions. Actual Behavior An empty view layer appears between my app and the StoreKit sheet, requiring users to dismiss twice. Questions Is anyone else experiencing this issue with iOS 26 beta? Is this a known beta issue that will be addressed? Are there any recommended workarounds while waiting for a fix?
3
0
21
4d
iOS 26 (beta 7) setting .searchFocused programmatically does not work
Already filed a feedback in case this is a bug, but posting here in case I'm doing something wrong? I'd like the search field to automatically be displayed with the keyboard up when the view appears. This sample code works in iOS 18, but it does not work in iOS 26 beta 7 I also tried adding a delay to setting searchIsFocused = true but that did not help struct ContentView: View { var body: some View { NavigationStack { NavigationLink(destination: ListView()) { Label("Go to list", systemImage: "list.bullet") } } .ignoresSafeArea() } } struct ListView: View { @State private var searchText: String = "" @State private var searchIsPresented: Bool = false @FocusState private var searchIsFocused: Bool var body: some View { ScrollView { Text("Test") } .searchable(text: $searchText, isPresented: $searchIsPresented, placement: .automatic, prompt: "Search") .searchFocused($searchIsFocused) .onAppear { searchIsFocused = true } } }
1
0
45
5d
NavigationStack path is being reset in NavigationSplitView details columns
I'm building a SwiftUI app for iPad using a NavigationSplitView as the navigation root. Below is a simplified version of the app's navigation. There are a Home Page and a Settings Page, each with its own NavigationStack. The page that appears in the detail column depends on the sidebar's selection value. The issue I'm facing is that when I navigate deeply into the Home Page's NavigationStack (e.g., to a Home Page Child view), switch to the Settings Page, and then switch back to the Home Page, the Home Page's navigation path has been reset to [] and the previous state is lost. The same issue occurs if I navigate deeply into the Settings Page (e.g., to a Settings Page Child view), switch to the Home Page, and then return to the Settings Page: the navigation state for the Settings Page is lost, and it reverts to the root of the NavigationStack. Why is this happening and how can I fix it so that switching pages in the sidebar doesn't reset the NavigationStack of each individual page in the detail column? Thank you. struct ContentView: View { @State var selection: String? @State var firstPath = [String]() @State var secondPath = [String]() var body: some View { NavigationSplitView { List(selection: $selection) { Text("Home") .tag("home") Text("Settings") .tag("settings") } } detail: { if selection == "home" { HomePage(path: $firstPath) } else { SettingsPage(path: $secondPath) } } } } struct HomePage: View { @Binding var path: [String] var body: some View { NavigationStack(path: $path) { NavigationLink("Home Page", value: "Home") .navigationDestination(for: String.self) { _ in Text("Home Page Child") } } } } struct SettingsPage: View { @Binding var path: [String] var body: some View { NavigationStack(path: $path) { NavigationLink("Settings Page", value: "Settings") .navigationDestination(for: String.self) { _ in Text("Settings Page Child") } } } } #Preview { ContentView() }
0
0
225
5d
WebView makes website content unaccessible on the top/bottom edges
I'm being faced with an issue when using SwiftUI's WebView on iOS 26. In many websites, the top/bottom content is unaccessible due to being under the app's toolbars. It feels like the WebView doesn't really understand the safe areas where it's being shown, because the content should start right below the navigation bar, and only when the user scrolls down, the content should move under the bar (but it's always reachable if the users scroll back up). Here's a demo of the issue: Here's a 'fix' by ensuring that the content of the WebView never leaves its bounds. But as you can see, it feels out of place on iOS 26 (would be fine on previous OS versions if you had a fully opaque toolbar): Code: struct ContentView: View { var body: some View { NavigationStack { WebView(url: URL(string: "https://apple.com")).toolbar { ToolbarItem(placement: .primaryAction) { Button("Top content covered, unaccessible.") {} } } } } } Does anyone know if there's a way to fix it using some sort of view modifier combination or it's just broken as-is?
5
1
135
5d
Textfield not updating integer with optional value
I am trying to get integer input by using textfield. However, I noticed that if I changed the binding variable as optional with an initial value of null, the textfield would not work. I would like to keep it as null initially because I want the placeholder to show text before the input, and if the int variable starts with any valid value, the text would not be shown. Is there a way to fix things here? struct TextFieldNumberInputView: View {     @Binding var intVariable: Int?     @State var isEditing: Bool = false     @State var placeholderText: String     @State var number: Int = 0          var body: some View {         VStack(alignment: .leading, spacing: 2){             TextField(placeholderText, value: $number, formatter: NumberFormatter()){             }             .textFieldStyle(InputTextFieldStyle())             .keyboardType(.numberPad)             .onReceive(Just(number)) {_ in                 print("number pad being editing")                 if isEditing == false && intVariable != nil {                                         isEditing = true                     print("number is being edited")                 } else if isEditing == true && intVariable != nil{                     isEditing = false                 }             }                          Text(placeholderText)                 .font(.caption2)                 .foregroundColor(isEditing ? Color(.systemGray3):Color.clear)                 .padding(.horizontal)                 .padding(.horizontal, 12)                  }.onTapGesture {             print("number pad being tapped, intVariable \(intVariable), \(number)")                          if number != nil {                 print("checking number")                 UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to:nil, from:nil, for:nil)             }                      }     }      }
2
0
747
5d
Charts SectorMark causing app to crash
Anytime I have 1 item, then add another, the app crashes with the following error: Swift/IntegerTypes.swift:8835: Fatal error: Double value cannot be converted to Int because it is either infinite or NaN I'm not working with Int values though, so I'm not sure why this is happening. It's also not point me towards any specific line. I've printed out all of the values being used for the chart and none of them are showing as infinite or NaN. The data being used is created in a View. @State private var pieChartData: [PieChartDataPoint] = [] Then in the onAppear and onChange its gets loaded using the following function: func getPieChartDataPoints() -> [PieChartDataPoint] { self.map({ PieChartDataPoint(label: $0.name, value: $0.monthlyAmount()) }) } That's an extension on a SwiftData model type I have called Recurring. @Model final class Recurring { var id = UUID() enum Kind: String, CaseIterable, Codable { case income = "Income" case bill = "Bill" func plural() -> String { switch self { case .income: "Income" case .bill: "Bills" } } } enum Frequency: String, CaseIterable, Codable, Identifiable { var id: Frequency { self } case weekly = "Weekly" case biweekly = "Biweekly" case monthly = "Monthly" case quarterly = "Quarterly" case annually = "Annually" } var name: String = "" var kind: Kind = Kind.income var frequency: Frequency = Frequency.biweekly var amount: Double = 0 init(name: String, kind: Kind, frequency: Frequency, amount: Double) { self.name = name self.kind = kind self.frequency = frequency self.amount = amount } func amount(from cycle: Cycle) -> Double { switch cycle { case .weekly: monthlyAmount() * 12 / 52 case .biweekly: monthlyAmount() * 12 / 26 case .monthly: monthlyAmount() } } func monthlyAmount() -> Double { switch frequency { case .weekly: amount * 52 / 12 case .biweekly: amount * 26 / 12 case .monthly: amount case .quarterly: amount * 4 / 12 case .annually: amount / 12 } } } Here is the DataPoint structure. struct PieChartDataPoint: Identifiable, Equatable { var id = UUID() var label: String var value: Double } Finally here is the chart. Chart(sorted, content: { dataPoint in SectorMark( angle: .value(dataPoint.label, getValue(from: dataPoint)), innerRadius: 50, angularInset: 5 ) .foregroundStyle(by: .value("Label", dataPoint.label)) .cornerRadius(10) .opacity(getSectorMarkOpacity(for: dataPoint)) }) .scaledToFill() .chartLegend(.hidden) .chartAngleSelection(value: $chartSelection) .onChange(of: chartSelection, checkSelection) For testing purposes, I have removed all of the modifiers and only had a simple SectorMark in the Chart, however, that was still crashing. Does anyone know why this is happening?
1
0
52
5d
UtilityWindow can't read @FocusedValue of main scene
According to the UtilityWindow documentation: • They receive FocusedValues from the focused main scene in an application, similar to commands in the main menu, which can be used to display information on the active content as the user focuses on different scenes. This makes me think that any UtilityWindow, even across Scenes, should always receive @FocusedValues from the currently focused window of any scene. However, the following code doesn't quite work: @Observable class Info: Identifiable { let id = UUID() } struct ExampleApp: App { var body: some Scene { WindowGroup { ContentView() // Inside, it uses .focusedSceneValue(info) } UtilityWindow("Test") { UtilityWindowContent() } } } struct UtilityWindowContent: View { @FocusedValue(Info.self) var info var body: some View { Text(info?.id ?? "<nil>") // This always shows "<nil>" } } Here's some annotated screenshots of what's happening in a project: Menu bar commands do work with the same setup: As a workaround, attempting to use @FocusedValue in the App struct works, but as a result, the value appears to instantiate multiple times in the background, and they re-instantiate with every focus change. The @FocusedValue variable gets the correct instance, but it's needlessly initializing others in the background. This is on macOS 26.0 Tahoe Beta 8 (25A5349a).
0
0
91
6d
SwiftUI drag & drop: reliable cancellation
Summary In a SwiftUI drag-and-drop flow, the only robust way I’ve found to detect cancellation (user drops outside any destination) is to rely on the NSItemProvider created in .onDrag and run cleanup when it’s deallocated, via a custom onEnded callback tied to its lifecycle. On iOS 26, the provider appears to be deallocated immediately after .onDrag returns (unless I keep a strong reference), so a deinit/onEnded-based cancel hook fires right away and no longer reflects the true end of the drag session. I’d like to know: 1. Is there a supported, reliable way to detect when a drag ends outside any drop target so I can cancel and restore the source row? 2. Is the iOS 26 NSItemProvider deallocation timing a bug/regression or intended behavior? Minimal SwiftUI Repro This example shows: • creating a custom NSItemProvider subclass with an onEnded closure • retaining it to avoid immediate dealloc (behavior change on iOS 26) • using performDrop to mark the drag as finished import SwiftUI import UniformTypeIdentifiers final class DragProvider: NSItemProvider { var onEnded: (() -> Void)? deinit { // Historically: called when the system drag session ended (drop or cancel). // On iOS 26: can fire immediately after .onDrag returns unless the provider is retained. onEnded?() } } struct ContentView: View { struct Item: Identifiable, Equatable { let id = UUID(); let title: String } @State private var pool: [Item] = (1...4).map { .init(title: "Option \($0)") } @State private var picked: [Item] = [] @State private var dragged: Item? @State private var dropFinished: Bool = true @State private var activeProvider: DragProvider? // Retain to avoid immediate dealloc private let dragType: UTType = .plainText var body: some View { HStack(spacing: 24) { // Destination list (accepts drops) VStack(alignment: .leading, spacing: 8) { Text("Picked").bold() VStack(spacing: 8) { ForEach(picked) { item in row(item) } } .padding() .background(RoundedRectangle(cornerRadius: 8).strokeBorder(.quaternary)) .onDrop(of: [dragType], delegate: Dropper( picked: $picked, pool: $pool, dragged: $dragged, dropFinished: $dropFinished, activeProvider: $activeProvider )) } .frame(maxWidth: .infinity, alignment: .topLeading) // Source list (draggable) VStack(alignment: .leading, spacing: 8) { Text("Pool").bold() VStack(spacing: 8) { ForEach(pool) { item in row(item) .onDrag { startDrag(item) return makeProvider(for: item) } preview: { row(item).opacity(0.9).frame(width: 200, height: 44) } .overlay( RoundedRectangle(cornerRadius: 8) .fill(item == dragged ? Color(.systemBackground) : .clear) // keep space ) } } .padding() .background(RoundedRectangle(cornerRadius: 8).strokeBorder(.quaternary)) } .frame(maxWidth: .infinity, alignment: .topLeading) } .padding() } private func row(_ item: Item) -> some View { RoundedRectangle(cornerRadius: 8) .strokeBorder(.secondary) .frame(height: 44) .overlay( HStack { Text(item.title); Spacer(); Image(systemName: "line.3.horizontal") } .padding(.horizontal, 12) ) } // MARK: Drag setup private func startDrag(_ item: Item) { dragged = item dropFinished = false } private func makeProvider(for item: Item) -> NSItemProvider { let provider = DragProvider(object: item.id.uuidString as NSString) // NOTE: If we DO NOT retain this provider on iOS 26, // its deinit can run immediately (onEnded fires too early). activeProvider = provider provider.onEnded = { [weak self] in // Intended: run when system drag session ends (drop or cancel). // Observed on iOS 26: may run too early unless retained; // if retained, we lose a reliable "session ended" signal here. DispatchQueue.main.async { guard let self else { return } if let d = self.dragged, self.dropFinished == false { // Treat as cancel: restore the source item if !self.pool.contains(d) { self.pool.append(d) } self.picked.removeAll { $0 == d } } self.dragged = nil self.dropFinished = true self.activeProvider = nil } } return provider } // MARK: DropDelegate private struct Dropper: DropDelegate { @Binding var picked: [Item] @Binding var pool: [Item] @Binding var dragged: Item? @Binding var dropFinished: Bool @Binding var activeProvider: DragProvider? func validateDrop(info: DropInfo) -> Bool { dragged != nil } func performDrop(info: DropInfo) -> Bool { guard let item = dragged else { return false } if let idx = pool.firstIndex(of: item) { pool.remove(at: idx) } picked.append(item) // Mark drag as finished so provider.onEnded won’t treat it as cancel dropFinished = true dragged = nil activeProvider = nil return true } } } Questions Is there a documented, source-side callback (or best practice) to know the drag session ended without any performDrop so we can cancel and restore the item? Has the NSItemProvider deallocation timing (for the object returned from .onDrag) changed intentionally on iOS 26? If so, what’s the recommended replacement signal? Is there a SwiftUI-native event to observe the end of a drag session that doesn’t depend on the provider’s lifecycle?
0
1
77
6d
PasteButton asks for permissions every time
Hi, i'm using the PasteButton component to paste content from clipboard. On the docs it says that the PasteButton will handle internally permissions and will not present the prompt. But in my case seems to be not true. I removed all the occurrencies of UIPasteboard.general.string since i read that this will cause the prompt to appear. Also as you can see on the code below i'm not doing fancy or weird things, even with the base component this behaviour is still there. PasteButton(payloadType: String.self) { strings in if let first = strings.first { print("clipboard text: \(first)") } } I can see other apps using this paste button without asking for permissions every time, but i cannot see any issue in my code.
0
0
12
6d
SwiftUI app crash with __swift_instantiateConcreteTypeFromMangledName
Hello, I am experiencing a crash in a SwiftUI app. It happens when I place multiple views inside a ScrollView. The crash occurs only on a physical device (it does not reproduce in the Simulator). It happens during runtime, seemingly while SwiftUI is updating or laying out the view hierarchy. I have not been able to determine the exact cause. I am attaching a text file with the entire backtrace from LLDB. swiftui_crash_backtrace Is this a known SwiftUI issue? Any recommendations on how to further investigate or work around it? Any help or suggestions would be appreciated. Xcode 16.3 / iOS 18.6.2 Thank you!
1
0
81
6d
Keyboard dismissal not animated
Hello, I’ve encountered what seems to be a bug with the keyboard dismissal animation on iOS 26.0 Beta (25A5349a), Xcode Version 26.0 beta 5 (17A5295f). When dismissing the keyboard from a SwiftUI TextField using @FocusState, the keyboard does not animate downward as expected. Instead, it instantly disappears, which feels jarring and inconsistent with system behavior. I am attaching a short video demonstrating the issue. Below is the minimal reproducible code sample: // // ContentView.swift // TestingKeyboardDismissal // // Created by Sasha Morozov on 27/08/25. // import SwiftUI struct ContentView: View { @State private var text: String = "" @FocusState private var isFocused: Bool var body: some View { ZStack { Color.clear.ignoresSafeArea() VStack(spacing: 20) { TextField("Enter text here...", text: $text) .textFieldStyle(.roundedBorder) .focused($isFocused) .padding(.horizontal) HStack { Button("Focus") { isFocused = true } .buttonStyle(.borderedProminent) Button("Unfocus") { isFocused = false } .buttonStyle(.bordered) } } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) .padding() } .ignoresSafeArea(.keyboard, edges: .bottom) } } #Preview { ContentView() } Steps to reproduce: Run** the app on iOS 26.0 beta 5 (17A5295f). Tap Focus → keyboard appears as expected. Tap Unfocus → keyboard disappears instantly without the usual slide-down animation. Expected result: Keyboard should animate smoothly downwards when dismissed. Actual result: Keyboard instantly vanishes without animation. p.s. we should be really able to upload videos here for demostration
2
1
106
6d
The new navigationLinkIndicatorVisibility modifier crashes on < iOS 26
This new modifier is supposedly backported to iOS 17, but on attempting to use it on the latest iOS 18.5, this happens: Symbol not found: _$s7SwiftUI17EnvironmentValuesV33_navigationIndicatorVisibilityABIAA0G0OvpMV This happens with any usage of the modifier. An availability check won't save you either. The cruelest part of this is that I only need the modifier on iOS 26, lmao. Am I just missing something?
Topic: UI Frameworks SubTopic: SwiftUI
6
0
153
6d