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

Replacement for ToolbarItems with .bottomBar placement in iOS 26 TabView?
Prior to iOS 26, ToolbarItems with .bottomBar placement were convenient for tab-specific frequent actions. With iOS 26’s new tab layering now obscuring such ToolbarItems, it’s unclear whether .tabViewBottomAccessory is the intended replacement or if another pattern (like persistent floating buttons) is encouraged instead. What’s the recommended way to support quick, tab-specific actions under the new system? I’ve tried conditionally rendering a .tabViewBottomAccessory based on the active tab, but this causes a crash, which I’ve reported as FB18479195.
4
2
311
Jul ’25
SwiftUI APIs for macOS app
What are the SwiftUI equivalent of NSSplitViewController.automaticallyAdjustsSafeAreaInsets NSToolbarItem.style These were introduced in the WWDC 2025 session named "Build an AppKit app with the new design". Jeff introduced only the AppKit API's while there was no mention of SwiftUI API
3
0
243
Jul ’25
SwiftUI List scroll indicator stutters, does not call `onAppear` or `onDisappear` consistently in iOS 16
My team has been debugging problems with the SwiftUI List component this week. We have found that it's performance is sub-optimal on iOS 16. You can see a simple grid of images, the scroll indicator stutters when scrolling down: Now compare it to what happens when we use a ScrollView with a LazyVStack: (An error occurred while uploading my second image, but pretend you see a scroll indicator moving smoothly down the side of the screen). You can see the scroll indicator moves smoothly without issue. We also found that the ScrollView combined with a LazyVStack properly calls onDisappear, which enables us to call a cancel method on the async image loading code that we use for our individual cells in this example. Though in a previous question, it was asserted that onDisappear cannot be reliably expected to be called in a List, I do not feel that answer is correct or proper behavior. Is this a bug, or is this expected behavior on a List? This is the cell that is being rendered: struct UserGridCell: View {   let stackId: String   let user: ProfileGridCellUIModel   let userGridCellType: UserGridCellType   @State var labelFrame: CGRect = .zero       private var isOnlineAcessibilityValue: String {     return user.isOnline == true ? "" : ""   }       init(stackId: String,      user: ProfileGridCellUIModel,      userGridCellType: UserGridCellType   ) {           self.stackId = stackId     self.user = user     self.userGridCellType = userGridCellType   }   var body: some View {     GeometryReader { containerGeometry in       ZStack(alignment: .bottom) {         HStack(spacing: 4) {                       let statusAccentColor: Color = .red                                   Circle()             .frame(width: 8, height: 8)             .foregroundColor(statusAccentColor)                       Text(String(user.remoteId) ?? "")             .lineLimit(1)             .foregroundColor(.black)             .overlay(GeometryReader { textGeometry in               Text("").onAppear {                 self.labelFrame = textGeometry.frame(in: .global)               }             })         }         .frame(maxWidth: .infinity, alignment: .bottomLeading)         .padding(.leading, 8)         .padding(.trailing, 8)         .padding(.bottom, 8)       }       .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom)       .contentShape(Rectangle())       .accessibilityLabel(Text(user.name ?? ""))       .accessibilityValue(isOnlineAcessibilityValue)     }     .background(       ZStack {         AsyncProfileImage(request: URLRequest(url: URL(string: "https://picsum.photos/id/\(100 + user.remoteId)/200/300")!))       }         .accessibilityHidden(true)     )     .overlay(       RoundedRectangle(cornerRadius: 4)         .stroke(.red, lineWidth: user.hasAnyUnreadMessages ? 4 : 0)     )     .cornerRadius(4)   } } This is the code that renders each cell: struct ProfileGrid: View {   public static var AspectRatio: CGFloat = 0.75   @Environment(\.horizontalSizeClass) var horizontalSizeClass   @Environment(\.redactionReasons) private var reasons   private let stacks: [ProfileGridStackUIModel]   public init(stacks: [ProfileGridStackUIModel]   ) {     self.stacks = stacks   }       var body: some View {     let columnCount: Int = 3           // If you use a list, you will get the stutter. If you use what you see below, // it will render properly.     ScrollView {       LazyVStack {         ForEach(stacks, id: \.self) { stack in           Grid(stack: stack, columns: columnCount)         }       }     }     .buttonStyle(PlainButtonStyle())     .listStyle(PlainListStyle())   }       @ViewBuilder private func Grid(stack: ProfileGridStackUIModel, columns: Int) -> some View {     let chunks = stride(from: 0, to: stack.profiles.count, by: columns).map {       Array(stack.profiles[$0..<min($0 + columns, stack.profiles.count)])     }                   ForEach(chunks, id: \.self) { chunk in       GridRow(chunk: chunk, stack: stack, columns: columns)         .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))     }   }       @ViewBuilder private func GridRow(chunk: [ProfileGridCellUIModel], stack: ProfileGridStackUIModel, columns: Int) -> some View {     let emptyElements = columns - chunk.count     HStack(spacing: 8) {       ForEach(chunk) { user in         UserGridCell(stackId: "id",                user: user,                userGridCellType: .grid)         .aspectRatio(ProfileGrid.AspectRatio, contentMode: .fill)       }               if emptyElements > 0 {         ForEach(0..<emptyElements, id: \.self) { _ in           Rectangle()             .foregroundColor(Color.clear)             .contentShape(Rectangle())             .frame(maxWidth: .infinity)             .aspectRatio(ProfileGrid.AspectRatio, contentMode: .fill)         }       }     }   } }
2
0
2.1k
Jul ’25
focusable modifier does not work on Ventura
It works on Monterey, but not work on Ventura. struct ContentView: View { @FocusState private var focus: FocusableElement? @FocusedValue(\.focusedElement) var focusElement var body: some View { VStack(spacing: 30) { HStack { GroupBox { Circle() .focusable() .focused($focus, equals: .circle) .focusedValue(\.focusedElement, .circle) .frame(width: 100, height: 100) .padding() Text(focus == .circle ? "Selected" : "Not selected") } .onTapGesture { focus = .circle } GroupBox { Rectangle() .focusable() .focused($focus, equals: .rectangle) .focusedValue(\.focusedElement, .rectangle) .frame(width: 100, height: 100) .padding() Text(focus == .rectangle ? "Selected" : "Not selected") } } .onTapGesture { focus = .rectangle } Text("Focused Element: \(focusElement?.rawValue ?? "None")") } .padding() .frame(width: 500, height: 300) } } enum FocusableElement: Equatable, Hashable { case rectangle case circle } enum Selection: String, Hashable { case none case rectangle case circle } extension FocusedValues { struct FocusedElement: FocusedValueKey { typealias Value = Selection } var focusedElement: FocusedElement.Value? { get { self[FocusedElement.self] } set { self[FocusedElement.self] = newValue } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
1
0
694
Jul ’25
.commandsRemoved() does not work for the first scene.
.commandsRemoved() does not work for the Window and WindowGroup scenes if it’s the primary group (first one). Then I tried to add new menu using the code .commands {       CommandGroup(replacing: .newItem) {           Button("New Document") {               newDocument { TestDocument() }           }           .keyboardShortcut("n") } But app crashed with error " Expected subclass override" The test app is a document-based app, with a welcome window using the new Window scene.
1
0
1k
Jul ’25
Pushing a UIHostingController has delayed toolbar items and title transitions
For over five years, this persistent issue has affected all platforms, and despite submitting numerous feedback reports, my concerns have remained unaddressed. When utilizing a UIHostingController within a UINavigationController, the toolbar items and title defined in the SwiftUI view manifest with a substantial delay. This delay is particularly noticeable with the introduction of Liquid Glass, resulting in a jarring transition. Although I had nearly lost hope, the issue was resolved in iOS 26 beta 3 when the push occurs from within a UISplitViewController. However, the problem persists outside of this context. Ultimately, this issue hinders my ability to develop high-quality applications and restricts my use of SwiftUI within my UIKit project for similar purposes. I sincerely hope that this issue can be resolved, enabling me to fully rely on SwiftUI in my project. Please prioritize this matter and make the necessary changes that were already made in UISplitViewController. This feedback has all the details and a sample project. FB14000542 Before the push: During the push: A second after the push finishes:
0
1
149
Jul ’25
TabView + NavigationStack + ScrollView navigationTitle bug
Hello there! I've been struggline with this thing for a two days now, and seems like it's a bug in SwiftUI. Navigation title is jumping on top of the ScrollView's content when switching tabs in TabView. Steps to reproduce: Scroll one tab to the bottom so that the large title is hidden and the floating toolbar appears. Go to another tab in the tab bar. Go back to the initial tab (it is still scrolled), and press the current tab button again to scroll to the top. The navigation title will glitch and be on top of the content. The animation fixes if you scroll again manually. Video: https://share.cleanshot.com/PFCSKMlH Code (simplified): import SwiftData import SwiftUI @main struct MyApp: App { var body: some Scene { WindowGroup { TabsContentView() } } } // ... struct TabsContentView: View { enum Tab { case library, profile } @State private var selectedTab: Tab = .library var body: some View { TabView(selection: $selectedTab) { NavigationStack { YourLibraryList() .navigationTitle("Your Library") } .tabItem { Label("Library", systemImage: "tray.fill") } .tag(Tab.library) NavigationStack { VStack { Spacer() Text("Profile") .font(.largeTitle) .foregroundColor(Color.theme.text) Text("Manage your account and preferences here") .font(.body) .foregroundColor(Color.theme.mutedForeground) .multilineTextAlignment(.center) .padding(.horizontal) Spacer() } .navigationTitle("Explore") } .tabItem { Label("Profile", systemImage: "person.fill") } .tag(Tab.profile) } .toolbarBackground(.ultraThinMaterial, for: .tabBar) .toolbarBackground(.visible, for: .tabBar) } } // ... struct YourLibraryList: View { var body: some View { ScrollView { VStack(spacing: 12) { ForEach(1 ... 20, id: \.self) { number in RoundedRectangle(cornerRadius: 12) .fill(Color.blue.opacity(0.1)) .stroke(Color.blue, lineWidth: 1) .frame(height: 60) .overlay( Text("\(number)") .font(.title2) .fontWeight(.semibold) .foregroundColor(.blue) ) } } .padding(.horizontal) } } }
2
0
262
Jul ’25
Liquid glass: UIPageViewController inside UITabbarController adding blur effect always in iOS26
When using UIPageViewController inside a UITabBarController on iOS 26 with Liquid Glass adoption, visiting the PageViewController tab applies a blur effect to the navigation bar and tab bar even though the current child view controller of the pageView is not scrollable and does not reach behind these bars. Questions: Is this the expected behavior that the pageview's internal scroll view causes the bars to blur regardless of the page view's child content’s scrollability? If so, is there an official way to make the blur effect appear only when the pageview's current child view controller actually scrolls behind the navigation bar or tab bar, and not in static cases? Tried the same in SwiftUI using TabView and TabView with page style. Facing the same issue there as well. Sample screenshots for reference, Sample SwiftUI code, struct TabContentView: View { var body: some View { TabView { // First Tab: Paging View PagingView() .tabItem { Label("Pages", systemImage: "square.fill.on.square.fill") } // Second Tab: Normal View NavigationStack { ListView() } .tabItem { Label("Second", systemImage: "star.fill") } // Third Tab: Normal View PageView(color: .blue, text: "Page 3") .tabItem { Label("Third", systemImage: "gearshape.fill") } } .ignoresSafeArea() } } struct PagingView: View { var body: some View { TabView { PageView(color: .red, text: "Page 1") PageView(color: .green, text: "Page 2") PageView(color: .blue, text: "Page 3") } .tabViewStyle(.page) // Enables swipe paging .indexViewStyle(.page(backgroundDisplayMode: .always)) .ignoresSafeArea()// Dots indicator } }
1
0
226
Jul ’25
Best Option for Programmatically Scrolling Long Dynamic Text
Hello! I am trying to create an iOS app that is based around a very large, vertically scrolling text view. The text is broken up into many sections, and the user should be able to press buttons in the navigation, which programmatically scroll to those sections. The user can also change the font size in a settings menu. It should generally keep the user's spot when resizing fonts or rotating the screen (from portrait to landscape). The problem I've been having is that no method of lazy text loading allows accurate enough navigation, and the text is too long to calculate the whole UI all at once. Here's my process in trying to find a solution: My app is built in SwiftUI, so I started with a ScrollView and a LazyVStack, and I used .scrollPosition() and bound it to an Int?. It worked pretty well for most scroll locations both on screen and far off the screen, but when I programmatically scroll to a location that is off the screen but not very far off, it completely misses. So, I investigated UIKit, and found that UITextView was a much better fit for the way I wanted to present the long text. I could also programmatically navigate by storing the NSRange of each section. I tried to use scrollRangeToVisible(), but for long distance it would scroll so that the desired section was just below the viewport and thus off screen. Then I tried to use UITextView's textLayoutManager.textViewportLayoutController.relocateViewport() to send it to the correct NSTextRange, it would not jump all the way, but instead would do nothing until I tried to scroll again and it would jump slightly forward. I tried to use textViewportLayoutController.layoutViewport() after the jump, and that fixed the glitch when scrolling, but it still did not jump to the correct place, only slightly forward. Then, I looked into TextKit 2 and the way it worked to try to find a solution. From what I can tell, it seems that to affect the NSTextViewportLayoutController without having to rewrite it, I need an NSTextViewportLayoutControllerDelegate, but the delegate required me to manually lay out the views, and in all the examples I've seen that use a custom NSTextViewportLayoutControllerDelegate, they wrote their own custom text view instead of using the default UITextView. I started looking into writing a custom text view so I can get the programmatic scroll to work consistently. However, it felt like, from a maintainability standpoint, it would probably be best to stick with what Apple has already implemented. For now, I found a workaround that scrolls consistently. Here is the code: if let start = self.textView.position(from: self.textView.beginningOfDocument, offset: desiredLineRange.location) { let location = textView.caretRect(for: start) self.textView.setContentOffset(CGPoint(x: 0, y: location.origin.y), animated: false) } if let start = self.textView.position(from: self.textView.beginningOfDocument, offset: desiredLineRange.location) { let location = textView.caretRect(for: start) self.textView.setContentOffset(CGPoint(x: 0, y: location.origin.y), animated: false) } It does the job, because the first time it gets close enough, and the second time it gets to the precise location, but it just feels like a bit of a hack to run the same code twice. I was wondering if anyone knows what I could be doing wrong and if Apple provides any solutions for this? (Also, all my UIKit navigation attempts ran inside an @objc func, which I passed using button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside). Just so you know in case it may be a problem with the way Swift and UIKit handle concurrency/parallel tasks). Thank you!
0
0
202
Jul ’25
Significant scrolling lag when using .focused modifier in large LazyVStack/LazyHStack on tvOS
Summary: When using the new .focused modifier to track focus within a large LazyVStack or LazyHStack, we observe a major frame-rate drop and stuttering on Apple TV (1st and 2nd generation). Steps to Reproduce: Create a LazyVStack (or LazyHStack) displaying a substantial list of data models (e.g., 100+ GroupData items). Attach the .focused(::) modifier to each row, binding to an @FocusState variable of the same model type. Build and run on an Apple TV device or simulator. Scroll through the list using the remote. static func == (lhs: GroupData, rhs: GroupData) -> Bool { lhs.id == rhs.id } var id: String var name: String var subName: String var subGroup: [GroupData] = [] var logo: URL? } struct TestView: View { @FocusState var focusedGroup: GroupData? let groupsArr: [GroupData] var body: some View { ScrollView { LazyVStack { ForEach(groupsArr, id: \.id) { group in Button { } label: { GroupTestView(group: group) } .id(group.id) .focused($focusedGroup, equals: group) } } } } } struct GroupTestView: View { let group: GroupData var body: some View { HStack { KFImage.url(group.logo) .placeholder { Image(systemName: "photo") .opacity(0.2) .imageScale(.large) } .resizable() .scaledToFit() .frame(width: 70) VStack { Text(group.name) Text(group.subName) } } } } Expected Behavior Scrolling remains smooth (60 fps) regardless of list size. Focus updates without introducing visible lag. Observed Behavior Frame rate drops significantly when .focused is applied. Scrolling becomes visibly laggy, especially on older Apple TV hardware. Even when binding an @FocusState<String?> (storing only the id), performance improves slightly but remains suboptimal. Workarounds Tried Switched to @FocusState of type String to track only the ID of each group, this has helped but there is still a big performance decrease. Minimised view-body complexity and removed other modifiers. Verified that excluding .focused entirely restores smooth scrolling. Any guidance or suggestions would be greatly appreciated.
3
1
167
Jul ’25
Unable to Drag 3D Model(Entity) in visionOS when UITextView Is in the Background
I'm running into an issue in Xcode when working on a visionOS app. Whenever I try to drag a 3D model entity in my scene, the drag gesture doesn't work if there's a UITextView (or SwiftUI TextEditor) in background of the 3D entity. It seems like the UITextView is intercepting the gesture or preventing the drag interaction from reaching the 3D content. Interestingly, when the 3D entity is placed infront of the ScrollView, the drag works as expected. Has anyone else experienced this behavior? Is this a known limitation or a bug in the current tooling? Any workarounds or fixes would be appreciated. Thanks!
0
0
199
Jul ’25
iOS 26 beta: Section headers no longer show translucent background when pinned with .listStyle(.plain)
Hi everyone, I've noticed a significant change in the visual behavior of List section headers between iOS 18 and iOS 26 beta that I'd like to clarify. Current Behavior: iOS 18 and earlier: Section headers with .listStyle(.plain) display with a translucent material background (regular material with blur effect) when pinned to the top during scrolling iOS 26 beta: Section headers with .listStyle(.plain) appear with a transparent/clear background even when pinned to the top Sample Code: struct ContentView: View { var body: some View { NavigationStack { List(1 ..< 5) { headerIndex in Section { ForEach(1...5, id: \.self) { rowIndex in HStack { Text("Row \(rowIndex)") .frame(height: 40) .padding(.horizontal) .background(Color.blue) Spacer() Image(systemName: "chevron.right") .foregroundStyle(.secondary) .font(.title3) } } } header: { Text("Header \(headerIndex)") .frame(height: 44) } .listRowSeparator(.hidden) } .listStyle(.plain) .clipped() } } } Questions: Is this change in header background behavior for .plain list style intentional in iOS 26? If so, what's the recommended way to maintain the previous material background appearance when headers are pinned? Should this be filed as feedback if it's unintended behavior? Testing Environment: Xcode 26.0 beta 3 (17A5276g) iOS 26 beta (23A5287g) vs iOS 18.5 Tested on simulator The translucent header background when pinned was quite useful for maintaining readability over scrolling content, so I'm hoping to understand if this is the new expected behavior or if there's a way to preserve the previous appearance. Any insights would be greatly appreciated! iOS 18.5 iOS 26 Beta
2
1
198
Jul ’25
Multi-Selection List : changing Binding Array to Binding Set and back again
I am trying to create a menu picker for two or three text items. Small miracles, but I have it basically working. Problem is it uses a set, and I want to pass arrays. I need to modify PickerView so the Bound Parameter is an [String] instead of Set. Have been fighting this for a while now... Hoping for insights. struct PickerView: View { @Binding var colorChoices: Set<String> let defaults = UserDefaults.standard var body: some View { let possibleColors = defaults.object(forKey: "ColorChoices") as? [String] ?? [String]() Menu { ForEach(possibleColors, id: \.self) { item in Button(action: { if colorChoices.contains(item) { colorChoices.remove(item) } else { colorChoices.insert(item) } }) { HStack { Text(item) Spacer() if colorChoices.contains(item) { Image(systemName: "checkmark") } } } } } label: { Label("Select Items", systemImage: "ellipsis.circle") } Text("Selected Colors: \(colorChoices, format: .list(type: .and))") } } #Preview("empty") { @Previewable @State var colorChoices: Set<String> = [] PickerView(colorChoices: $colorChoices) } #Preview("Prefilled") { @Previewable @State var colorChoices: Set<String> = ["Red","Blue"] PickerView(colorChoices: $colorChoices) } My Content View is suppose to set default values the first time it runs, if no values already exist... import SwiftUI struct ContentView: View { @State private var viewDidLoad: Bool = false var body: some View { HomeView() .onAppear { // The following code should execute once the first time contentview loads. If a user navigates back to it, it should not execute a second time. if viewDidLoad == false { viewDidLoad = true // load user defaults let defaults = UserDefaults.standard // set the default list of school colors, unless the user has already updated it prior let defaultColorChoices: [String] = ["Black","Gold","Blue","Red","Green","White"] let colorChoices = defaults.object(forKey: "ColorChoices") as? [String] ?? defaultColorChoices defaults.set(colorChoices, forKey: "ColorChoices") } } } } #Preview { ContentView() } PickLoader allows you to dynamically add or delete choices from the list... import SwiftUI struct PickLoader: View { @State private var newColor: String = "" var body: some View { Form { Section("Active Color Choices") { // we should have set a default color list in contentview, so empty string should not be possible. let defaults = UserDefaults.standard let colorChoices = defaults.object(forKey: "ColorChoices") as? [String] ?? [String]() List { ForEach(colorChoices, id: \.self) { color in Text(color) } .onDelete(perform: delete) HStack { TextField("Add a color", text: $newColor) Button("Add"){ defaults.set(colorChoices + [newColor], forKey: "ColorChoices") newColor = "" } } } } } .navigationTitle("Load Picker") Button("Reset Default Choices") { let defaults = UserDefaults.standard //UserDefaults.standard.removeObject(forKey: "ColorChoices") let colorChoices: [String] = ["Black","Gold","Blue","Red","Green","White"] defaults.set(colorChoices, forKey: "ColorChoices") } Button("Clear all choices") { let defaults = UserDefaults.standard defaults.removeObject(forKey: "ColorChoices") } } } func delete(at offsets: IndexSet) { let defaults = UserDefaults.standard var colorChoices = defaults.object(forKey: "ColorChoices") as? [String] ?? [String]() colorChoices.remove(atOffsets: offsets) defaults.set(colorChoices, forKey: "ColorChoices") } #Preview { PickLoader() } And finally HomeView is where I am testing from - to see if binding works properly... import SwiftUI struct HomeView: View { //@State private var selection: Set<String> = [] //@State private var selection: Set<String> = ["Blue"] @State private var selection: Set<String> = ["Blue", "Red"] var body: some View { NavigationStack { List { Section("Edit Picker") { NavigationLink("Load Picker") { PickLoader() } } Section("Test Picker") { PickerView(colorChoices: $selection) } Section("Current Results") { Text("Current Selection: \(selection, format: .list(type: .and))") } } .navigationBarTitle("Hello, World!") } } } #Preview { HomeView() } If anyone uses this code, there are still issues - buttons on Loader don't update the list on the screen for one, and also dealing with deleting choices that are in use - how does picker deal with them? Probably simply add to the list automatically and move on. If anyone has insights on any of this also, great! but first I just need to understand how to accept an array instead of a set in pickerView. I have tried using a computed value with a get and set, but I can't seem to get it right. Thanks for any assistance! Cheers!
2
0
197
Jul ’25
Look to Scroll
Hello! I’m excited to see that Look to Scroll has been included in visionOS 26 Beta. I’m aiming to achieve a feature where the user’s gaze at a specific edge automatically scrolls to that position. However, I’ve experimented with ScrollView and haven’t been able to trigger this functionality. Could you advise if additional API modifiers are necessary? Thank you!
1
0
555
Jul ’25
SwiftData and discarding unsaved changes idea???
Someone smarter than me please tell me if this will work... I want to have an edit screen for a SwiftData class. Auto Save is on, but I want to be able to revert changes. I have read all about sending a copy in, sending an ID and creating a new context without autosave, etc. What about simply creating a second set of ephemeral values in the actual original model. initialize them with the actual fields. Edit them and if you save changes, migrate that back to the permanent fields before returning. Don't have to manage a list of @State variables corresponding to every model field, and don't have to worry about a second model context. Anyone have any idea of the memory / performance implications of doing it this way, and if it is even possible? Does this just make a not quite simple situation even more complicated? Haven't tried yet, just got inspiration from reading some medium content on attributes on my lunch break, and wondering if I am just silly for considering it.
2
0
188
Jul ’25
TabView - .search roles
I'm having some difficulty with a tabview and getting the new search bar to expand from the search icon. The tabview works so far, it looks fine, tapping on the search opens the view I will be modifying to use the search bar. snip from my tabview: var body: some View { TabView(selection: $selectedTab) { Tab("Requests", systemImage: "list.bullet", value: .requests) { OverseerrRequestView(integrationId: integrationId) } Tab("Users", systemImage: "person.3", value: .users) { OverseerrUserView(integrationId: integrationId) } Tab("Search", systemImage: "magnifyingglass", value: .search, role: .search) { NavigationStack { OverseerrView(integrationId: integrationId) .searchable(text: $searchString) } } } .modifier(TabBarMinimizeIfAvailable()) .navigationTitle("Overseerr") .modifier(NavigationBarInlineIfAvailable()) } Currently in that view, I have temporarily constructed a search bar that handles the search function (we're searching externally, not just contents in the view) snip from my view: .safeAreaInset(edge: .bottom) { HStack { Image(systemName: "magnifyingglass") .foregroundColor(.secondary) TextField("Search movies, TV or people", text: $query) .focused($isSearchFieldFocused) .onSubmit { Task { await performSearch() } } .submitLabel(.search) .padding(.vertical, 8) .padding(.horizontal, 4) if !query.isEmpty { Button(action: { query = "" searchResults = [] Task { await loadTrending() } }) { Image(systemName: "xmark.circle.fill") .foregroundColor(.secondary) } } } .padding(.horizontal) .padding(.vertical, 5) .adaptiveGlass() .shadow(radius: 8) .onAppear { isSearchFieldFocused = false } } Notes: .adaptiveGlass() is a modifier I created to easily apply liquid glass or not depending on OS version, so as not to require the use of #if or #available in the views. The end goal here: have the tab view search "tab" open the OverseerrView.swift (Discover) view, activate the animated search bar, and search the input text to the performSearch() function. I have similar needs on other tab views, and am trying to move away from needing to manually create a search bar, when one should work from the .search role. Is there an example project with this search in the tab that I can reference? the landmarks sample project sadly did not include one.
4
0
178
Jul ’25
VisionOS26 PresentationComponent not working
I am trying to get the new PresentationComponent working in VisionOS26 as seen in this WWDC video: https://developer.apple.com/videos/play/wwdc2025/274/?time=962 (18:29 minutes into video) Here is some other example code but it doesn't work either: https://stepinto.vision/devlogs/project-graveyard-devlog-002/ My simple Text view (that I am adding as a PresentationComponent) does not appear in my RealityView even though the entity is found. Here is a simple example built from an Xcode immersive view default project: struct ImmersiveView: View { @Environment(AppModel.self) var appModel var body: some View { RealityView { content in // Add the initial RealityKit content if let immersiveContentEntity = try? await Entity(named: "Immersive", in: realityKitContentBundle) { content.add(immersiveContentEntity) if let materializedImmersiveContentEntity = try? await Entity(named: "Test", in: realityKitContentBundle) { content.add(materializedImmersiveContentEntity) var presentation = PresentationComponent( configuration: .popover(arrowEdge: .bottom), content: Text("Hello, World!") .foregroundColor(.red) ) presentation.isPresented = true materializedImmersiveContentEntity.components.set(presentation) } } } } } Here is the Apple reference: https://developer.apple.com/documentation/realitykit/presentationcomponent
1
0
582
Jul ’25
Panel Toggle Glitch
Development environment: Simulator: iOS 26 beta 3 iPhone 16 (for testing) Simulator 2: iPadOS 26 beta 3 iPad Air 13 inch (M3) (for testing) Connected Device: iPadOS 26 beta 3 iPad Pro 11 inch (M4) (for testing) Dev Device: macOS Tahoe 26 beta 3 Macbook Air When using the NavigationSplitView element, the sidebar has a built-in panel toggle button. However, when I click the toggle button to toggle the sidebar section in SwiftUI 26 on both simulator 2 and the connected device, it has a slight animation glitch before going back to normal. What's going on? This is my code for the specific view that has the NavigationSplitView (and all views are connected through TabViews): RecordsPage.swift Here are image references: When I clicked the toggle: After 1~2 seconds: These images are in the state of the panel being hidden.
Topic: Design SubTopic: General Tags:
1
0
399
Jul ’25
How to use defaultSize with visionOS window restoration?
One of the most common ways to provide a window size in visionOS is to use the defaultSize scene modifier. WindowGroup(id: "someID") { SomeView() } .defaultSize(CGSize(width: 600, height: 600)) Starting in visionOS 26, using this has a side effect. visionOS 26 will restore windows that have been locked in place or snapped to surfaces. If a user has manually adjusted the size of a locked/snapped window, the users size is only restore in some cases. Manual resize respected Leaving a room and returning later Taking the headset off and putting it back on later Manual resize NOT respected Device restart. In this case, the window is reopened where it was locked, but the size is set back to the values passed to defaultSize. The manual resizing adjustments the user has made are lost. This is counter to how all other windows and widgets work. I reported this last month (FB18429638), but haven't heard back if this is a bug or intended behavior. Questions What is the best way to provide a default window size that will only be used when opening new windows–and not used during scene restoration? Should we try to keep track of window size after users adjust them and save that somewhere? If this is intended behavior, can someone please update the docs accordingly?
1
0
445
Jul ’25