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

dropDestination does not work inside List
I've discovered an issue with using iOS 16's Transferable drag-and-drop APIs for SwiftUI. The dropDestination modifier does not work when applied to a subview of a List. This code below will not work, unless you replace the List with a VStack or any other container (which, of course, removes all list-specific rendering). The draggable modifier will still work and the item will drag, but the dropDestination view won't react to it and neither closure will be called. struct MyView: View { var body: some View { List { Section { Text("drag this title") .font(.largeTitle) .draggable("a title") } Section { Color.pink .frame(width: 400, height: 400) .dropDestination(for: String.self) { receivedTitles, location in true } isTargeted: { print($0) } } } } } Has anyone encountered this bug and perhaps found a workaround?
9
0
3.7k
1w
Zoom navigation transitions for tabViewBottomAccessory are not working in SwiftUI with ObservableObject or Observable
The zoom navigation transition with matchedTransitionSource in tabViewBottomAccessory does not work when a Published var in an ObservableObjector Observable gets changed. Here is an minimal reproducible example with ObservableObject: import SwiftUI import Combine private final class ViewModel: ObservableObject { @Published var isPresented = false } struct ContentView: View { @Namespace private var namespace @StateObject private var viewModel = ViewModel() // @State private var isPresented = false var body: some View { TabView { Button { viewModel.isPresented = true } label: { Text("Start") } .tabItem { Image(systemName: "house") Text("Home") } Text("Search") .tabItem { Image(systemName: "magnifyingglass") Text("Search") } Text("Profile") .tabItem { Image(systemName: "person") Text("Profile") } } .sheet(isPresented: $viewModel.isPresented) { Text("Sheet") .presentationDragIndicator(.visible) .navigationTransition(.zoom(sourceID: "tabViewBottomAccessoryTransition", in: namespace)) } .tabViewBottomAccessory { Button { viewModel.isPresented = true } label: { Text("BottomAccessory") } .matchedTransitionSource(id: "tabViewBottomAccessoryTransition", in: namespace) } } } However, when using only a State property everything works: import SwiftUI import Combine private final class ViewModel: ObservableObject { @Published var isPresented = false } struct ContentView: View { @Namespace private var namespace // @StateObject private var viewModel = ViewModel() @State private var isPresented = false var body: some View { TabView { Button { isPresented = true } label: { Text("Start") } .tabItem { Image(systemName: "house") Text("Home") } Text("Search") .tabItem { Image(systemName: "magnifyingglass") Text("Search") } Text("Profile") .tabItem { Image(systemName: "person") Text("Profile") } } .sheet(isPresented: $isPresented) { Text("Sheet") .presentationDragIndicator(.visible) .navigationTransition(.zoom(sourceID: "tabViewBottomAccessoryTransition", in: namespace)) } .tabViewBottomAccessory { Button { isPresented = true } label: { Text("BottomAccessory") } .matchedTransitionSource(id: "tabViewBottomAccessoryTransition", in: namespace) } } }
5
1
328
1w
UIHostingConfiguration on tvOS, focus engine problem with SwiftUI and collectionView
UIHostingConfiguration on tvOS: focus permanently broken with multiple focusable SwiftUI views Hi everyone, I'm working on a tvOS app with a UICollectionView. Some cells embed SwiftUI content via UIHostingConfiguration, specifically a row of 3 buttons that should be individually focusable. The cell itself returns canBecomeFocused = false so focus passes through to the SwiftUI buttons. The problem: after navigating focus into that section once, it becomes permanently unfocusable. Focus enters briefly, then immediately exits to nil on its own, without any user input. From that point on, the focus engine completely skips the section. The exact same SwiftUI view works perfectly when embedded via UIHostingController instead. How to reproduce Press DOWN to move focus into the UIHostingConfiguration section Focus lands on a SwiftUI button for a split second Focus exits on its own and bumps to another section The section is now dead, focus skips it on every subsequent navigation What the system logs say (-UIFocusLoggingEnabled YES) Right when focus enters, the system reports the SwiftUI focus items as "disappearing": Ignoring focus update request for disappearing focus environment <UIKitFocusSectionResponderItem> Then when searching for a new focusable item: <SwiftUI._UIInheritedView> → (warning) No focusable items found. <UIHostingContentView> → (warning) No focusable items found. === unable to find focused item in context. retrying with updated request. === The views are still in the hierarchy (verified by pointer), but the UIHostingContentView no longer exposes its virtual focus items. I also see mismatched parentFocusEnvironment on those items, pointing to a _UIHostingView from a completely different cell. What I've tried I've spent a lot of time on this with my colleagues, dug through the very limited documentation available online, and even used AI agents to help brainstorm. We tested 10 different approaches, none worked: Overriding preferredFocusEnvironments to point to the UIHostingContentView setNeedsFocusUpdate() / updateFocusIfNeeded(), rescan finds nothing Forcing UIKit redraws (setNeedsLayout, setNeedsDisplay) Removing .focusSection() Removing all SwiftUI animations, identical behavior Using canFocusItemAt: delegate instead of cell subclass, identical remembersLastFocusedIndexPath = true, causes a separate focus trap configurationUpdateHandler + setNeedsUpdateConfiguration(), config is rebuilt but virtual items stay deregistered Verified the UIHostingContentView never leaves the hierarchy. It doesn't, its internal state is just corrupted My workaround I switched to UIHostingController with proper view controller containment. It works because the hosting controller is a full UIFocusEnvironment, so the focus engine can traverse it and it correctly maintains its virtual items. Has anyone encountered this? Is there a known pattern for using UIHostingConfiguration on tvOS with multiple focusable SwiftUI elements? Or should I just file a Feedback? Thanks for any help! You can find the code here : https://github.com/ThomasDutartre/focus-problem-tvos I recored the problem here : https://youtu.be/yPfM5AvU2ko
0
0
70
1w
Application Hangs with Nested LazyVStack When Accessibility Inspector is Active
Description I've encountered a consistent hang/freeze issue in SwiftUI applications when using nested LazyVStack containers with Accessibility Inspector (simulator) or VoiceOver (physical device) enabled. The application becomes completely unresponsive and must be force-quit. Importantly, this hang occurs in a minimal SwiftUI project with no third-party dependencies, suggesting this is a framework-level issue with the interaction between SwiftUI's lazy view lifecycle and the accessibility system. Reproduction Steps I've created a minimal reproduction project available here: https://github.com/pendo-io/SwiftUI_Hang_Reproduction To Reproduce: Create a SwiftUI view with the following nested LazyVStack structure: struct NestedLazyVStackView: View { @State private var outerSections: [Int] = [] @State private var innerRows: [Int: [Int]] = [:] var body: some View { ScrollView { LazyVStack(alignment: .leading, spacing: 24) { ForEach(outerSections, id: \.self) { section in VStack(alignment: .leading, spacing: 8) { Text("Section #\(section)") // Nested LazyVStack LazyVStack(alignment: .leading, spacing: 2) { ForEach(innerRows[section] ?? [], id: \.self) { row in Text("Section #\(section) - Row #\(row)") .onAppear { // Load more data when row appears loadMoreInner(section: section) } } } } .onAppear { // Load more sections when section appears loadMoreOuter() } } } } } } Enable Accessibility Inspector in iOS Simulator: Xcode → Open Developer Tool → Accessibility Inspector Select your running simulator Enable Inspection mode (eye icon) Navigate to the view and start scrolling Result: The application hangs and becomes unresponsive within a few seconds of scrolling Expected Behavior The application should remain responsive when Accessibility Inspector or VoiceOver is enabled, allowing users to scroll through nested lazy containers without freezing. Actual Behavior The application freezes/hangs completely CPU usage may spike The app must be force-quit to recover The hang occurs consistently and is reproducible Workaround 1: Replace inner LazyVStack with VStack LazyVStack { ForEach(...) { section in VStack { // ← Changed from LazyVStack ForEach(...) { row in ... } } } } Workaround 2: Embed in TabView TabView { NavigationStack { NestedLazyVStackView() // ← Same nested structure, but no hang } .tabItem { ... } } Interestingly, wrapping the entire navigation stack in a TabView prevents the hang entirely, even with the nested LazyVStack structure intact. Questions for Apple Is there a known issue with nested LazyVStack containers and accessibility traversal? Why does wrapping the view in a TabView prevent the hang? Are there recommended patterns for using nested lazy containers with accessibility support? Is this a timing issue, a deadlock, or an infinite loop in the accessibility system? Why that happens? Reproduction Project A complete, minimal reproduction project is available at: https://github.com/pendo-io/SwiftUI_Hang_Reproduction
4
0
270
1w
tabViewBottomAccessory in 26.1: View's @State is lost when switching tabs
Any view that is content for the tabViewBottomAccessory API fails to retain its state as of the last couple of 26.1 betas (and RC). The loss of state happens (at least) when the currently selected tab is switched (filed as FB20901325). Here's code to reproduce the issue: struct ContentView: View { @State private var selectedTab = TabSelection.one enum TabSelection: Hashable { case one, two } var body: some View { TabView(selection: $selectedTab) { Tab("One", systemImage: "1.circle", value: .one) { BugExplanationView() } Tab("Two", systemImage: "2.circle", value: .two) { BugExplanationView() } } .tabViewBottomAccessory { AccessoryView() } } } struct AccessoryView: View { @State private var counter = 0 // This guy's state gets lost (as of iOS 26.1) var body: some View { Stepper("Counter: \(counter)", value: $counter) .padding(.horizontal) } } struct BugExplanationView: View { var body: some View { ScrollView { VStack(alignment: .leading, spacing: 16) { Text("(1) Manipulate the counter state") Text("(2) Then switch tabs") Text("BUG: The counter state gets unexpectedly reset!") } .multilineTextAlignment(.leading) } } }
6
4
611
1w
UIHostingConfiguration focus problem on tvOS, with SwiftUI view
UIHostingConfiguration on tvOS: focus permanently broken with multiple focusable SwiftUI views Hi everyone, I'm working on a tvOS app with a UICollectionView. Some cells embed SwiftUI content via UIHostingConfiguration, specifically a row of 3 buttons that should be individually focusable. The cell itself returns canBecomeFocused = false so focus passes through to the SwiftUI buttons. The problem: after navigating focus into that section once, it becomes permanently unfocusable. Focus enters briefly, then immediately exits to nil on its own, without any user input. From that point on, the focus engine completely skips the section. The exact same SwiftUI view works perfectly when embedded via UIHostingController instead. How to reproduce Press DOWN to move focus into the UIHostingConfiguration section Focus lands on a SwiftUI button for a split second Focus exits on its own and bumps to another section The section is now dead, focus skips it on every subsequent navigation What the system logs say (-UIFocusLoggingEnabled YES) Right when focus enters, the system reports the SwiftUI focus items as "disappearing": Ignoring focus update request for disappearing focus environment <UIKitFocusSectionResponderItem> Then when searching for a new focusable item: <SwiftUI._UIInheritedView> → (warning) No focusable items found. <UIHostingContentView> → (warning) No focusable items found. === unable to find focused item in context. retrying with updated request. === The views are still in the hierarchy (verified by pointer), but the UIHostingContentView no longer exposes its virtual focus items. I also see mismatched parentFocusEnvironment on those items, pointing to a _UIHostingView from a completely different cell. What I've tried I've spent a lot of time on this with my colleagues, dug through the very limited documentation available online, and even used AI agents to help brainstorm. We tested 10 different approaches, none worked: Overriding preferredFocusEnvironments to point to the UIHostingContentView setNeedsFocusUpdate() / updateFocusIfNeeded(), rescan finds nothing Forcing UIKit redraws (setNeedsLayout, setNeedsDisplay) Removing .focusSection() Removing all SwiftUI animations, identical behavior Using canFocusItemAt: delegate instead of cell subclass, identical remembersLastFocusedIndexPath = true, causes a separate focus trap configurationUpdateHandler + setNeedsUpdateConfiguration(), config is rebuilt but virtual items stay deregistered Verified the UIHostingContentView never leaves the hierarchy. It doesn't, its internal state is just corrupted My workaround I switched to UIHostingController with proper view controller containment. It works because the hosting controller is a full UIFocusEnvironment, so the focus engine can traverse it and it correctly maintains its virtual items. Has anyone encountered this? Is there a known pattern for using UIHostingConfiguration on tvOS with multiple focusable SwiftUI elements? Or should I just file a Feedback? Thanks for any help!
1
0
67
1w
Prevention of ScreenShot and ScreenRecording in an iOS app
In my app i need to restrict the user to take screenshot or screen recording . i used the following code snippet, let field = UITextField() let view = UIView(frame: CGRect(x: 0, y: 0, width: field.frame.self.width, height: field.frame.self.height)) // Following view can be customised if required let newView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)) newView.backgroundColor = .black field.isSecureTextEntry = true window.addSubview(field) view.addSubview(newView) window.layer.superlayer?.addSublayer(field.layer) //field.layer.sublayers?.last!.addSublayer(window.layer) if let lastSublayer = field.layer.sublayers?.last { lastSublayer.addSublayer(window.layer) } field.leftView = view field.leftViewMode = .always My query is will below lines meet the Apple compliance? will ther be any rejection while publishing to Appstore? window.layer.superlayer?.addSublayer(field.layer) field.layer.sublayers?.last!.addSublayer(window.layer).
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
84
1w
How to disable highlight state on Link in LA widget
I am working on a Live Activity widget. In it, I want some of the elements to open different deeplink URLs. I have found that assigning multiple widgetURL doesn't work, only one of the URLs gets opened no matter where you tap. I also found that Buttons don't seem to do anything, tapping them actually just open my app as if I just tapped a naked Live Activity. I have found that really only Link elements work if I want to open different URLs upon tapping different elements. And Links are cool and fine, but I am seeing that on tap, my elements become tinted... As in, there is a highlighted state, and it makes the elements inside blue. I have tried to use button style API on a link, but it didn't work. How can I disable the highlighted state for a Link element in a live activity widget?
1
0
123
1w
Wrong position of searchable component on first render
Hey all, I found a weird behaviour with the searchable component. I created a custom bottom nav bar (because I have custom design in my app) to switch between screens. On one screen I display a List component with the searchable component. Whenever I enter the search screen the first time, the searchable component is displayed at the bottom. This is wrong. It should be displayed at the top under the navigationTitle. When I enter the screen a second time, everything is correct. This behaviour can be reproduced on all iOS 26 versions on the simulator and on a physical device with debug and release build. On iOS 18 everything works fine. Steps to reproduce: Cold start of the app Click on Search TabBarIcon (searchable wrong location) Click on Home TabBarIcon Click on Search TabBarIcon (searchable correct location) Simple code example: import SwiftUI struct ContentView: View { @State var selectedTab: Page = Page.main var body: some View { NavigationStack { ZStack { VStack { switch selectedTab { case .main: MainView() case .search: SearchView() } } VStack { Spacer() VStack(spacing: 0) { HStack(spacing: 0) { TabBarIcon(iconName: "house", selected: selectedTab == .main, displayName: "Home") .onTapGesture { selectedTab = .main } TabBarIcon(iconName: "magnifyingglass", selected: selectedTab == .search, displayName: "Search") .onTapGesture { selectedTab = .search } } .frame(maxWidth: .infinity) .frame(height: 55) .background(Color.gray) } .ignoresSafeArea(.all, edges: .bottom) } } } } } struct TabBarIcon: View { let iconName: String let selected: Bool let displayName: String var body: some View { ZStack { VStack { Image(systemName: iconName) .resizable() .renderingMode(.template) .aspectRatio(contentMode: .fit) .foregroundColor(Color.black) .frame(width: 22, height: 22) Text(displayName) .font(Font.system(size: 10)) } } .frame(maxWidth: .infinity) } } enum Page { case main case search } struct MainView: View { var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") } .padding() .navigationTitle("Home") } } struct SearchView: View { @State private var searchText = "" let items = [ "Apple", "Banana", "Pear", "Strawberry", "Orange", "Peach", "Grape", "Mango" ] var filteredItems: [String] { if searchText.isEmpty { return items } else { return items.filter { $0.localizedCaseInsensitiveContains(searchText) } } } var body: some View { List(filteredItems, id: \.self) { item in Text(item) } .navigationTitle("Fruits") .searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always), prompt: "Search") } }
2
0
132
1w
Seeking Guidance: How to Launch a Privacy-First Messaging App with Maximum Impact
Hi everyone, I’m building a messaging app because I’ve seen firsthand how much support and safety is overlooked for this generation online. My goal is to give teens a foundation of security, privacy, and mental health support, while still letting them connect freely. I want to leverage Apple’s platform to help this mission reach the right audience and have real impact. The app already includes: Community chat with message blurring for sensitive or harmful words. Anti-shoulder surfing tools to protect private conversations. Shake dashboard for quick access to emergency services. In-chat locks with ML detection for grooming patterns, offering resources while respecting privacy. Full user control: messages can be deleted anytime, blocking is permanent, and accounts can’t bypass restrictions on the same device. User consent-first design: every feature is opt-in and controlled by the user. At this point, I’m looking for guidance on how to position and prepare the app to reach Apple editorial or headline attention — what steps or best practices help mission-driven apps get noticed for features, WWDC spotlights, or App Store promotion? My focus isn’t just on improving the app, but on launch strategy and visibility in a way that amplifies the mission responsibly. If it’s helpful, I can share a TestFlight build or walkthrough to illustrate the app in action. Thank you for any insights or advice — I want to make sure this mission has the best chance to reach and support the generation it’s built for.
0
0
88
1w
RealityKit_DirectionalLight_Question
My application calculates three distinct Meesus Double [x, y, z] Radian values to light a sphere in RealityKit with DirectionalLight. It is my understanding that I must use (simd_quatf) for each radian value to properly light the sphere in the view. The code correctly [orientates] the sphere with the combined (simd_quatf) DirectionalLight in the view, but the illumination (Z-axis) fails to properly illuminate the sphere with the expected result, compared to associated Meesus web page images. For the moment, I do not know how to correct the (Z-axis). Curious for a suggestion ... :] // Location values. let theLatitude: Double = 51.13107260 let theLongitude: Double = -114.01127910 let currentDate: Date = Date() struct TheCalculatedMoonPhaseTest_ContentView: View { var body: some View { VStack { if #available(macOS 15.0, *) { RealityView { content in let moonSphere_Entity = Entity.createSphere(radius: 0.90, color: .black) moonSphere.Entity.name = "MoonSphere" moonSphere.Entity.position = SIMD3<Float>(x: 0, y: 0, z: 0) content.add(moonSphere.Entity) let sunLight_Entity = createDirectionalLight(latitude: theLatitude, longitude: theLongitude, date: currentDate) content.add(sunLight_Entity) } // End of [RealityView] } else { // Earlier version required. } // End of [if #available(macOS 15.0, *)] } // End of [VStack] .background(Color.black) } // End of [var body: some View] // MARK: - 🟠🟠🟠🟠 [SET THE BACKGROUND COLOUR] 🟠🟠🟠🟠 var backgroundColor: Color = Color.init(.black) // MARK: - 🟠🟠🟠🟠 [CREATE THE DIRECTIONAL LIGHT FOR THE SPHERE] 🟠🟠🟠🟠 func createDirectionalLight(latitude: Double, longitude: Double, date: Date) -> Entity { let directionalLight = DirectionalLight() directionalLight.light.color = .white directionalLight.light.intensity = 1000000 directionalLight.shadow = DirectionalLightComponent.Shadow() directionalLight.shadow?.maximumDistance = 5 directionalLight.shadow?.depthBias = 1 // MARK: 🟠🟠🟠🟠 Retrieve the [MEESUS MOON AGE VALUES] from the [CONSTANT FOLDER] 🟠🟠🟠🟠 let theMeesusMoonAge_LunarAgeDaysValue = 25.90567592898601 if theMeesusMoonAge_LunarAgeDaysValue >= 23.10 && theMeesusMoonAge_LunarAgeDaysValue < (29.530588853 - 1.00) { let someCalculatedX_WestEastRadian: Float = Float(1.00) // Identify the sphere’s DirectionalLight Tilt Angle (Y) radian value :: // Note :: The following Tilt Angle is corrected to [Zenith] with the [MeesusCalculatedTilt_Angle] minus the [MeesusCalculatedPar_Angle]. let someCalculatedY_TiltAngleRadian: Float = Float(1.3396086) // Identify the sphere’s DirectionalLight Illumination (Z) radian Value :: // Note :: The Meesus calculated illumination fraction is converted to degrees, then converted to a radian value. let someCalculatedZ_IlluminationAngleRadian: Float = Float(0.45176168630244457) // <=== 14.3800% Illumination. // Define rotation angles in radians for X, Y, and Z axes. let x_Radians = someCalculatedX_WestEastRadian let y_Radians = someCalculatedY_TiltAngleRadian let z_Radians = someCalculatedZ_IlluminationAngleRadian // Identify and separate the quaternion [simd_quatf] for each Radian. let q_X = simd_quatf(angle: x_Radians, axis: SIMD3<Float>(1, 0, 0)) let q_Y = simd_quatf(angle: y_Radians, axis: SIMD3<Float>(0, 1, 0)) let q_Z = simd_quatf(angle: z_Radians, axis: SIMD3<Float>(0, 0, 1)) // Apply and combine the rotations, where order matters. let combinedRotation = q_Z * q_Y * q_X // Identify the [Combined Rotation]. // The [MyMoonMeesus] :: [WANING CRESCENT] calculated [combinedRotation] :: simd_quatf(real: 0.73715997, imag: SIMD3<Float>(0.24427173, 0.61516714, -0.13599981)) ° Radians // Normalize the [combinedRotation]. let theNormalizesRotation = simd_normalize(combinedRotation) // Identify the [Normalized Combined Rotation]. // The [MyMoonMeesus] :: [WANING CRESCENT] calculated [normalizedRotation] :: simd_quatf(real: 0.73715997, imag: SIMD3<Float>(0.24427173, 0.61516714, -0.13599981)) ° Radians // Assume the [theNormalizesRotation] appears reversed. let theCorrectedRotation = theNormalizesRotation.inverse // Identify the [Reversed Combined Rotation]. // The [MyMoonMeesus] :: [WANING CRESCENT] calculated [correctedRotation] :: simd_quatf(real: 0.73715997, imag: SIMD3<Float>(-0.24427173, -0.61516714, 0.13599981)) ° Radians // Apply the [Corrected Rotation] to the entity. directionalLight.transform.rotation *= theCorrectedRotation // Add the [directionalLight] to the scene :: let anchor = AnchorEntity() anchor.addChild(directionalLight) } // End of [if theMeesusMoonAge_LunarAgeDaysValue >= 23.10 && theMeesusMoonAge_LunarAgeDaysValue < (29.530588853 - 1.00)] return directionalLight } // End of [func createDirectionalLight(latitude: Double, longitude: Double, date: Date) -> Entity] } // End of [struct TheCalculatedMoonPhaseTest_ContentView: View] // MARK: 🟠🟠🟠🟠 [ENTITY HELPER EXTENSION] 🟠🟠🟠🟠 extension Entity { static func createSphere(radius: Float, color: NSColor) -> Entity { let mesh = MeshResource.generateSphere(radius: radius) var material = PhysicallyBasedMaterial() material.baseColor = .init(tint: color) let modelComponent = ModelComponent(mesh: mesh, materials: [material]) let entity = Entity() entity.components.set(modelComponent) entity.components.set(Transform()) return entity } // End of [static func createSphere(radius: Float, color: NSColor) -> Entity] } // End of [extension Entity] // Application Image :: Calgary // Website Image :: timeanddate // mooncalc.org
1
0
132
1w
Intrinsic content/system fitting size not propagating up to hosting controller.
Overview I have the following view hierarchy that mixes SwiftUI and UIKit: AccordionView └─ VStack ├─ Text ├─ Button └─ UIViewRepresentable └─ UIStackView ├─ UILabel └─ UILabel When tapping the button, the UIViewRepresentable hides and shows its content. This all works as expected. However, in certain circumstances the view's sizing is rendered with the correct size, but the text can often render incorrectly, despite the frame seemingly looking as though it has enough room to render the text. More info Below you can see the UILabel has the correct frame height (the light grey background and coloured borders) but the text is rendered as though it has infinite width along one line. There's a few configurations of my view hierarchy that seem to have this effect. I've added a playground to the bottom of this post of various configurations to show what does and doesn't work, just copy and paste to see for yourself... It seems of the ones that don't work, there's a couple of reasons why that may be: HostedView and TextViewContainer do not do the following (I think we only need to do one of these things for auto layout/stack views to work effectively): a) implement an intrinsic content size b) return a 'good' size for systemLayoutSizeFitting(). UIHostingController shouldn't use intrinsic size (although I'm sure it should) Something related to setting setContentCompressionResistancePriority() or setContentHuggingPriority() but having played about with this it doesn't seem relevant here... I've played around with everything I can think of here but can't find a solution that works for all, although I'm 99% sure it's one or all of the points above. If there are any UIKit gurus out there that can help that would be great! Ive already spent so much time on this 🫨 Playground Swift Playground
0
0
93
2w
Driving NavigationSplitView with something other than List?
Is it possible to drive NavigationSplitView navigation with a view in sidebar (left column) that is not a List? All examples that I have seen from this year only contain List in sidebar. I ask this because I would like to have a more complex layout in sidebar (or first view on iOS) that contains a mix of elements, some of them non-interactive and not targeting navigation. Here’s what I would like to do: import SwiftUI struct Thing: Identifiable, Hashable {     let id: UUID     let name: String } struct ContentView: View {     let things: [Thing]     @State private var selectedThingId: UUID?          var body: some View {         NavigationSplitView {             ScrollView(.vertical) {                 VStack {                     ForEach(things) { thing in                         Button("Thing: \(thing.name) \( selectedThingId == thing.id ? "selected" : "" )") {                             selectedThingId = thing.id                         }                     } SomeOtherViewHere() Button("Navigate to something else") { selectedThingId = someSpecificId }                 }             }         } detail: {             // ZStack is workaround for known SDK bug             ZStack {                 if let selectedThingId {                     Text("There is a thing ID: \(selectedThingId)")                 } else {                     Text("There is no thing.")                 }             }         }     } } This actually works as expected on iPadOS and macOS, but not iOS (iPhone). Tapping changes the selection as I see in the button label, but does not push anything to navigation stack, I remain stuck at home screen. Also filed as FB10332749.
14
5
7.1k
2w
SwiftUI .toolbar(placement: .keyboard) item not exposed to accessibility on iOS 26.1 (affects VoiceOver + XCUITest)
Description On iOS 26.1, a ToolbarItem placed in .keyboard is no longer exposed to the accessibility hierarchy. As a result: VoiceOver cannot focus or activate the toolbar button XCUITest cannot discover the element, making the UI impossible to test TextEditor() .toolbar { ToolbarItem(placement: .keyboard) { Button("Done") { /* action */ } } } This worked correctly on previous iOS versions. The button appears visually but is missing from both VoiceOver navigation and XCUI accessibility queries. Steps to Reproduce Create a new SwiftUI project. Use a simple text field with a keyboard toolbar button. Run on an iOS 26.1 device or simulator. Focus the text field to show the keyboard. Turn on VoiceOver and attempt to navigate to the toolbar button. Run an XCUITest attempting to locate the button
2
1
183
2w
.edgesIgnoringSafeArea(.vertical) combined with .tabViewStyle(.page(indexDisplayMode: .never)) causes "Out of Bounds" layout in Xcode 26 / iOS 26 SDK
I am reporting a regression/behavioral change in the SwiftUI layout engine when building with Xcode 26 (iOS 26 SDK). In previous versions (Xcode 15/16 and iOS 17/18 SDKs), a TabView using .tabViewStyle(.page(indexDisplayMode: .never)) correctly respected the coordinate space when combined with .edgesIgnoringSafeArea(.vertical). However, when compiling with the iOS 26 SDK, the internal views of the TabView render "out of bounds," pushing content vertically beyond the intended safe area boundaries and causing UI overlapping/clipping - an abnormal behavior. TabView(selection: $selectedIndex) { ForEach(0..<data.count, id: \.self) { index in nextPreviousHandlerView(id: data[index]) .tag(index) } } .tabViewStyle(.page(indexDisplayMode: .never)) .edgesIgnoringSafeArea(.vertical) // Causes vertical "jump" out of bounds in Xcode 26
0
0
46
2w
Smooth appearance switching
Hello every developers. I need your help. Do you know how to attach animation to appearance, like a smooth transition from dark to light and vise versa. My code here: @main struct The_Library_of_BabelonApp: App { @AppStorage("selectedAppearance") private var selectedAppearance = 0 @StateObject private var router = AppRouter() var scheme: ColorScheme? { if selectedAppearance == 1 { return .light } if selectedAppearance == 2 { return .dark } return nil } var body: some Scene { WindowGroup { RootView() .preferredColorScheme(scheme) .environmentObject(router) // this is doesn't work correctly .animation(.smooth(duration: 2), value: selectedAppearance) } } } And my appearance switching looks: struct SettingsView: View { @AppStorage("selectedAppearance") private var selectedAppearance = 0 var body: some View { List { Section(header: Text("Appearance")) { HStack(spacing: 20) { ThemePreview(title: "Light", imageName: "lightTheme", tag: 1, selection: $selectedAppearance) ThemePreview(title: "Dark", imageName: "darkTheme", tag: 2, selection: $selectedAppearance) ThemePreview(title: "System", imageName: "systemMode", tag: 0, selection: $selectedAppearance) } .padding(.vertical, 10) .frame(maxWidth: .infinity) } } } } struct ThemePreview: View { let title: String let imageName: String let tag: Int @Binding var selection: Int var body: some View { Button { selection = tag } label: { VStack { Image(imageName) .resizable() .aspectRatio(contentMode: .fill) .frame(width: 120, height: 80) .clipShape(RoundedRectangle(cornerRadius: 12)) .overlay( RoundedRectangle(cornerRadius: 12) .stroke(selection == tag ? Color.blue : Color.clear, lineWidth: 3) ) Text(title) .font(.caption) .foregroundColor(selection == tag ? .blue : .primary) } } .buttonStyle(.plain) } } I guess my code works but animation working another way, its turn my Section, I don't know.... Thank you in advance
1
0
50
2w
Swipe to go back still broken with Zoom navigation transition.
When you use .navigationTransition(.zoom(sourceID: "placeholder", in: placehoder)) for navigation animation, going back using the swipe gesture is still very buggy on IOS26. I know it has been mentioned in other places like here: https://developer.apple.com/forums/thread/796805?answerId=856846022#856846022 but nothing seems to have been done to fix this issue. Here is a video showing the bug comparing when the back button is used vs swipe to go back: https://imgur.com/a/JgEusRH I wish there was a way to at least disable the swipe back gesture until this bug is fixed.
8
2
516
2w
External Keyboard DatePicker Issues
I am currently trying to get my app ready for full external keyboard support, while testing I found an issue with the native DatePicker. Whenever I enter the DatePicker with an external keyboard it only jumps to the time picker and I am not able to move away from it. Arrow keys don't work, tab and control + tab only move me to the toolbar and back. This is how they look like private var datePicker: some View { DatePicker( "", selection: date, in: minDate..., displayedComponents: [.date] ) .fixedSize() .accessibilityIdentifier("\(datePickerLabel).DatePicker") } private var timePicker: some View { DatePicker( "", selection: date, in: minDate..., displayedComponents: [.hourAndMinute] ) .fixedSize() .accessibilityIdentifier("\(datePickerLabel).TimePicker") } private var datePickerLabelView: some View { Text(datePickerLabel.localizedString) .accessibilityIdentifier(datePickerLabel) } And we implement it like this in the view: HStack { datePickerLabelView Spacer() datePicker timePicker } Does anyone know how to fix this behavior? Is it our fault or is it the system? The issue comes up both in iOS 18 and 26.
0
2
258
2w
Image not rendering on some devices
Hi, new developer here. I have an issue where an image I have on app is not showing up on some devices. The image is: Resources/Assets/logo: I am using it in my app like: ZStack { Color.white .ignoresSafeArea() VStack { Spacer() Image("logo") Spacer() Text(dateString) .font(.custom("LinLibertine", size: 17)) .fontWeight(.bold) .tracking(5) .padding(.bottom, 50) } } The image appears fine on all simulators. And also on my real device iPad with A14. But when I run it on iPhone 8 or iPad Air M4, it shows empty space in place of image. I tried many different options like: Image("logo") .renderingMode(.original) .resizable() .scaledToFit() frame(width: 300) .background(Color.red.opacity(0.3)) But nothing works. What can be the issue?
2
1
121
2w
SwiftUI mysterious behavior
Hello dear developers! Recently, I stumbled upon some really strange behavior of SwiftUI and I’m very curious why it works this way struct ContentView: View { @State private var title: String? @State private var isSheetPresented: Bool = false var body: some View { Button("Hello, world!") { title = "Sheet title" isSheetPresented = true } .sheet(isPresented: $isSheetPresented, content: { if let title { Text(title) } else { EmptyView() } }) } } Why in this case when we tap the button and sheet comes in we go to the branch else even though we set title before isSheetPresented but it still somehow nil But what really drive me crazy is that if we change a little bit code to this: I just added another @State property 'number' and use it as the Button's title. In this scenario it works 😃 and Text in the sheet view appearing struct ContentView: View { @State private var title: String? @State private var number = 0 @State private var isSheetPresented = false var body: some View { Button("\(number)") { title = "Sheet title" number += 0 isSheetPresented = true } .sheet(isPresented: $isSheetPresented, content: { if let title { Text(title) } else { EmptyView() } }) } } Is this somehow related to what happens under the hood like View Tree and Render Tree (Attribute Graph)? Maybe because ContentView’s body doesn't capture title it cannot be stored in the Render Tree so it always would have the initial value of nil? if there are any well-informed folks here, please help me figure out this mystery, I’d appreciate it!!! p.s. Don’t get me wrong. Im not interested in how to make it work. I’m interested in why this doesn’t work and what really happens under the hood that led to this result
2
0
137
2w