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

iOS 27 beta 1: .scrollEdgeEffectStyle(.soft) renders fully transparent above safeAreaBar
Feedback ID: FB23086400 On iOS 27 beta 1, .scrollEdgeEffectStyle(.soft, for: .top) on a List underneath a custom .safeAreaBar(edge: .top) no longer renders the progressive fade-blur. The top edge is fully transparent — scrolled rows pass under the bar with no visual treatment at all, as if scrollEdgeEffectDisabled() had been applied. What I've verified so far: .hard renders correctly in the exact same hierarchy; only .soft is affected. The same binary works correctly on iOS 26.x Xcode preview. I'm building with Xcode 26.3 (iOS 26 SDK). Minimal reproduction: import SwiftUI struct EdgeEffectRepro: View { enum Style: String, CaseIterable, Identifiable { case automatic, soft, hard var id: Self { self } var value: ScrollEdgeEffectStyle { switch self { case .automatic: .automatic case .soft: .soft case .hard: .hard } } } @State private var style: Style = .soft @State private var useSystemBarOnly = false var body: some View { NavigationStack { List(0..<60, id: \.self) { i in Text("Row \(i)") .frame(maxWidth: .infinity, alignment: .leading) .listRowBackground( i.isMultiple(of: 2) ? Color.orange.opacity(0.45) : Color.teal.opacity(0.45) ) } .scrollIndicators(.hidden) .scrollEdgeEffectStyle(style.value, for: .top) .safeAreaBar(edge: .top) { if !useSystemBarOnly { VStack(spacing: 8) { HStack { Text("Custom Top Bar") .font(.system(size: 28, weight: .bold)) Spacer() } HStack { Text("Second row (e.g. date range picker)") .font(.caption) .foregroundStyle(.secondary) Spacer() } } .padding(.horizontal) } } .safeAreaInset(edge: .bottom) { VStack(spacing: 8) { Picker("Edge effect style", selection: $style) { ForEach(Style.allCases) { Text($0.rawValue).tag($0) } } .pickerStyle(.segmented) Toggle("System bar only (control group)", isOn: $useSystemBarOnly) .font(.caption) } .padding() .background(.regularMaterial) } .navigationTitle("EdgeEffect Repro") .navigationBarTitleDisplayMode(.inline) } } } Steps: run on iOS 27 beta 1, set the picker to soft, scroll rows under the bar. Expected: fade-blur as on iOS 26. Actual: fully transparent. Switch to hard: renders fine.
8
10
1.3k
1h
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) } } }
8
4
948
2h
ShareLink with Collaboration in SwiftUI with a Document based app
Hello to anyone reading this. I am a bit lost as to what is the correct approach for enabling Collaboration for a Document based SwiftUI app. If I understand correctly, after setting up all the relevant entitlements and capabilities for enabling sharing, you only need to use ShareLink to begin a collaboration/send a copy by passing in the URL of the document. The collaboration is then handled with SWCollaborationView, which there have been NSViewRepresentable wrapper implementations posted around the web. My main question is; how do I know whether the document has been shared to create a collaboration? Do I have to have 2 sharing ToolbarItems? Basically, is there any documentation for implementing collaborations from a document based app, other than simply saying that starting a share is done by passing the url into a ShareLink? This seems to massively missing, or have I massively missed something?
0
0
25
18h
iOS 26: Enabling "Reduce Transparency" causes a persistent white bar where the tab bar was hidden, blocking user interaction
Hi everyone, We're experiencing a bug on iOS 26 that only occurs when the user has Reduce Transparency enabled in Accessibility settings. App structure: Our app uses a TabView with a standard tab bar. Inside each tab, we use a NavigationStack. The tab bar is visible on root-level screens, and hidden on all pushed destinations using: .toolbar(.hidden, for: .tabBar) The problem: On iOS 26 with Reduce Transparency off (Liquid Glass active) — everything works correctly. The tab bar hides as expected. On iOS 26 with Reduce Transparency on — a white bar appears at the bottom of the screen in every place where the tab bar is hidden. This white bar: Overlaps content at the bottom of the screen. Blocks scroll, tap, and all user interactions in that area. We also tried: .toolbarBackground(.hidden, for: .tabBar) Removing all custom UITabBarAppearance configuration The only workaround we found is setting UIDesignRequiresCompatibility = YES in Info.plist, which reverts the entire app to the pre-iOS 26 design — not a viable long-term solution. What can we do? Thanks in advance.
4
1
513
19h
SwiftUI NavigationSplitView sidebar toolbar has excessive top inset when embedded in TabView since iPadOS 26.4
I’m seeing a layout regression in SwiftUI on iPadOS 26.4 involving NavigationSplitView inside a TabView. When a NavigationSplitView is embedded in a TabView, the sidebar toolbar appears to reserve too much vertical space. There is a large vertical gap between the top edge of the sidebar and the sidebar collapse/toggle icon. It looks as if the sidebar toolbar itself has become much taller than expected. The same NavigationSplitView layout is rendered correctly when it is shown directly without being embedded in a TabView. Environment: iPadOS 26.4 or later SwiftUI iPad TabView NavigationSplitView inside one tab Expected behavior The sidebar toolbar should use its normal height, as it does when the same NavigationSplitView is shown without a surrounding TabView. The sidebar collapse/toggle icon should appear close to the top of the sidebar, without a large empty gap above it. Actual behavior When the NavigationSplitView is hosted inside a TabView, the sidebar toolbar area becomes excessively tall. A large empty space appears above the sidebar collapse/toggle icon. This only happens in the TabView setup. Rendering the same NavigationSplitView directly does not show the issue. Feedback I also filed this as Feedback Assistant report: FB22645938 Has anyone else seen this behavior since iPadOS 26.4? Is this an intentional layout change, or is there a supported way to avoid this additional top inset when using NavigationSplitView inside TabView? Reproduction import SwiftUI struct ContentView: View { enum AppTab { case first case second } @State private var selectedTab: AppTab = .first var body: some View { TabView(selection: $selectedTab) { Tab("First", systemImage: "sidebar.leading", value: .first) { NavigationSplitView { List { Section("Sidebar Content") { ForEach(1...20, id: \.self) { index in Text("Item \(index)") } } } .navigationTitle("Sidebar") .toolbar { ToolbarItem(placement: .topBarLeading) { Button { // action } label: { Image(systemName: "plus") } } } } detail: { Text("Detail") } } Tab("Second", systemImage: "doc", value: .second) { Text("Second tab") } } } }
3
3
599
19h
Did VisionOS27 get the LazyVGrid Performance Updates?
Did VisionOS get the LazyVGrid Performance Updates that other platforms received? I’m observing that a LazyVGrid that works well on iPhone, iPad, and Mac appears to hitch and jitter as cells exit and renter the lazyVGrid on VisionOS. It really feels like it did not get the same behavior changes as the other platforms. I observe the scrollbar expands as cells leave the top of the grid, and each “exit” of a row seems to cause a hitch. I’ve got rigidly defined cell frames, rigidly defined columns. I don’t think any cells frames are being invalidated during scroll… (there’s no way to check this with instruments, right?) I‘ve made several analysis passes myself and threw the Xcode Agent with Codex at it just to scan for stuff, but it’s starting to just guess at things. Any known issues with VisionOS?
5
0
539
21h
SwiftUI macOS Preview Crash When Using Custom Row Directly Inside List
I’ve hit a strange SwiftUI preview crash that happens on macOS previews when using a view inside a List’s ForEach, resulting in the error Fatal Error in TableViewListCore_Mac2.swift. Only crashes macOS preview - iPhone/iPad preview doesn't crash. Doesn't crash when actually running the app. Here’s a minimal reproducible example, causing the preview to crash. XCode: Version 26.0.1 (17A400) MacOS: 26.0.1 (25A362) import SwiftUI struct Item: Identifiable { let id = UUID() let name: String } struct ItemRow: View { let item: Item var body: some View { HStack { Button(action: {}) { Image(systemName: "play") } Text(item.name) Spacer() ProgressView() } } } struct ContentView: View { @State private var items = [ Item(name: "Item A"), Item(name: "Item B"), ] var body: some View { List { ForEach(items) { item in ItemRow(item: item) } } } } #Preview("Content view") { ContentView() } #Preview("Item row") { ItemRow(item: Item(name: "Item A")) } If I wrap the row in a container, like this: ForEach(items) { item in ZStack { ItemRow(item: item) } } the crash seems to disappear. Has anyone else seen this behavior? What might I be doing wrong? Any ideas about what could be causing this?
3
1
760
22h
Best path for a 14-year-old student to begin Swift development using an iPad
Hello, My 14-year-old daughter is beginning high school in Florida and is interested in learning Swift and developing applications for Apple platforms. She currently has an iPad and iPhone but does not yet have access to a Mac. We understand that Swift Playground can be used on iPad, while Xcode requires a Mac. We would appreciate guidance on the best learning path for a beginner in her situation: Which official Apple Swift or SwiftUI curriculum should she begin with? How much can she realistically learn and build using Swift Playground on an iPad? At what stage would access to Xcode on a Mac become necessary? Can an app playground started on iPad later be transferred to Xcode on a Mac? Are there recommended Swift Coding Clubs, education programs, or student resources for high-school students in the United States? What should she focus on during her first year if she eventually wants to participate in the Swift Student Challenge? She is motivated to learn correctly from the beginning and build her first small app playground. Thank you for any guidance or educational resources you can provide.
5
0
1k
3d
Different keyboards show up for KeyboardType .decimalPad
Environment: iOS 26; iPad Mini/Air/Pro Problem: In a TextField, I am using a keyboard with the type .decimalPad. When I initially tap into the TextField, the "popover" keyboard (i.e. the decimalPad) shows up and focusses the TextField. However, when I click outside the TextField (to dismiss the keyboard), the TextField is still focussed (the keyboard was dismissed though). When reentering in the TextField, another keyboard (from the bottom of the screen) appears (most likely .numeric). Does anybody know how to solve this? What I already tried: I tried listening to the dismissal of the keyboard to manually set the FocusState to nil. However, the dismissal of the "popover/decimal" keyboard is not recognized as such a dismissal. I also tried to build a custom component out of that, but then I lose the TextField behavior, conflicting with HIG.
3
0
500
5d
ManipulationComponent + Warning messages in RealityView
Hi guys! I wanted to study this new ManipulationComponent(), but I keep getting a warning that I don’t understand, even in a very simple scenario. i don't have any collisions just binding the Manipulation the warning message is : ** Entity returned from EntityWrapper.makeEntity(context:) was already parented to another entity. This is not supported and may lead to unexpected behavior. SwiftUI adds entities to internally-managed entity hierarchies.** RealityView { content, attachments in if let loadedModel = try? await Entity(named: "cloud_glb", in: realityKitContentBundle) { content.add(loadedModel) loadedModel.components.set(ManipulationComponent()) } Thanks !
4
0
655
6d
Pinch gesture not recognized on MTKView when attaching it to a RealityView using a ViewAttachmentComponent in a immersive space
Hello! We are seeing a problem with a SwiftUI view that wraps an MTKView and that MTKView uses gesture recognizers from UIKit. One of those gestures we are using is UIPinchGestureRecognizer. And that gesture isn’t recognized at all when the SwiftUI view is attached to a RealityView using the ViewAttachmentComponent AND the RealityView is being shown in an ImmersiveSpace. If the SwiftUI view is attached to the RealityView using the init that has an attachment closure then pinching works fine there. So this definitely seems like a bug. Here is some code to help you reproduce the problem. Run this on a Vision Pro device. A simple red square will be rendered and if a single tap or pinch gesture is recognized on the red square, it will print to the console. App Code: import SwiftUI @main struct VisionPinchProblemsApp: App { var body: some Scene { WindowGroup { MenuView() } ImmersiveSpace(id: "RedSquare") { RedSquareView() } } } View code: import MetalKit import RealityKit import SwiftUI import UIKit struct MenuView: View { @Environment(\.openImmersiveSpace) private var openImmersiveSpace @Environment(\.dismissImmersiveSpace) private var dismissImmersiveSpace @State private var showImmersiveSpace = false @State private var immersiveSpaceIsOpen = false var body: some View { Form { Toggle("Show red square", isOn: $showImmersiveSpace) .task(id: showImmersiveSpace) { if showImmersiveSpace { await openImmersiveSpace(id: "RedSquare") immersiveSpaceIsOpen = true } else { if immersiveSpaceIsOpen { await dismissImmersiveSpace() immersiveSpaceIsOpen = false } } } } .onDisappear { // Attempt to close the immersive space on the way out. Task { if immersiveSpaceIsOpen { await dismissImmersiveSpace() } } } } } struct RedSquareView: View { let metalViewAttachmentID = "metalID" var body: some View { // Adds SwiftUI view using attachments closure. // Pinching and single taps are recognized here! // RealityView { content, attachments in // if let metalViewEntity = attachments.entity(for: metalViewAttachmentID) { // metalViewEntity.position = [0, 1, -1.25] // content.add(metalViewEntity) // } // } placeholder: { // ProgressView() // } attachments: { // Attachment(id: metalViewAttachmentID) { // MetalView() // } // } // Add SwiftUI view using ViewAttachmentComponent. // Pinching is not recognized here! // Single tapping is recognized ! // Why doesn't the red square show up in the Vision Pro simulator? RealityView { content in let metalViewEntity = Entity() let metalView = MetalView() .frame(width: 500, height: 500) let component = ViewAttachmentComponent(rootView: metalView) metalViewEntity.components.set(component) metalViewEntity.position = [0, 1, -1.25] content.add(metalViewEntity) } placeholder: { ProgressView() } } } struct MetalView: UIViewRepresentable { var device: MTLDevice? init() { self.device = MTLCreateSystemDefaultDevice() } func makeUIView(context: Context) -> MTKView { let mtkView = MTKView() mtkView.device = device mtkView.clearColor = MTLClearColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0) mtkView.delegate = context.coordinator let pinchGesture = UIPinchGestureRecognizer(target: context.coordinator, action: #selector(context.coordinator.handlePinch(_:))) mtkView.addGestureRecognizer(pinchGesture) let tapGesture = UITapGestureRecognizer(target: context.coordinator, action: #selector(context.coordinator.handleTap(_:))) mtkView.addGestureRecognizer(tapGesture) return mtkView } func updateUIView(_ uiView: MTKView, context: Context) { } func makeCoordinator() -> Coordinator { Coordinator(self) } class Coordinator: NSObject, MTKViewDelegate { var parent: MetalView init(_ parent: MetalView) { self.parent = parent } func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) { } func draw(in view: MTKView) { guard let drawable = view.currentDrawable else { return } guard let descriptor = view.currentRenderPassDescriptor else { return } let commandQueue = parent.device?.makeCommandQueue() let commandBuffer = commandQueue?.makeCommandBuffer() let renderEncoder = commandBuffer?.makeRenderCommandEncoder(descriptor: descriptor) renderEncoder?.endEncoding() commandBuffer?.present(drawable) commandBuffer?.commit() } @objc func handlePinch(_ sender: UIPinchGestureRecognizer) { print("Pinch detected") } @objc func handleTap(_ sender: UITapGestureRecognizer) { print("Tap detected") } } }
1
0
423
1w
ManipulationComponent causes makeUIView(context:) to get called twice
Here I have some demo code that is rendering a cylinder "platter" using RealityKit and there is a red circle rendered on top of it which uses Metal and SwiftUI. When the platter appears you will see in the console that makeUIView(context:) is called twice while it is documented that it will only be called once when the view appears for the first time. So this seems like a bug. If you remove ManipulationComponent from the platter's components you will see that this problem goes away so it seems like that is the cause of the problem. Any insight here would be appreciated! Thank you. Here is what is printed in the console: Entity returned from EntityWrapper.makeEntity(context:) was already parented to another entity. This is not supported and may lead to unexpected behavior. SwiftUI adds entities to internally-managed entity hierarchies. Make UI View! This should be called once. Make UI View! This should be called once. Here is the app code: import SwiftUI @main struct SomeApp: App { var body: some Scene { WindowGroup { ContentView() } ImmersiveSpace(id: "TableTop") { TableTopPlatterView() } } } Here is the view code: import MetalKit import RealityKit import SwiftUI struct ContentView: View { @Environment(\.openImmersiveSpace) private var openImmersiveSpace @Environment(\.dismissImmersiveSpace) private var dismissImmersiveSpace @State private var showImmersiveSpace = false @State private var immersiveSpaceIsOpen = false var body: some View { Form { Toggle("Show table top", isOn: $showImmersiveSpace) .task(id: showImmersiveSpace) { if showImmersiveSpace { await openImmersiveSpace(id: "TableTop") immersiveSpaceIsOpen = true } else { if immersiveSpaceIsOpen { await dismissImmersiveSpace() immersiveSpaceIsOpen = false } } } } .onDisappear { // Attempt to close the immersive space on the way out. Task { if immersiveSpaceIsOpen { await dismissImmersiveSpace() } } } } } struct TableTopPlatterView: View { private var attachmentID: String { "RedCircle" } var body: some View { RealityView { content, attachments in if let redCircleEntity = attachments.entity(for: attachmentID) { // Lays the red circle in the platter. let rotation = Rotation3D(redCircleEntity.orientation) .rotated(by: .init(angle: .degrees(-90), axis: .x)) redCircleEntity.setOrientation(.init(rotation), relativeTo: nil) redCircleEntity.position.y = 0.026 platterEntity.addChild(redCircleEntity) content.add(platterEntity) } } placeholder: { ProgressView() } attachments: { Attachment(id: attachmentID) { MetalView() .clipShape(.circle) } } } /// The platter entity that the red circle lays on top of. private let platterEntity: ModelEntity = { let anchor = AnchorEntity( .plane( .horizontal, classification: .table, minimumBounds: [0.01, 0.01] ) ) let material = SimpleMaterial( color: .lightGray, roughness: 0.5, isMetallic: false ) let platter = ModelEntity( mesh: .generateCylinder(height: 0.05, radius: 0.475), materials: [material] ) platter.generateCollisionShapes(recursive: false) let components: [any Component] = [ InputTargetComponent(), GroundingShadowComponent(castsShadow: true), ManipulationComponent() // MARK: This is causing makeUIView to get called twice! ] platter.components.set(components) // Placed closer to the user when booted up. platter.position = [0, 1, -1.25] anchor.addChild(platter) return platter }() } // Metal view that renders a red square. struct MetalView: UIViewRepresentable { var device: MTLDevice? init() { self.device = MTLCreateSystemDefaultDevice() } func makeUIView(context: Context) -> MTKView { print("Make UI View! This should be called once.") let mtkView = MTKView() mtkView.device = device mtkView.clearColor = MTLClearColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0) mtkView.delegate = context.coordinator return mtkView } func updateUIView(_ uiView: MTKView, context: Context) { } func makeCoordinator() -> Coordinator { Coordinator(self) } class Coordinator: NSObject, MTKViewDelegate { var metalView: MetalView init(_ metalView: MetalView) { self.metalView = metalView } func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) { } func draw(in view: MTKView) { guard let drawable = view.currentDrawable else { return } guard let descriptor = view.currentRenderPassDescriptor else { return } let commandQueue = metalView.device?.makeCommandQueue() let commandBuffer = commandQueue?.makeCommandBuffer() let renderEncoder = commandBuffer?.makeRenderCommandEncoder(descriptor: descriptor) renderEncoder?.endEncoding() commandBuffer?.present(drawable) commandBuffer?.commit() } } }
3
0
1.3k
1w
Intermittent UIHostingController layout regression after app launch on iPadOS 27 beta 4
On iPadOS 27.0 beta 4, SwiftUI views hosted inside UIKit-managed containers/overlays can be laid out incorrectly. The same app and same code work correctly on iPadOS 26.x release versions. One visible example is the app’s About dialog. The dialog is implemented as a UIKit UIViewController presented with UIModalPresentationFormSheet. Inside that controller, a UIHostingController is added as a child view controller, and the hosting controller’s view is constrained to all four edges of the parent view. The SwiftUI root view is a VStack containing the app icon, app name, version, text, links, and buttons. Expected behavior: The SwiftUI content should be vertically centered inside the form sheet. The app icon should appear above the app title, followed by the version, text, links, and buttons. This is the behavior on iPadOS 26.x. Actual behavior on iPadOS 27.0 beta 4: When the About dialog is opened immediately after launching the app, this issue occurs intermittently. The form sheet itself appears, but the SwiftUI content is shifted upward. The app icon is missing or clipped, the title starts too close to the top edge of the sheet, and a large empty area appears at the bottom of the sheet. This is not limited to the About dialog. Similar layout issues can also appear in other SwiftUI-hosted UI surfaces in the app. The issue also appears to be affected by system-level UI changes: If I put the app into windowed mode and resize the whole app window, the layout inside the dialog recovers and becomes correct. The issue only occurs with some probability the first time this dialog is opened after launching the app. After the layout is restored by resizing the app window, the issue does not appear again as long as the app process is not terminated. This suggests the problem may be related to an incorrect initial layout pass, cached geometry, trait/safe-area propagation, or UIHostingController layout invalidation after the app/window scene is first created. Environment: Device: iPad OS with issue: iPadOS 27.0 beta 4 OS without issue: iPadOS 26.x release App: VoidLink - Extreme UI stack: UIKit containers/overlays hosting SwiftUI through UIHostingController Relevant code: AboutView.swift: https://github.com/The-Fried-Fish/VoidLink-previously-moonlight-zwm/blob/Integration/VoidLink/AboutView.swift AboutViewController.swift: https://github.com/The-Fried-Fish/VoidLink-previously-moonlight-zwm/blob/Integration/VoidLink/AboutViewController.swift Attachments: IMG_0291.PNG: correct layout on iPadOS 26.x IMG_0292.PNG: incorrect layout on iPadOS 27.0 beta 4
1
0
360
1w
ViewAttachmentComponent Resolution Low After Moving Into Frame
If a ViewAttachmentComponent moves into frame, it is low resolution until something changes the view while it is in frame. Video demonstrating the behavior: https://youtu.be/KXEFFiAnv1s I am on visionOS 27 beta 4. This did not occur when I was on visionOS 26.5. Also using Xcode 27.0 beta 4 and macOS 27.0 beta 4. To reproduce, have a ViewAttachmentComponent in an immersive space, look away, then look back, and it'll be low resolution. Anything which would change the view while it's in frame will then cause it to update in full resolution. Screenshot of low-resolution view after it moves back into frame from being out of frame: Screenshot after updating the view, making it high-resolution again: I've submitted feedback as FB24116473.
0
0
311
1w
Is it normal that mounted @Query cause every object of that type to re-render, even after unrelated saves?
I have a SwiftUI + SwiftData app where scrolling became very slow, and I've traced it to something about @Query I didn't expect. The app was running save for each lazy list item appearing in viewport (a separate bug, but it did highlight the problem), which made the whole list re-render on each save. After tracing why this happens I have discovered that it is because another model watched in the list parent is invalidated after every save, and the problem was that this another model has @Query in a separate view (sidebar), removing that @Query fixed the problem. Here is a minimal reproduction of this https://github.com/aytigra/QueryRefaultRepro I wonder if it is a bug or an expected behavior?
0
0
470
1w
How to achieve the UIEditMenuInteraction (?) for Link Preview used in iOS 27 Messages
I've been using the iOS 27 beta and noticed in Messages app that the link presentation is now customisable. Upon tapping on the link it opens (what I assume is) an edit menu interaction, which allows customising which metadata is shown. I've seen some links offer more customisation than others, presumably based on available metadata. There's also an option in the menu to convert to a text link, and when highlighting a link in text there's an option to "show link preview" which converts it to an LPLinkView. I've been wondering for a while now if it was possible to add a similar feature to my own app, allowing the user more control over the link previews. How can I achieve similar? Especially "Customise Link" sheet seen in the middle two screenshots?
0
0
527
1w
Adding a ManipulationComponent detaches the whole RealityView content hierarchy on visionOS 27
On visionOS 27 (27.0 Seed 4, 24M5326g), adding a ManipulationComponent to a single entity makes RealityKit remove the RealityView's ENTIRE content hierarchy from the scene and re-add it about 30ms later. Not just the manipulated entity — everything. Same app binary on visionOS 26: never happens. FB24092291. Bisected on the same build and device: two entities, neither with manipulation -> no detach add one entity with a ManipulationComponent -> detach, every time same entity, manipulation swapped for my own drag/rotate/ scale gesture handling -> no detach Everything else is identical between the last two cases — same entity, same collision shape, same InputTargetComponent, same ViewAttachmentComponent, same scene, same view hierarchy. The only variable is whether the component is installed. Setup: an immersive space containing a SwiftUI RealityView. One root entity added to the RealityViewContent in the make closure; all app content built as its descendants. The detach is brief but not harmless: every entity in the hierarchy gets SceneEvents.WillRemoveEntity and then DidAddEntity, so anything keyed to those events runs a full teardown and re-add for content that was never meant to go anywhere. In my app that cascade is what makes the scene visibly empty and rebuild. Nothing in my code removes it. Stack captured from a WillRemoveEntity subscription on the root — frame 0 is my callback, everything above it is framework: SwiftUI (AttributeGraph StatefulRule.withObservation ...) -> RealityFoundation -> CoreRE -> entity removal Ruled out before landing on the component: make runs exactly once, the root re-enters a scene with the same ObjectIdentifier (not a re-host), the hosting controller is never deallocated, there is exactly one RealityViewContent.add(_:) in the whole app, and with Self._printChanges() in the view's body the detach happens in an update pass where the body is not re-evaluated at all. Also ruled out: transient overlay UI (suppressed entirely, still detached) and entity count. Workaround if this is biting you: skip ManipulationComponent on 27 and handle drag/rotate/scale yourself. That is what I am doing for now. If you are debugging something similar: SceneEvents.WillRemoveEntity also fires when an entity merely leaves a scene, so a teardown-looking log is not proof anything was destroyed. Check whether make ran twice and whether the scene identity changed before suspecting your own code.
1
2
1k
1w
Extract Subview option missing in Xcode 26
Hi everyone, I recently updated to Xcode 26.0 and noticed that the “Extract Subview” refactoring option seems to be missing. Now, in Xcode 26, the only options I see under Editor -> Refactor -> are: Extract to Selection File Extract to Method Extract to Variable Extract All Occurrences But there’s no Extract Subview as there was before. Was Extract Subview intentionally removed in Xcode 26? Or is it hidden behind a new menu location or renamed?
6
8
936
1w
iOS 27 beta 1: .scrollEdgeEffectStyle(.soft) renders fully transparent above safeAreaBar
Feedback ID: FB23086400 On iOS 27 beta 1, .scrollEdgeEffectStyle(.soft, for: .top) on a List underneath a custom .safeAreaBar(edge: .top) no longer renders the progressive fade-blur. The top edge is fully transparent — scrolled rows pass under the bar with no visual treatment at all, as if scrollEdgeEffectDisabled() had been applied. What I've verified so far: .hard renders correctly in the exact same hierarchy; only .soft is affected. The same binary works correctly on iOS 26.x Xcode preview. I'm building with Xcode 26.3 (iOS 26 SDK). Minimal reproduction: import SwiftUI struct EdgeEffectRepro: View { enum Style: String, CaseIterable, Identifiable { case automatic, soft, hard var id: Self { self } var value: ScrollEdgeEffectStyle { switch self { case .automatic: .automatic case .soft: .soft case .hard: .hard } } } @State private var style: Style = .soft @State private var useSystemBarOnly = false var body: some View { NavigationStack { List(0..<60, id: \.self) { i in Text("Row \(i)") .frame(maxWidth: .infinity, alignment: .leading) .listRowBackground( i.isMultiple(of: 2) ? Color.orange.opacity(0.45) : Color.teal.opacity(0.45) ) } .scrollIndicators(.hidden) .scrollEdgeEffectStyle(style.value, for: .top) .safeAreaBar(edge: .top) { if !useSystemBarOnly { VStack(spacing: 8) { HStack { Text("Custom Top Bar") .font(.system(size: 28, weight: .bold)) Spacer() } HStack { Text("Second row (e.g. date range picker)") .font(.caption) .foregroundStyle(.secondary) Spacer() } } .padding(.horizontal) } } .safeAreaInset(edge: .bottom) { VStack(spacing: 8) { Picker("Edge effect style", selection: $style) { ForEach(Style.allCases) { Text($0.rawValue).tag($0) } } .pickerStyle(.segmented) Toggle("System bar only (control group)", isOn: $useSystemBarOnly) .font(.caption) } .padding() .background(.regularMaterial) } .navigationTitle("EdgeEffect Repro") .navigationBarTitleDisplayMode(.inline) } } } Steps: run on iOS 27 beta 1, set the picker to soft, scroll rows under the bar. Expected: fade-blur as on iOS 26. Actual: fully transparent. Switch to hard: renders fine.
Replies
8
Boosts
10
Views
1.3k
Activity
1h
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) } } }
Replies
8
Boosts
4
Views
948
Activity
2h
ShareLink with Collaboration in SwiftUI with a Document based app
Hello to anyone reading this. I am a bit lost as to what is the correct approach for enabling Collaboration for a Document based SwiftUI app. If I understand correctly, after setting up all the relevant entitlements and capabilities for enabling sharing, you only need to use ShareLink to begin a collaboration/send a copy by passing in the URL of the document. The collaboration is then handled with SWCollaborationView, which there have been NSViewRepresentable wrapper implementations posted around the web. My main question is; how do I know whether the document has been shared to create a collaboration? Do I have to have 2 sharing ToolbarItems? Basically, is there any documentation for implementing collaborations from a document based app, other than simply saying that starting a share is done by passing the url into a ShareLink? This seems to massively missing, or have I massively missed something?
Replies
0
Boosts
0
Views
25
Activity
18h
iOS 26: Enabling "Reduce Transparency" causes a persistent white bar where the tab bar was hidden, blocking user interaction
Hi everyone, We're experiencing a bug on iOS 26 that only occurs when the user has Reduce Transparency enabled in Accessibility settings. App structure: Our app uses a TabView with a standard tab bar. Inside each tab, we use a NavigationStack. The tab bar is visible on root-level screens, and hidden on all pushed destinations using: .toolbar(.hidden, for: .tabBar) The problem: On iOS 26 with Reduce Transparency off (Liquid Glass active) — everything works correctly. The tab bar hides as expected. On iOS 26 with Reduce Transparency on — a white bar appears at the bottom of the screen in every place where the tab bar is hidden. This white bar: Overlaps content at the bottom of the screen. Blocks scroll, tap, and all user interactions in that area. We also tried: .toolbarBackground(.hidden, for: .tabBar) Removing all custom UITabBarAppearance configuration The only workaround we found is setting UIDesignRequiresCompatibility = YES in Info.plist, which reverts the entire app to the pre-iOS 26 design — not a viable long-term solution. What can we do? Thanks in advance.
Replies
4
Boosts
1
Views
513
Activity
19h
SwiftUI NavigationSplitView sidebar toolbar has excessive top inset when embedded in TabView since iPadOS 26.4
I’m seeing a layout regression in SwiftUI on iPadOS 26.4 involving NavigationSplitView inside a TabView. When a NavigationSplitView is embedded in a TabView, the sidebar toolbar appears to reserve too much vertical space. There is a large vertical gap between the top edge of the sidebar and the sidebar collapse/toggle icon. It looks as if the sidebar toolbar itself has become much taller than expected. The same NavigationSplitView layout is rendered correctly when it is shown directly without being embedded in a TabView. Environment: iPadOS 26.4 or later SwiftUI iPad TabView NavigationSplitView inside one tab Expected behavior The sidebar toolbar should use its normal height, as it does when the same NavigationSplitView is shown without a surrounding TabView. The sidebar collapse/toggle icon should appear close to the top of the sidebar, without a large empty gap above it. Actual behavior When the NavigationSplitView is hosted inside a TabView, the sidebar toolbar area becomes excessively tall. A large empty space appears above the sidebar collapse/toggle icon. This only happens in the TabView setup. Rendering the same NavigationSplitView directly does not show the issue. Feedback I also filed this as Feedback Assistant report: FB22645938 Has anyone else seen this behavior since iPadOS 26.4? Is this an intentional layout change, or is there a supported way to avoid this additional top inset when using NavigationSplitView inside TabView? Reproduction import SwiftUI struct ContentView: View { enum AppTab { case first case second } @State private var selectedTab: AppTab = .first var body: some View { TabView(selection: $selectedTab) { Tab("First", systemImage: "sidebar.leading", value: .first) { NavigationSplitView { List { Section("Sidebar Content") { ForEach(1...20, id: \.self) { index in Text("Item \(index)") } } } .navigationTitle("Sidebar") .toolbar { ToolbarItem(placement: .topBarLeading) { Button { // action } label: { Image(systemName: "plus") } } } } detail: { Text("Detail") } } Tab("Second", systemImage: "doc", value: .second) { Text("Second tab") } } } }
Replies
3
Boosts
3
Views
599
Activity
19h
Did VisionOS27 get the LazyVGrid Performance Updates?
Did VisionOS get the LazyVGrid Performance Updates that other platforms received? I’m observing that a LazyVGrid that works well on iPhone, iPad, and Mac appears to hitch and jitter as cells exit and renter the lazyVGrid on VisionOS. It really feels like it did not get the same behavior changes as the other platforms. I observe the scrollbar expands as cells leave the top of the grid, and each “exit” of a row seems to cause a hitch. I’ve got rigidly defined cell frames, rigidly defined columns. I don’t think any cells frames are being invalidated during scroll… (there’s no way to check this with instruments, right?) I‘ve made several analysis passes myself and threw the Xcode Agent with Codex at it just to scan for stuff, but it’s starting to just guess at things. Any known issues with VisionOS?
Replies
5
Boosts
0
Views
539
Activity
21h
SwiftUI macOS Preview Crash When Using Custom Row Directly Inside List
I’ve hit a strange SwiftUI preview crash that happens on macOS previews when using a view inside a List’s ForEach, resulting in the error Fatal Error in TableViewListCore_Mac2.swift. Only crashes macOS preview - iPhone/iPad preview doesn't crash. Doesn't crash when actually running the app. Here’s a minimal reproducible example, causing the preview to crash. XCode: Version 26.0.1 (17A400) MacOS: 26.0.1 (25A362) import SwiftUI struct Item: Identifiable { let id = UUID() let name: String } struct ItemRow: View { let item: Item var body: some View { HStack { Button(action: {}) { Image(systemName: "play") } Text(item.name) Spacer() ProgressView() } } } struct ContentView: View { @State private var items = [ Item(name: "Item A"), Item(name: "Item B"), ] var body: some View { List { ForEach(items) { item in ItemRow(item: item) } } } } #Preview("Content view") { ContentView() } #Preview("Item row") { ItemRow(item: Item(name: "Item A")) } If I wrap the row in a container, like this: ForEach(items) { item in ZStack { ItemRow(item: item) } } the crash seems to disappear. Has anyone else seen this behavior? What might I be doing wrong? Any ideas about what could be causing this?
Replies
3
Boosts
1
Views
760
Activity
22h
Best path for a 14-year-old student to begin Swift development using an iPad
Hello, My 14-year-old daughter is beginning high school in Florida and is interested in learning Swift and developing applications for Apple platforms. She currently has an iPad and iPhone but does not yet have access to a Mac. We understand that Swift Playground can be used on iPad, while Xcode requires a Mac. We would appreciate guidance on the best learning path for a beginner in her situation: Which official Apple Swift or SwiftUI curriculum should she begin with? How much can she realistically learn and build using Swift Playground on an iPad? At what stage would access to Xcode on a Mac become necessary? Can an app playground started on iPad later be transferred to Xcode on a Mac? Are there recommended Swift Coding Clubs, education programs, or student resources for high-school students in the United States? What should she focus on during her first year if she eventually wants to participate in the Swift Student Challenge? She is motivated to learn correctly from the beginning and build her first small app playground. Thank you for any guidance or educational resources you can provide.
Replies
5
Boosts
0
Views
1k
Activity
3d
Different keyboards show up for KeyboardType .decimalPad
Environment: iOS 26; iPad Mini/Air/Pro Problem: In a TextField, I am using a keyboard with the type .decimalPad. When I initially tap into the TextField, the "popover" keyboard (i.e. the decimalPad) shows up and focusses the TextField. However, when I click outside the TextField (to dismiss the keyboard), the TextField is still focussed (the keyboard was dismissed though). When reentering in the TextField, another keyboard (from the bottom of the screen) appears (most likely .numeric). Does anybody know how to solve this? What I already tried: I tried listening to the dismissal of the keyboard to manually set the FocusState to nil. However, the dismissal of the "popover/decimal" keyboard is not recognized as such a dismissal. I also tried to build a custom component out of that, but then I lose the TextField behavior, conflicting with HIG.
Replies
3
Boosts
0
Views
500
Activity
5d
How to make a layout like Android's StaggeredGridLayoutManager in SwiftUI
Hi everyone In SwiftUI, are there any good solutions to achieve a layout similar to Android's StaggeredGridLayoutManager for displaying a large amount of data?
Replies
1
Boosts
0
Views
121
Activity
6d
ManipulationComponent + Warning messages in RealityView
Hi guys! I wanted to study this new ManipulationComponent(), but I keep getting a warning that I don’t understand, even in a very simple scenario. i don't have any collisions just binding the Manipulation the warning message is : ** Entity returned from EntityWrapper.makeEntity(context:) was already parented to another entity. This is not supported and may lead to unexpected behavior. SwiftUI adds entities to internally-managed entity hierarchies.** RealityView { content, attachments in if let loadedModel = try? await Entity(named: "cloud_glb", in: realityKitContentBundle) { content.add(loadedModel) loadedModel.components.set(ManipulationComponent()) } Thanks !
Replies
4
Boosts
0
Views
655
Activity
6d
[API] cannot add handler to 3 from 3 - dropping New XCode error!
while resizing screen on mac, start getting this weird error [API] cannot add handler to 3 from 3 - dropping All lazyVgrids fail to show afterwards then app crashes if you keep resizing. This error started with macOS Ventura. Any help much appreciated.
Replies
6
Boosts
5
Views
3.2k
Activity
1w
Pinch gesture not recognized on MTKView when attaching it to a RealityView using a ViewAttachmentComponent in a immersive space
Hello! We are seeing a problem with a SwiftUI view that wraps an MTKView and that MTKView uses gesture recognizers from UIKit. One of those gestures we are using is UIPinchGestureRecognizer. And that gesture isn’t recognized at all when the SwiftUI view is attached to a RealityView using the ViewAttachmentComponent AND the RealityView is being shown in an ImmersiveSpace. If the SwiftUI view is attached to the RealityView using the init that has an attachment closure then pinching works fine there. So this definitely seems like a bug. Here is some code to help you reproduce the problem. Run this on a Vision Pro device. A simple red square will be rendered and if a single tap or pinch gesture is recognized on the red square, it will print to the console. App Code: import SwiftUI @main struct VisionPinchProblemsApp: App { var body: some Scene { WindowGroup { MenuView() } ImmersiveSpace(id: "RedSquare") { RedSquareView() } } } View code: import MetalKit import RealityKit import SwiftUI import UIKit struct MenuView: View { @Environment(\.openImmersiveSpace) private var openImmersiveSpace @Environment(\.dismissImmersiveSpace) private var dismissImmersiveSpace @State private var showImmersiveSpace = false @State private var immersiveSpaceIsOpen = false var body: some View { Form { Toggle("Show red square", isOn: $showImmersiveSpace) .task(id: showImmersiveSpace) { if showImmersiveSpace { await openImmersiveSpace(id: "RedSquare") immersiveSpaceIsOpen = true } else { if immersiveSpaceIsOpen { await dismissImmersiveSpace() immersiveSpaceIsOpen = false } } } } .onDisappear { // Attempt to close the immersive space on the way out. Task { if immersiveSpaceIsOpen { await dismissImmersiveSpace() } } } } } struct RedSquareView: View { let metalViewAttachmentID = "metalID" var body: some View { // Adds SwiftUI view using attachments closure. // Pinching and single taps are recognized here! // RealityView { content, attachments in // if let metalViewEntity = attachments.entity(for: metalViewAttachmentID) { // metalViewEntity.position = [0, 1, -1.25] // content.add(metalViewEntity) // } // } placeholder: { // ProgressView() // } attachments: { // Attachment(id: metalViewAttachmentID) { // MetalView() // } // } // Add SwiftUI view using ViewAttachmentComponent. // Pinching is not recognized here! // Single tapping is recognized ! // Why doesn't the red square show up in the Vision Pro simulator? RealityView { content in let metalViewEntity = Entity() let metalView = MetalView() .frame(width: 500, height: 500) let component = ViewAttachmentComponent(rootView: metalView) metalViewEntity.components.set(component) metalViewEntity.position = [0, 1, -1.25] content.add(metalViewEntity) } placeholder: { ProgressView() } } } struct MetalView: UIViewRepresentable { var device: MTLDevice? init() { self.device = MTLCreateSystemDefaultDevice() } func makeUIView(context: Context) -> MTKView { let mtkView = MTKView() mtkView.device = device mtkView.clearColor = MTLClearColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0) mtkView.delegate = context.coordinator let pinchGesture = UIPinchGestureRecognizer(target: context.coordinator, action: #selector(context.coordinator.handlePinch(_:))) mtkView.addGestureRecognizer(pinchGesture) let tapGesture = UITapGestureRecognizer(target: context.coordinator, action: #selector(context.coordinator.handleTap(_:))) mtkView.addGestureRecognizer(tapGesture) return mtkView } func updateUIView(_ uiView: MTKView, context: Context) { } func makeCoordinator() -> Coordinator { Coordinator(self) } class Coordinator: NSObject, MTKViewDelegate { var parent: MetalView init(_ parent: MetalView) { self.parent = parent } func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) { } func draw(in view: MTKView) { guard let drawable = view.currentDrawable else { return } guard let descriptor = view.currentRenderPassDescriptor else { return } let commandQueue = parent.device?.makeCommandQueue() let commandBuffer = commandQueue?.makeCommandBuffer() let renderEncoder = commandBuffer?.makeRenderCommandEncoder(descriptor: descriptor) renderEncoder?.endEncoding() commandBuffer?.present(drawable) commandBuffer?.commit() } @objc func handlePinch(_ sender: UIPinchGestureRecognizer) { print("Pinch detected") } @objc func handleTap(_ sender: UITapGestureRecognizer) { print("Tap detected") } } }
Replies
1
Boosts
0
Views
423
Activity
1w
ManipulationComponent causes makeUIView(context:) to get called twice
Here I have some demo code that is rendering a cylinder "platter" using RealityKit and there is a red circle rendered on top of it which uses Metal and SwiftUI. When the platter appears you will see in the console that makeUIView(context:) is called twice while it is documented that it will only be called once when the view appears for the first time. So this seems like a bug. If you remove ManipulationComponent from the platter's components you will see that this problem goes away so it seems like that is the cause of the problem. Any insight here would be appreciated! Thank you. Here is what is printed in the console: Entity returned from EntityWrapper.makeEntity(context:) was already parented to another entity. This is not supported and may lead to unexpected behavior. SwiftUI adds entities to internally-managed entity hierarchies. Make UI View! This should be called once. Make UI View! This should be called once. Here is the app code: import SwiftUI @main struct SomeApp: App { var body: some Scene { WindowGroup { ContentView() } ImmersiveSpace(id: "TableTop") { TableTopPlatterView() } } } Here is the view code: import MetalKit import RealityKit import SwiftUI struct ContentView: View { @Environment(\.openImmersiveSpace) private var openImmersiveSpace @Environment(\.dismissImmersiveSpace) private var dismissImmersiveSpace @State private var showImmersiveSpace = false @State private var immersiveSpaceIsOpen = false var body: some View { Form { Toggle("Show table top", isOn: $showImmersiveSpace) .task(id: showImmersiveSpace) { if showImmersiveSpace { await openImmersiveSpace(id: "TableTop") immersiveSpaceIsOpen = true } else { if immersiveSpaceIsOpen { await dismissImmersiveSpace() immersiveSpaceIsOpen = false } } } } .onDisappear { // Attempt to close the immersive space on the way out. Task { if immersiveSpaceIsOpen { await dismissImmersiveSpace() } } } } } struct TableTopPlatterView: View { private var attachmentID: String { "RedCircle" } var body: some View { RealityView { content, attachments in if let redCircleEntity = attachments.entity(for: attachmentID) { // Lays the red circle in the platter. let rotation = Rotation3D(redCircleEntity.orientation) .rotated(by: .init(angle: .degrees(-90), axis: .x)) redCircleEntity.setOrientation(.init(rotation), relativeTo: nil) redCircleEntity.position.y = 0.026 platterEntity.addChild(redCircleEntity) content.add(platterEntity) } } placeholder: { ProgressView() } attachments: { Attachment(id: attachmentID) { MetalView() .clipShape(.circle) } } } /// The platter entity that the red circle lays on top of. private let platterEntity: ModelEntity = { let anchor = AnchorEntity( .plane( .horizontal, classification: .table, minimumBounds: [0.01, 0.01] ) ) let material = SimpleMaterial( color: .lightGray, roughness: 0.5, isMetallic: false ) let platter = ModelEntity( mesh: .generateCylinder(height: 0.05, radius: 0.475), materials: [material] ) platter.generateCollisionShapes(recursive: false) let components: [any Component] = [ InputTargetComponent(), GroundingShadowComponent(castsShadow: true), ManipulationComponent() // MARK: This is causing makeUIView to get called twice! ] platter.components.set(components) // Placed closer to the user when booted up. platter.position = [0, 1, -1.25] anchor.addChild(platter) return platter }() } // Metal view that renders a red square. struct MetalView: UIViewRepresentable { var device: MTLDevice? init() { self.device = MTLCreateSystemDefaultDevice() } func makeUIView(context: Context) -> MTKView { print("Make UI View! This should be called once.") let mtkView = MTKView() mtkView.device = device mtkView.clearColor = MTLClearColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0) mtkView.delegate = context.coordinator return mtkView } func updateUIView(_ uiView: MTKView, context: Context) { } func makeCoordinator() -> Coordinator { Coordinator(self) } class Coordinator: NSObject, MTKViewDelegate { var metalView: MetalView init(_ metalView: MetalView) { self.metalView = metalView } func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) { } func draw(in view: MTKView) { guard let drawable = view.currentDrawable else { return } guard let descriptor = view.currentRenderPassDescriptor else { return } let commandQueue = metalView.device?.makeCommandQueue() let commandBuffer = commandQueue?.makeCommandBuffer() let renderEncoder = commandBuffer?.makeRenderCommandEncoder(descriptor: descriptor) renderEncoder?.endEncoding() commandBuffer?.present(drawable) commandBuffer?.commit() } } }
Replies
3
Boosts
0
Views
1.3k
Activity
1w
Intermittent UIHostingController layout regression after app launch on iPadOS 27 beta 4
On iPadOS 27.0 beta 4, SwiftUI views hosted inside UIKit-managed containers/overlays can be laid out incorrectly. The same app and same code work correctly on iPadOS 26.x release versions. One visible example is the app’s About dialog. The dialog is implemented as a UIKit UIViewController presented with UIModalPresentationFormSheet. Inside that controller, a UIHostingController is added as a child view controller, and the hosting controller’s view is constrained to all four edges of the parent view. The SwiftUI root view is a VStack containing the app icon, app name, version, text, links, and buttons. Expected behavior: The SwiftUI content should be vertically centered inside the form sheet. The app icon should appear above the app title, followed by the version, text, links, and buttons. This is the behavior on iPadOS 26.x. Actual behavior on iPadOS 27.0 beta 4: When the About dialog is opened immediately after launching the app, this issue occurs intermittently. The form sheet itself appears, but the SwiftUI content is shifted upward. The app icon is missing or clipped, the title starts too close to the top edge of the sheet, and a large empty area appears at the bottom of the sheet. This is not limited to the About dialog. Similar layout issues can also appear in other SwiftUI-hosted UI surfaces in the app. The issue also appears to be affected by system-level UI changes: If I put the app into windowed mode and resize the whole app window, the layout inside the dialog recovers and becomes correct. The issue only occurs with some probability the first time this dialog is opened after launching the app. After the layout is restored by resizing the app window, the issue does not appear again as long as the app process is not terminated. This suggests the problem may be related to an incorrect initial layout pass, cached geometry, trait/safe-area propagation, or UIHostingController layout invalidation after the app/window scene is first created. Environment: Device: iPad OS with issue: iPadOS 27.0 beta 4 OS without issue: iPadOS 26.x release App: VoidLink - Extreme UI stack: UIKit containers/overlays hosting SwiftUI through UIHostingController Relevant code: AboutView.swift: https://github.com/The-Fried-Fish/VoidLink-previously-moonlight-zwm/blob/Integration/VoidLink/AboutView.swift AboutViewController.swift: https://github.com/The-Fried-Fish/VoidLink-previously-moonlight-zwm/blob/Integration/VoidLink/AboutViewController.swift Attachments: IMG_0291.PNG: correct layout on iPadOS 26.x IMG_0292.PNG: incorrect layout on iPadOS 27.0 beta 4
Replies
1
Boosts
0
Views
360
Activity
1w
ViewAttachmentComponent Resolution Low After Moving Into Frame
If a ViewAttachmentComponent moves into frame, it is low resolution until something changes the view while it is in frame. Video demonstrating the behavior: https://youtu.be/KXEFFiAnv1s I am on visionOS 27 beta 4. This did not occur when I was on visionOS 26.5. Also using Xcode 27.0 beta 4 and macOS 27.0 beta 4. To reproduce, have a ViewAttachmentComponent in an immersive space, look away, then look back, and it'll be low resolution. Anything which would change the view while it's in frame will then cause it to update in full resolution. Screenshot of low-resolution view after it moves back into frame from being out of frame: Screenshot after updating the view, making it high-resolution again: I've submitted feedback as FB24116473.
Replies
0
Boosts
0
Views
311
Activity
1w
Is it normal that mounted @Query cause every object of that type to re-render, even after unrelated saves?
I have a SwiftUI + SwiftData app where scrolling became very slow, and I've traced it to something about @Query I didn't expect. The app was running save for each lazy list item appearing in viewport (a separate bug, but it did highlight the problem), which made the whole list re-render on each save. After tracing why this happens I have discovered that it is because another model watched in the list parent is invalidated after every save, and the problem was that this another model has @Query in a separate view (sidebar), removing that @Query fixed the problem. Here is a minimal reproduction of this https://github.com/aytigra/QueryRefaultRepro I wonder if it is a bug or an expected behavior?
Replies
0
Boosts
0
Views
470
Activity
1w
How to achieve the UIEditMenuInteraction (?) for Link Preview used in iOS 27 Messages
I've been using the iOS 27 beta and noticed in Messages app that the link presentation is now customisable. Upon tapping on the link it opens (what I assume is) an edit menu interaction, which allows customising which metadata is shown. I've seen some links offer more customisation than others, presumably based on available metadata. There's also an option in the menu to convert to a text link, and when highlighting a link in text there's an option to "show link preview" which converts it to an LPLinkView. I've been wondering for a while now if it was possible to add a similar feature to my own app, allowing the user more control over the link previews. How can I achieve similar? Especially "Customise Link" sheet seen in the middle two screenshots?
Replies
0
Boosts
0
Views
527
Activity
1w
Adding a ManipulationComponent detaches the whole RealityView content hierarchy on visionOS 27
On visionOS 27 (27.0 Seed 4, 24M5326g), adding a ManipulationComponent to a single entity makes RealityKit remove the RealityView's ENTIRE content hierarchy from the scene and re-add it about 30ms later. Not just the manipulated entity — everything. Same app binary on visionOS 26: never happens. FB24092291. Bisected on the same build and device: two entities, neither with manipulation -> no detach add one entity with a ManipulationComponent -> detach, every time same entity, manipulation swapped for my own drag/rotate/ scale gesture handling -> no detach Everything else is identical between the last two cases — same entity, same collision shape, same InputTargetComponent, same ViewAttachmentComponent, same scene, same view hierarchy. The only variable is whether the component is installed. Setup: an immersive space containing a SwiftUI RealityView. One root entity added to the RealityViewContent in the make closure; all app content built as its descendants. The detach is brief but not harmless: every entity in the hierarchy gets SceneEvents.WillRemoveEntity and then DidAddEntity, so anything keyed to those events runs a full teardown and re-add for content that was never meant to go anywhere. In my app that cascade is what makes the scene visibly empty and rebuild. Nothing in my code removes it. Stack captured from a WillRemoveEntity subscription on the root — frame 0 is my callback, everything above it is framework: SwiftUI (AttributeGraph StatefulRule.withObservation ...) -> RealityFoundation -> CoreRE -> entity removal Ruled out before landing on the component: make runs exactly once, the root re-enters a scene with the same ObjectIdentifier (not a re-host), the hosting controller is never deallocated, there is exactly one RealityViewContent.add(_:) in the whole app, and with Self._printChanges() in the view's body the detach happens in an update pass where the body is not re-evaluated at all. Also ruled out: transient overlay UI (suppressed entirely, still detached) and entity count. Workaround if this is biting you: skip ManipulationComponent on 27 and handle drag/rotate/scale yourself. That is what I am doing for now. If you are debugging something similar: SceneEvents.WillRemoveEntity also fires when an entity merely leaves a scene, so a teardown-looking log is not proof anything was destroyed. Check whether make ran twice and whether the scene identity changed before suspecting your own code.
Replies
1
Boosts
2
Views
1k
Activity
1w
Extract Subview option missing in Xcode 26
Hi everyone, I recently updated to Xcode 26.0 and noticed that the “Extract Subview” refactoring option seems to be missing. Now, in Xcode 26, the only options I see under Editor -> Refactor -> are: Extract to Selection File Extract to Method Extract to Variable Extract All Occurrences But there’s no Extract Subview as there was before. Was Extract Subview intentionally removed in Xcode 26? Or is it hidden behind a new menu location or renamed?
Replies
6
Boosts
8
Views
936
Activity
1w