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

Posts under SwiftUI tag

200 Posts

Post

Replies

Boosts

Views

Activity

Crash while presenting popover on toolbar item in MacCatalyst app
struct ContentView: View { @State private var showingPopover:Bool = false private var popOverHeight: CGFloat { return 566 } var body: some View { NavigationStack { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") } .padding() .toolbar { ToolbarItem(placement: .topBarTrailing) { Button { showingPopover = true } label: { Image(systemName: "plus") .font(Font.system(size: 15)) .foregroundColor(Color.red) } .popover(isPresented: $showingPopover) { FTShelfNewNotePopoverView1() .frame(minWidth: 340.0) .frame(height: popOverHeight) } } } } } }
0
0
194
1w
How can I optimize multilingual string translations in SwiftUI for App Store apps using Localization APIs?
Hi team, I’m developing an iOS app that helps manage and translate multilingual content . The app uses SwiftUI with Localizable.strings and Bundle.localizedString(forKey:). I’m trying to optimize for dynamic language switching inside the app without restarting. I’ve tested various methods like: Text(NSLocalizedString("welcome_text", comment: "")) and some approaches using @Environment(.locale), but the system doesn’t always update views instantly when language changes. Question: What’s the recommended approach (or WWDC reference) for real-time language change handling in SwiftUI apps targeting iOS 18+?
1
0
103
1w
How to display SegmentControl in tabViewBottomAccessory inline mode like iOS 26 Photos app?
Question I'm trying to replicate the iOS 26 Photos app behavior where a segmented control appears in the tab bar area when scrolling. Specifically, when the tab bar minimizes to inline mode, I want to show a Picker with .segmented style between the minimized tab button and search button. Expected Behavior (iOS 26 Photos App) When scrolling up in the Photos app: Tab bar minimizes to inline mode A segmented control (Years/Months/All) appears in the center Layout: [Tab Button] [Segmented Control] [Search Button] Current Implementation I'm using tabViewBottomAccessory with tabBarMinimizeBehavior: struct PhotosMainView: View { @Environment(ModelData.self) private var modelData @State private var searchText: String = "" var body: some View { @Bindable var modelData = modelData TabView { Tab("Library", systemImage: "photo.on.rectangle") { NavigationStack { PhotosGridView() .navigationTitle("Library") } } Tab("Albums", systemImage: "square.grid.2x2") { NavigationStack { AlbumsGridView() .navigationTitle("Albums") } } Tab("Search", systemImage: "magnifyingglass", role: .search) { NavigationStack { PhotosGridView() .navigationTitle("Search") .searchable(text: $searchText) } } } .tabBarMinimizeBehavior(.onScrollUp) .tabViewBottomAccessory { TimelineAccessoryView() .environment(modelData) } } } struct TimelineAccessoryView: View { @Environment(ModelData.self) private var modelData @Environment(\.tabViewBottomAccessoryPlacement) var placement var body: some View { Group { if let placement = placement { switch placement { case .inline: inlineView case .expanded: expandedView } } } } @ViewBuilder private var inlineView: some View { @Bindable var modelData = modelData Picker("View", selection: $modelData.timelineFilter) { Text("Years").tag(TimelineFilter.year) Text("Months").tag(TimelineFilter.month) Text("All").tag(TimelineFilter.all) } .pickerStyle(.segmented) .frame(maxWidth: 200) } @ViewBuilder private var expandedView: some View { Text("Expanded state") } } Issues Encountered 1. Console logs show placement changes correctly: placement: nil → expanded → inline 2. However, the segmented control doesn't appear visually in inline mode - The accessory view seems to render, but nothing is visible on screen - Only a small empty space appears where the control should be 3. AttributeGraph cycle warnings appear: === AttributeGraph: cycle detected through attribute 27160 === === AttributeGraph: cycle detected through attribute 26304 === What I've Tried 1. ✅ Separating inline/expanded views into @ViewBuilder properties to avoid cycles 2. ✅ Using .onAppear and .onChange for debugging instead of direct prints in body 3. ✅ Confirming placement environment value changes correctly 4. ❌ The segmented control still doesn't display in inline mode Questions 1. Is tabViewBottomAccessory the correct API to achieve this Photos app effect? 2. How should content be structured in .inline placement to display properly between tab button and search? 3. Are there additional modifiers or constraints needed for inline accessories? 4. Is there documentation or sample code showing this pattern? Environment - Xcode 17.0 - iOS 26.0 - iPhone 16 Simulator - SwiftUI Any guidance on the correct approach to implement this would be greatly appreciated. Thank you!
1
0
154
1w
Fous, FocusState and Architecture
I am currently struggling with resolving what appear to be competing design issues, and (while I may be just demonstrating my own ignorance) I would like to share my thoughts in the hope that you may have useful insights. For purposes of discussion, consider a large and complex data entry screen with multiple sections for input. For all of the usual reasons (such as reuse, performance management, etc) each of these sections is implemented as its own, separately-compiled View. The screen is, then, composed of a sequence of reusable components. However, each of these components has internal structure and may contain multiple focusable elements (and internal use of .onKeyPress(.tab) {...} to navigate internally). And the logic of each component is such that it has an internal @FocusState variable defined with its own unique type. So, obviously what I want is on the one hand, to provide a tab-based navigation scheme for the screen as a whole, where focus moves smoothly from one component's internals to the next component, and on the other hand ,to build components that don't know anything about each other and have no cross-component dependencies, so that they can be freely reused in different situations. And that's where I'm stuck. Since focus state variables for different components can have different types, a single over-arching FocusState passed (as a binding) to each component doesn't seem possible or workable. But I don't know how else to approach this issue. (Note: in UIKit, I've done things like this by direct manipulation of the Responder Chain, but I don't see how to apply this type of thinking to SwiftUI.) Thoughts?
3
0
134
1w
iOS 26: Navigation bar unexpectedly switches to Light appearance during navigation in Dark Mode
Summary On iOS 26, the navigation bar unexpectedly switches to a Light appearance during/after a view transition while the device/app is in Dark Mode. This seems correlated with applying listStyle(.plain) to a List. Removing .plain prevents the issue, but my app’s layout requires it. Sample code: import SwiftUI @main struct iOS26NavigationTitleSampleApp: App { var body: some Scene { WindowGroup { NavigationStack { ContentView() .navigationTitle("Root") .navigationBarTitleDisplayMode(.inline) } } } } struct ContentView: View { var body: some View { VStack { NavigationLink { ListView() } label: { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") } } } .padding() .toolbar { ToolbarItemGroup(placement: .navigation) { Button("Test") { } Button("Test2") { } } } } } struct ListView: View { var items: [Int] = Array(0..<100) var body: some View { List { ForEach(items.indices, id: \.self) { idx in cell(items[idx]) } } .listStyle(.plain) .toolbar { ToolbarItemGroup(placement: .navigation) { Button("Test") { } Button("Test2") { } } } .navigationTitle("TTT") } private func cell(_ item: Int) -> some View { Text("\(item)") } } Steps to Reproduce: Set the device to Dark Mode. Launch the sample app. → The root view’s navigation bar is in Dark appearance (as expected). Tap “Hello World” to navigate. → On the destination view, the navigation bar becomes Light. Navigate back to the root view. → The root view’s navigation bar now also remains Light. Expected Result The navigation bar should consistently retain the Dark appearance throughout navigation. Notes Removing listStyle(.plain) stops the issue (navigation bar stays Dark). Simulator: Could not reproduce on iOS Simulator. Devices: Reproducible on physical device. Environment Device: iPhone 15 Plus OS: iOS 26 (23A341) Xcode: 26.0 (17A324)
5
0
332
1w
List's shadow flickering
When Home tab opened, there is some white shadow on the bottom and the top sides of the list. But when switching to other tab or return to Home tab this shadow disappearing for a second and appearing again. Actual for iOS 26.0.1 on simulator and on real device. Below is short example code that can reproduce issue. When change let pages = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal) to let pages = UIPageViewController(transitionStyle: .pageCurl, navigationOrientation: .horizontal) issue is not reproduced. import SwiftUI @main struct GlassTestApp: App { var body: some Scene { WindowGroup { MainView() .ignoresSafeArea() } } } struct MainView: UIViewControllerRepresentable { func makeUIViewController(context: Context) -> UITabBarController { let controller = UITabBarController() let home = Home() home.tabBarItem = UITabBarItem(title: "Home", image: UIImage(systemName: "house"), tag: 1) let settings = UIHostingController(rootView: Settings()) settings.tabBarItem = UITabBarItem(title: "Settings", image: UIImage(systemName: "gearshape"), tag: 2) controller.viewControllers = [home, settings] return controller } func updateUIViewController(_ uiViewController: UITabBarController, context: Context) { } } class Home: UINavigationController { init() { let pages = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal) pages.setViewControllers([UIHostingController(rootView: Page1())], direction: .forward, animated: false) super.init(rootViewController: pages) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } struct Page1: View { var body: some View { List { ForEach(1...100, id: \.self) { Text("\($0)") } } .listStyle(.plain) } } struct Settings: View { var body: some View { Text("Settings") } }
4
0
224
1w
Zoom navigation causes the source view to disappear
After returning from the child view to the parent, the latter one will simply disappear. This is the full view. See itemsContent where I perform the navigation. The last tapped rectangle in this example will simply disappear. struct DashboardView: View { @State var viewModel: DahsboardViewModel @Namespace private var namespace var body: some View { ScrollView(.vertical) { LazyVStack(spacing: 24) { ForEach(viewModel.sections) { section in VStack(spacing: 16) { Text(section.title) itemsContent(for: section) } } } } } func itemsContent(for section: DashboardSection) -> some View { ForEach(section.items) { item in NavigationLink { PatternLearningRouter().rootView .id(item.id) .navigationTransition(.zoom(sourceID: item.id, in: namespace)) } label: { Rectangle() .fill(Color.yellow) .frame(width: 80, height: 80) .overlay { Text(item.title) } .matchedTransitionSource(id: item.id, in: namespace) } } } } XCode26 26.0.1(17A400) iPhone 16 Pro, iOS 26.0.1 Note: Only reproduced when I swipe back (not reproducing it when using back button) Only reproduced on real device not simulator I
0
0
49
1w
I don't want black background in presented sheet
I want a different color, one from my asset catalog, as the background of my first ever swift UI view (and, well, swift, the rest of the app is still obj.c) I've tried putting the color everywhere, but it does't take. I tried with just .red, too to make sure it wasn't me. Does anyone know where I can put a color call that will actually run? Black looks very out of place in my happy app. I spent a lot of time making a custom dark palette. TIA KT @State private var viewModel = ViewModel() @State private var showAddSheet = false var body: some View { ZStack { Color.myCuteBg .ignoresSafeArea(.all) NavigationStack { content .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .principal) { Image("cute.image") .font(.system(size: 30)) .foregroundColor(.beigeTitle) } } } .background(Color.myCuteBg) .presentationBackground(.myCuteBg) .sheet(isPresented: $showAddSheet) { AddView() } .environment(viewModel) .onAppear { viewModel.fetchStuff() } } .tint(.cuteColor) } @ViewBuilder var content: some View { if viewModel.list.isEmpty && viewModel.anotherlist.isEmpty { ContentUnavailableView( "No Content", image: "stop", description: Text("Add something here by tapping the + button.") ) } else { contentList } } var contentList: some View { blah blah blah } } First I tried the background, then the presentation background, and finally the Zstack. I hope this is fixed because it's actually fun to build scrollable content and text with swiftUI and I'd been avoiding it for years.
7
0
292
1w
.bottomBar menu button briefly disappears after menu dismissal on iOS 26.1 Seed 2 (23B5059e)
[Also submitted as FB20636175] In iOS 26.1 Seed 2 (23B5059e), ToolbarItem menus with .bottomBar placement cause the toolbar item to disappear and rebuild after the menu is dismissed, instead of smoothly morphing back. The bottom toolbar can take 1–2 seconds to reappear. This also seems to coincide with this console error: Adding 'UIKitToolbar' 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. This occurs both on device and in a simulator. Sample Project This sample ContentView includes two menu buttons—one in the bottom bar and one in the top bar. Dismissing the bottom bar menu causes a short delay before the button reappears, while the top bar menu behaves normally. struct ContentView: View { var body: some View { NavigationStack { Text("Tap and dismiss both menu buttons and note the difference.") .navigationTitle("BottomBar Menu Issue") .navigationSubtitle("Reproduces on iOS 26.1 Seed 2 (23B5059e)") .toolbar { // Control: top bar trailing menu animates back smoothly ToolbarItem(placement: .topBarTrailing) { Menu { Button("Dismiss", role: .cancel) { } Button("Do Nothing") { } } label: { Label("More", systemImage: "ellipsis.circle") .font(.title3) } } // Repro: delay before menu button reappears after menu dismissal ToolbarItem(placement: .bottomBar) { Menu { Button("Dismiss", role: .cancel) { } Button("Do Nothing") { } } label: { Label("Actions", systemImage: "ellipsis.circle") .font(.title2) } } } } } } Passwords App This can also be seen in iOS 26.1 Seed 2 (23B5059e)'s Passwords app ("All" or "Passcodes" views):
0
1
81
2w
How to bind AppKit window to Observable viewmodel using SwiftUI app life cycle
Hey everyone. I have a macOS app written in SwiftUI. I have multiple SwiftUI Scenes and Views, but needed to write one specific window in AppKit (an NSPanel, to be specific). The problem I'm facing is- I'm not sure how to incorporate this NSPanel with the rest of my SwiftUI/Observable code. I'm relying on the SwiftUI app cycle. For example, I have a boolean in my view model (observation tracked). I'd like to use this boolean to hide/unhide my NSPanel. Any way to cleanly hook into the viewmodel, or onto some specific observable variables would be very very helpful. Thank you everyone.
1
0
149
2w
subscriptionPeriod.unit returns both .week AND .day for weekly subscriptions?
After creating a new weekly subscription option, I get inconsistent results for subscriptionPeriod. In local testing with a synced or a un-synced StoreKit file I am getting unit == .week (as expected) whereas in TestFlight I am getting unit == .day. This makes unit.localizedDescriptionsomewhat unusable in the paywall. Am I missing something? Or is this bug or a limitation of StoreKit and/or TestFlight and/or newly created subscription options? Affected code (in a custom SubscriptionStoreControlStyle): private func priceDisplay(for pickerOption: Configuration.PickerOption) -> String { var result = "" if pickerOption.introductoryOffer != nil { result += NSLocalizedString("then", comment: "") + " " } result += pickerOption.displayPrice if let unit = pickerOption.subscriptionPeriod?.unit { result += " / " + unit.localizedDescription } return result } private func percentageSaved(for pickerOption: Configuration.PickerOption, allOptions: [Product]) -> Int? { guard let subscriptionPeriod = pickerOption.subscriptionPeriod, subscriptionPeriod != .weekly else { return nil } let weeklyOption = allOptions.first { otherOption in otherOption.subscription?.subscriptionPeriod == .weekly } guard let weeklyOption, weeklyOption.price > 0 else { return nil } let percentageSaved = 100 - (pickerOption.price / (weeklyOption.price * 52)) * 100 return Int((percentageSaved as NSNumber).doubleValue) }
0
0
91
2w
Mac Catalyst: Toolbar still appears below title bar, leaving empty safe area
Hi everyone, I’m testing my Catalyst SwiftUI project on iOS 26 / iPadOS 26 / macOS 26. I started with a NavigationSplitView (triple-column) inside a WindowGroup. On iPad it looks great: the toolbar items merge into the navigation bar, with the three traffic lights. But on Mac Catalyst, the app always reserves a blank safe area below the traffic lights, and places the toolbar on a separate line beneath the title bar. That leaves wasted vertical space I don’t want. What I expect (based on Apple’s WWDC session “Elevate the design of your iPad app”): The toolbar should merge into the title bar with the traffic lights, no separate row. Content should extend into the full height of the window. What I get on Mac Catalyst: Title bar + traffic lights at the top. Then a completely separate toolbar row below it. Safe area inset prevents my content from reaching the top of the window. What I’ve tried: .toolbarRole(.automatic), .editor, .browser → no effect. Hiding the title bar via titlebar?.titleVisibility = .hidden → removes the text but not the toolbar gap. Clearing titlebar?.toolbar → no difference. So far, I can’t find any way to get Catalyst to integrate toolbars into the window chrome the way native SwiftUI on macOS does. Is this a known limitation of Mac Catalyst, or is there a supported way to achieve the same “inline toolbar with window controls” layout? Switching to a Mac app vs. Catalyst fixes the issue, but I would have a lot more work to do to get the app ready for release, not ideal since it works near perfect on iPad. Thanks!
1
2
212
2w
Illegible navigation title when presenting Map view
When building with the iOS 26 SDK (currently beta 4), the navigation title is often illegible when rendering a Map view. For example, note how the title "Choose Location" is obscured by the map's text ("South America") in the screenshot below: This screenshot is the result of the following view code: import MapKit import SwiftUI struct Demo: View { var body: some View { NavigationStack { Map() .navigationTitle(Text("Choose Location")) .navigationBarTitleDisplayMode(.inline) } } } I tried using the scrollEdgeEffectStyle(_:for:) modifier to apply a scroll edge effect to the top of the screen, in hopes of making the title legible, but that doesn't seem to have any effect. Specifically, the following code seems to produce the exact same result shown in the screenshot above. import MapKit import SwiftUI struct Demo: View { var body: some View { NavigationStack { Map() .scrollEdgeEffectStyle(.hard, for: .top) // ⬅️ no apparent effect .navigationTitle(Text("Choose Location")) .navigationBarTitleDisplayMode(.inline) } } } Is there a recommended way to resolve this issue so that the navigation title is always readable?
7
3
241
2w
Foundation Models inside of DeviceActivityReport?
Pretty much as per the title and I suspect I know the answer. Given that Foundation Models run on device, is it possible to use Foundation Models framework inside of a DeviceActivityReport? I've been tinkering with it, and all I get is errors and "Sandbox restrictions". Am I missing something? Seems like a missed trick to utilise on device AI/ML with other frameworks.
1
0
354
2w
SwiftUI animation is laggy in NSStatusItem since macOS 26 Tahoe
My app is a bit of a special case and relies on a custom view in a NSStatusItem. I use a NSHostingView and add it as a subview to my NSStatusItem's .button property. Since macOS 26 Tahoe, even simple animations like a .frame change of a Circle won't animate smoothly even though the same SwiftUI animates normally in a WindowGroup. class AppDelegate: NSObject, NSApplicationDelegate { private let statusItem: NSStatusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) func applicationDidFinishLaunching(_ aNotification: Notification) { let subview = NSHostingView(rootView: AnimationView()) let view = self.statusItem.button view?.addSubview(subview) subview.translatesAutoresizingMaskIntoConstraints = false guard let view = view else { return } NSLayoutConstraint.activate([ subview.centerXAnchor.constraint(equalTo: view.centerXAnchor), subview.centerYAnchor.constraint(equalTo: view.centerYAnchor), subview.widthAnchor.constraint(equalToConstant: 22), subview.heightAnchor.constraint(equalToConstant: 22) ]) } } struct AnimationView: View { @State private var isTapped = false @State private var size: CGSize = .init(width: 4, height: 4) var body: some View { Circle() .fill(.pink) .frame(width: size.width, height: size.height) .frame(width: 20, height: 20) // .frame(maxHeight: .infinity) // .padding(.horizontal, 9) // .frame(height: 22) .contentShape(Rectangle()) // .background(Color.blue.opacity(0.5)) .onTapGesture { withAnimation(.interactiveSpring(response: 0.85, dampingFraction: 0.26, blendDuration: 0.45)) { // withAnimation(.spring()) { if isTapped { size = .init(width: 4, height: 4) } else { size = .init(width: 16, height: 16) } } isTapped.toggle() }} } Example project: https://app.box.com/s/q28upunrgkxyyd97ovslgud9yitqaxfk
0
0
51
2w
Safari-like toolbar in visionOS
I like the toolbar visionOS's Safari uses for back & forward page, share, etc. It floats above the window. My attempt to do this with ornaments isn't as satisfying as they partially cover the window. My attempts with toolbar haven't produced visible results. Is this Safari-style toolbar for visionOS exposed by Apple in the API's? If so, could someone point me to documentation or sample code? Thanks!
1
0
166
2w