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

SwiftUI Text rendering with too small height / one line missing causing unexpected text truncation on iPhone devices
FB: FB22577211 The following trivial SwiftUI Text rendering causes wrong text layout and truncated text. The text should take the required height to render the text without truncation. Adding fixedSize does also not solve this. This bug only happens on devices and not on the simulator. Confirmed with iPhone 15 and iOS 26.4.1 but my colleague used another iPhone so it’s multiple iPhone devices. import SwiftUI let txt = """ Es sollte die erste Japan-Tournee von vielen werden, kein anderes Land – abgesehen von Österreich und der Schweiz – bereisten die Berliner Philharmoniker häufiger. Wie kam es zu dem überschäumend herzlichen Empfang, der dem Orchester bei seinem ersten Gastspiel in Tokio bereitet wurde und wie wurde das Land zu einer »zweiten Heimat« für die Berliner? Ein konkreter historischer Grundstein für das hohe Ansehen klassischer Musik »made in Germany« in Japan wurde bereits im 19. Jahrhunderts gelegt: Als Teil von umfassenden gesellschaftlichen Modernisierungsmaßnahmen vergab die Regierung ab 1868 Stipendien an junge japanische Intellektuelle, damit diese an den besten internationalen Instituten studieren konnten. Berlin wurde – neben Wien – als globales Zentrum der Musik betrachtet, und so erhielten viele japanische Studierende um die Jahrhundertwende die Gelegenheit, von Komponisten wie etwa Max Bruch zu lernen. Zurück in der Heimat, teilten sie ihre Begeisterung für die europäische Kunstmusik sowie das Wissen um die instrumentale und kompositorische Praxis der klassisch-romantischen Tradition. """ struct ContentView: View { var body: some View { VStack { Text(txt) } .padding(.leading, 20) .padding(.trailing, 20) .frame(maxWidth: .infinity) } } This is also enough: Text(txt) .padding(.horizontal, 20) .fixedSize(horizontal: false, vertical: true) Expected: Text is rendered without truncation / ellipsis. Actual: Text is rendered with too small height / missing one line so it’s truncated / with ellipsis.
0
0
74
7h
Navigation title scroll issue in iOS 26
Navigation title scroll along with the content in iOS 26. working fine in iOS 18 and below. One of my UI component is outside the scrollview which is causing the issue. var body: some View { VStack { Rectangle() .frame(maxWidth: .infinity) .frame(height: 60) .padding(.horizontal) .padding(.top) ScrollView { ForEach(0...5, id: \.self) { _ in RoundedRectangle(cornerRadius: 10) .fill(.green) .frame(maxWidth: .infinity) .frame(height: 100) .padding(.horizontal) } } } .navigationTitle("Hello World") } }
2
0
297
14h
Creating UTImportedTypeDeclarations entries yields duplicate Open menu entry
My iPadOS app can open .xml files. In my XMLApp.swift, I hooked up a: var body: some Scene { WindowGroup(id: "main") { .commands CommandGroup(replacing: .newItem) { ... Button(.openDot) { openXMLFile() } ... Next, I entered a new UTImportedTypeDeclarations / UTExportedTypeDeclarations in Project Settings -> Target -> Info -> Document Types, Exported Type Identifiers, Imported Type Identifiers, for the XML file-type: ... <key>UTImportedTypeDeclarations</key> <array> <dict> <key>UTTypeConformsTo</key> <array> <string>public.data</string> <string>public.xml</string> <string>public.content</string> </array> ... As soon as I do that, Xcode creates an additional Open... menu entry all the way at the bottom of the File menu. I cannot get rid of this additional menu entry. Its state is disabled (grayed out). I have my own Open (per the code above), which also responds to ⌘ - O. My menu entry works fine, as long as I disable the same keyboard shortcut so they don't collide. The extra Open entry is also displayed on the matching iPadOS simulator. From the same codebase, the Open is not displayed on the Mac (targeting macOS, not Catalyst). On macOS, only my Open is in the File menu, as expected. Why is there a duplicate Open menu entry and how do I get rid of it?
0
0
119
1d
Toolbar Display Bug When Using Zoom NavigationTransition with Swipe-Back Gesture
Could anyone help confirm if this is a bug and suggest possible solutions? Thanksssss In iOS 18, when using Zoom NavigationTransition, the toolbar from the destination view may randomly appear on the source view after navigating back with the swipe-back gesture. Re-entering the destination view and navigating back again can temporarily resolve the issue, but it may still occur intermittently. This bug only happens with Zoom NavigationTransition and does not occur when using a button tap to navigate back. import SwiftUI struct test: View { @Namespace private var namespace var body: some View { NavigationStack { NavigationLink { Image("img1") .resizable() .navigationTransition(.zoom(sourceID: 1, in: namespace)) .toolbar { ToolbarItem(placement: .bottomBar) { Text("destination noDisappear") } } } label: { Image("img1") .resizable() .frame(width: 100, height: 100) .matchedTransitionSource(id: 1, in: namespace) .toolbar { ToolbarItem(placement: .bottomBar) { Text("source toolbar") } } } } } }
2
0
333
1d
View Navigation Title Disappears on watchOS Target When Built With Xcode 26+
I have a SwiftUI view in a watch companion app, and when I build my app with Xcode 26.2 or 26.3, the navigation title on a presented screen disappears after the watch screen goes dark. So, the navigation title is only visible when the screen is first presented and not again after the watch screen goes dark, for example when the user lowers their arm. Please see the screenshots for a better understanding. Notice that the "Bench Press" text is not visible in the third image. Also, I’ve confirmed that this does not happen when the app is built with Xcode 16.4. First Image (initial presentation of the screen): Second Image (watch screen goes dark): Third Image (watch screen goes back on, title missing): Although I've confirmed that this is related to Xcode versioning, and it happens on multiple screens, here is the redacted version of this SwiftUI view that is shown in the screenshots, in case it helps: var body: some View { NavigationStack(path: $viewModel.pushedViews) { TabView(selection: $selectedTab) { ... ZStack { List { ForEach(Array(viewModel.setModels.enumerated()), id: \.element) { index, setModel in VStack(spacing: 8.0) { SetContentView() } } ... } .listStyle(.plain) .buttonStyle(.plain) VStack { WatchRestTimerView(viewModel: viewModel.restTimerViewModel) Spacer() } } .tag(WatchExerciseLoggingTab.logExercise) // HERE IS THE TITLE SET .navigationTitle(viewModel.name) NowPlayingView().tag(WatchExerciseLoggingTab.nowPlaying) } .tabViewStyle(PageTabViewStyle()) .navigationDestination(for: WatchWeightAndSetExerciseSummaryPushedView.self, destination: { _ in RedactedView() }) } } This prevents me from migrating to Xcode 26, I would also appreciate if anyone has a work around until there is a fix for this, I mean I can stop using navigation title and add a Text at the top but it is not quite the same UI experience we get from the navigation title in a watch app.
0
0
27
4d
Embedded Collection View in SwiftUI offset issue
I have a collection view that covers all the screen and it is scrolling behavior is paging. This collection view is embedded in a UIViewRepresentable and used in a SwiftUI app. The issue is that when users rotate the devices, sometimes the CollectionView.contentOffset get miscalculated and shows 2 pages. This is the code that I'm using for the collectionView and collectionViewLayout: class PageFlowLayout: UICollectionViewFlowLayout { override class var layoutAttributesClass: AnyClass { UICollectionViewLayoutAttributes.self } private var calculatedAttributes: [UICollectionViewLayoutAttributes] = [] private var calculatedContentWidth: CGFloat = 0 private var calculatedContentHeight: CGFloat = 0 public weak var delegate: PageFlowLayoutDelegate? override var collectionViewContentSize: CGSize { return CGSize(width: self.calculatedContentWidth, height: self.calculatedContentHeight) } override init() { super.init() self.estimatedItemSize = .zero self.scrollDirection = .horizontal self.minimumLineSpacing = 0 self.minimumInteritemSpacing = 0 self.sectionInset = .zero } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func prepare() { guard let collectionView = collectionView, collectionView.numberOfSections > 0, calculatedAttributes.isEmpty else { return } estimatedItemSize = collectionView.bounds.size for item in 0..<collectionView.numberOfItems(inSection: 0) { let indexPath = IndexPath(item: item, section: 0) let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath) let itemOrigin = CGPoint(x: CGFloat(item) * collectionView.frame.width, y: 0) attributes.frame = .init(origin: itemOrigin, size: collectionView.frame.size) calculatedAttributes.append(attributes) } calculatedContentWidth = collectionView.bounds.width * CGFloat(calculatedAttributes.count) calculatedContentHeight = collectionView.bounds.size.height } override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { return calculatedAttributes.compactMap { return $0.frame.intersects(rect) ? $0 : nil } } override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { return calculatedAttributes[indexPath.item] } override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { guard let collectionView else { return false } if newBounds.size != collectionView.bounds.size { return true } if newBounds.size.width > 0 { let pages = calculatedContentWidth / newBounds.size.width // If the contentWidth matches the number of pages, // if not it requires to layout the cells let arePagesExact = pages.truncatingRemainder(dividingBy: 1) == 0 return !arePagesExact } return false } override func invalidateLayout() { calculatedAttributes = [] super.invalidateLayout() } override func shouldInvalidateLayout(forPreferredLayoutAttributes preferredAttributes: UICollectionViewLayoutAttributes, withOriginalAttributes originalAttributes: UICollectionViewLayoutAttributes) -> Bool { guard let collectionView, #available(iOS 18.0, *) else { return false } return preferredAttributes.size != collectionView.bounds.size } override func invalidateLayout(with context: UICollectionViewLayoutInvalidationContext) { guard let customContext = context as? UICollectionViewFlowLayoutInvalidationContext else { return } if let collectionView, let currentPage = delegate?.currentPage() { let delta = (CGFloat(currentPage) * collectionView.bounds.width) - collectionView.contentOffset.x customContext.contentOffsetAdjustment.x += delta } calculatedAttributes = [] super.invalidateLayout(with: customContext) } override func prepare(forAnimatedBoundsChange oldBounds: CGRect) { super.prepare(forAnimatedBoundsChange: oldBounds) guard let collectionView else { return } if oldBounds.width != collectionView.bounds.width { invalidateLayout() } } override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint) -> CGPoint { guard let collectionView, let currentPage = delegate?.currentPage() else { return .zero } let targetContentOffset = super.targetContentOffset(forProposedContentOffset: proposedContentOffset) let targetPage = targetContentOffset.x / collectionView.frame.width if targetPage != CGFloat(currentPage) { let xPosition = CGFloat(currentPage) * collectionView.frame.width return CGPoint(x: xPosition, y: 0) } return targetContentOffset } // This function updates the contentOffset in case is wrong override func finalizeCollectionViewUpdates() { guard let collectionView, let currentPage = delegate?.currentPage() else { return } let xPosition = CGFloat(currentPage) * collectionView.bounds.width if xPosition != collectionView.contentOffset.x { let offset = CGPoint(x: xPosition, y: 0) collectionView.setContentOffset(offset, animated: false) } } } The full implementation is attached in the .txt file: RotationTestView.txt
6
0
156
5d
TabView's Tab Label Image symbolEffect not allowed?
Hi, I'm using a TabView and for a given case I wish to have the icon of the Tab animated by symbolEffect to signify a state. The symbolEffect however doesn't seem to have an effect when used on a tab's label image. Is it really not possible? Tab(value: .hello) { EmptyView() } label: { Image(systemName: "hand.wave.fill") .symbolEffect(.wiggle, options: .repeating) } I still wish to use the TabView because it's amazing.
2
0
63
5d
fullScreenCover & Sheet modifier lifecycles
Hello everyone, I’m running into an issue where a partial sheet repeatedly presents and dismisses in a loop. Setup The main screen is presented using fullScreenCover From that screen, a button triggers a standard partial-height sheet The sheet is presented using .sheet(item:) Expected Behavior Tapping the button should present the sheet once and allow it to be dismissed normally. Actual Behavior After the sheet is triggered, it continuously presents and dismisses. What I’ve Verified The bound item is not being reassigned in either the parent or the presented view There is no .task, .onAppear, or .onChange that sets the item again The loop appears to happen without any explicit state updates Additional Context I encountered a very similar issue when iOS 26.0 was first released At that time, moving the .sheet modifier to a higher parent level resolved the issue The problem has now returned on iOS 26.4 beta I’m currently unable to reproduce this in a minimal sample project, which makes it unclear whether: this is a framework regression, or I’m missing a new presentation requirement Environment iOS: 26.4 beta Xcode: 26.4 beta I’ve attached a screen recording of the behavior. Has anyone else experienced this with a fullScreenCover → sheet flow on iOS 26.4? Any guidance or confirmation would be greatly appreciated. Thank you!
3
0
249
1w
iOS 26: Interactive sheet dismissal causes layout hitch in underlying SwiftUI view
I’ve been investigating a noticeable animation hitch when interactively dismissing a sheet over a SwiftUI screen with moderate complexity. This was not the case on iOS 18, so I’m curious if others are seeing the same on iOS 26 or have found any mitigations. When dismissing a sheet via the swipe gesture, there’s a visible hitch right after lift-off. The hitch comes from layout work in the underlying view (behind the sheet) The duration scales with the complexity of that view (e.g. number of TextFields/layout nodes) The animation for programmatic dismiss (e.g. tapping a “Done” button) is smooth, although it hangs for a similar amount of time before dismissing, so it appears that the underlying work still happens. SwiftUI is not reevaluating the body during this (validated with Self._printChanges()), so that is not the cause. Using Instruments, the hitch shows up as a layout spike on the main thread: 54ms UIView layoutSublayersOfLayer 54ms └─ _UIHostingView.layoutSubviews 38ms └─ SwiftUI.ViewGraph.updateOutputs 11ms ├─ partial apply for implicit closure #1 in closure #1 │ in closure #1 in Attribute.init<A>(_:) 4ms └─ -[UIView For the same hierarchy with varying complexity: ~3 TextFields in a List: ~25ms (not noticeable) ~20+ TextFields: ~60ms (clearly visible hitch) The same view hierarchy on iOS 18 did not exhibit a visible hitch. I’ve tested this on an iOS 26.4 device and simulator. I’ve also included a minimum reproducible example that illustrates this: struct ContentView: View { @State var showSheet = false var body: some View { NavigationStack { ScrollView { ForEach(0..<120) { _ in RowView() } } .navigationTitle("Repro") .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Present") { showSheet = true } } } .sheet(isPresented: $showSheet) { PresentedSheet() } } } } struct RowView: View { @State var first = "" @State var second = "" var body: some View { VStack(alignment: .leading, spacing: 12) { Text("Row") .font(.headline) HStack(spacing: 12) { TextField("First", text: $first) .textFieldStyle(.roundedBorder) TextField("Second", text: $second) .textFieldStyle(.roundedBorder) } HStack(spacing: 12) { Text("Third") Text("Fourth") Image(systemName: "chevron.right") } } } } struct PresentedSheet: View { @Environment(\.dismiss) private var dismiss var body: some View { NavigationStack { List {} .navigationTitle("Swipe To Dismiss Me") .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Done") { dismiss() } } } } } } Is anyone else experiencing this and have any mitigations been found beyond reducing view complexity? I’ve filed a feedback report under FB22501630.
1
0
144
1w
tvOS: Background audio + local caching works on Simulator but stops on real Apple TV device
Description: I’m developing a tvOS app using SwiftUI where we play background audio (music) in the Welcome screen, with support for offline playback via local caching. 🔹 Feature Overview App fetches audio metadata from API Starts streaming audio (HLS .m3u8) immediately In parallel, downloads the raw audio file (.mp3) Once download completes: Switches playback from streaming → local file On next launch (offline mode), app plays audio from local storage 🔹 Issue This flow works perfectly on the Simulator, but on a real Apple TV device: Audio plays for a few seconds (2–5 sec) and then stops Especially after switching from streaming → local file No explicit AVPlayer error is logged Playback sometimes stops after UI updates or periodic API refresh 🔹 Implementation Details Using AVPlayer with AVPlayerItem Background audio controlled via a shared manager (singleton) Files stored locally using FileManager (currently using .cachesDirectory) Switching playback using: player.replaceCurrentItem(with: AVPlayerItem(url: localURL)) player.play() 🔹 Observations Works reliably on Simulator On device: Playback stops silently Seems related to lifecycle, buffering, or file access No issues when continuously streaming (without switching to local) 🔹 Questions Is there any limitation or known issue with AVPlayer when switching from streaming (HLS) to local file playback on tvOS? Are there specific requirements for playing locally cached media files on tvOS (e.g., file location, permissions, or sandbox behavior)? What is the recommended storage location and size limit for cached media files on tvOS? We understand tvOS has limited persistent storage Is .cachesDirectory the correct approach for this use case? Are there known differences in AVPlayer behavior between Simulator and real Apple TV devices (especially regarding buffering or lifecycle)? What is the recommended approach for implementing offline background audio on tvOS apps? 🔹 Goal We want to implement a reliable system where: Audio streams initially Seamlessly switches to local file after download Continues playing without interruption Supports offline playback on subsequent launches Any guidance or best practices would be greatly appreciated. Thank you!
1
0
199
1w
Flutter iOS Project: WidgetKit Extension Not Embedding / Build Cycle Error
Hi, I need your opinion about an issue we faced while trying to implement an iOS widget in our Flutter app. Here is what we did and the problems we encountered: We created a Widget Extension (SwiftUI + WidgetKit) inside the existing Flutter iOS project. The widget files were generated correctly (Widget.swift, WidgetBundle.swift, Info.plist, etc.). However, during the integration, we faced multiple issues: Build Cycle Error We repeatedly got: “Cycle inside Runner; building could produce unreliable results” This was related to embedding the widget extension into the Runner target. Embed Problems Sometimes Xcode did not automatically create the “Embed App Extensions” phase. When we added it manually → build cycle errors appeared. When we removed it → the widget was not embedded at all (no PlugIns folder in Runner.app). Duplicate / Conflicting Embed The extension appeared both in: “Embed Foundation Extensions” “Frameworks, Libraries, and Embedded Content” Removing one often broke the build or removed the other as well. Widget Not Appearing Even when build succeeded: Widget did not appear on device PlugIns/Widget.appex was missing from build output Flutter Linking Errors In another test project, we got: Undefined symbol: _FlutterMethodChannel Undefined symbol: _FlutterBasicMessageChannel etc. This happened because the widget extension tried to link Flutter dependencies, which should not happen. App Group Confusion We also tried adding App Group (group.com.xxx), but behavior didn’t change. Conclusion: We suspect the root issue is: The Flutter template we are using was not designed for WidgetKit integration Xcode embedding phases and Flutter build scripts conflict with extension targets Question: In your opinion: Is this a known limitation with Flutter-based iOS projects? Is there a clean way to integrate WidgetKit without breaking the Runner target? Or is it better to create a separate native iOS module for the widget? Any guidance would be really appreciated. Thanks!
0
0
79
1w
tvOS: Background audio + local caching works on Simulator but stops on real Apple TV device
Description: I’m developing a tvOS app using SwiftUI where we play background audio (music) in the Welcome screen, with support for offline playback via local caching. Feature Overview: App fetches audio metadata from API Starts streaming audio (HLS .m3u8) immediately In parallel, downloads the raw audio file (.mp3) Once download completes: Switches playback from streaming → local file On next launch (offline mode), app plays audio from local storage Issue: This flow works perfectly on the Simulator, but on a real Apple TV device: Audio plays for a few seconds (2–5 sec) and then stops Especially after switching from streaming → local file No explicit AVPlayer error is logged Playback sometimes stops after UI updates or periodic API refresh Implementation Details: Using AVPlayer with AVPlayerItem Background audio controlled via a shared manager (singleton) Files stored locally using FileManager (currently using .cachesDirectory) Switching playback using: player.replaceCurrentItem(with: AVPlayerItem(url: localURL)) player.play() Observations: Works reliably on Simulator On device: -- Playback stops silently -- Seems related to lifecycle, buffering, or file access No issues when continuously streaming (without switching to local) Questions: Is there any limitation or known issue with AVPlayer when switching from streaming (HLS) to local file playback on tvOS? Are there specific requirements for playing locally cached media files on tvOS (e.g., file location, permissions, or sandbox behavior)? What is the recommended storage location and size limit for cached media files on tvOS? We understand tvOS has limited persistent storage Is .cachesDirectory the correct approach for this use case? Are there known differences in AVPlayer behavior between Simulator and real Apple TV devices (especially regarding buffering or lifecycle)? What is the recommended approach for implementing offline background audio on tvOS apps? Goal: We want to implement a reliable system where: Audio streams initially Seamlessly switches to local file after download Continues playing without interruption Supports offline playback on subsequent launches Any guidance or best practices would be greatly appreciated. Thank you!
0
0
125
1w
Navigation bar flickers when pushing to a different screen
Hi everyone, I’m building a SwiftUI app using NavigationStack and running into a weird nav bar issue. For the setup I have a 'home' screen with a vertical ScrollView and a large edge-to-edge header that extends under the top safe area (using .ignoresSafeArea(edges: .top)). I also have a 'detail' screen with a similar immersive layout, where the header/poster image sits at the top and the ScrollView also extends under the top area. I’m using the native navigation bar on both screens and default back button, not a custom nav bar, and I’m not manually configuring UINavigationBarAppearance, I'm just relying on SwiftUI’s default/automatic toolbar behavior. The problem I’m facing is when I push from home to the detail screen, the top nav area briefly flickers and shows the system navigation bar/material background (white in light mode, black in dark mode). It’s clearly the system material, not the poster/image underneath. The screen initially renders with that nav bar state (white/dark), and only after I start scrolling does it correct itself and visually align with the header/background behind it. What I'm thinking is that maybe the detail screen initially renders with systemBackground, so the nav bar uses its default (standard) appearance on the first frame, and only after layout/interaction, once the image-derived background settles, does it switch to the correct scroll-edge/transparent style. One important thing, if I hide the nav bar on the detail screen using .toolbar(.hidden, for: .navigationBar), the issue disappears completely. So this seems specifically tied to the native nav bar’s initial render/appearance timing during the push, rather than just the layout or image loading. I’d prefer to keep the native nav bar and back button rather than implement a custom approach. Has anyone faced this issue before, or is there a correct way to structure edge-to-edge content under the nav bar so it renders properly on first push? Video of the issue: https://imgur.com/a/OYHtYbp
1
0
107
1w
Navigation bar flickers when pushing to a different screen
Hi everyone, I’m building a SwiftUI app using NavigationStack and running into a weird nav bar issue. For the setup I have a 'home' screen with a vertical ScrollView and a large edge-to-edge header that extends under the top safe area (using .ignoresSafeArea(edges: .top)). I also have a 'detail' screen with a similar immersive layout, where the header/poster image sits at the top and the ScrollView also extends under the top area. I’m using the native navigation bar on both screens and default back button, not a custom nav bar, and I’m not manually configuring UINavigationBarAppearance, I'm just relying on SwiftUI’s default/automatic toolbar behavior. The problem I’m facing is when I push from home to the detail screen, the top nav area briefly flickers and shows the system navigation bar/material background (white in light mode, black in dark mode). It’s clearly the system material, not the poster/image underneath. The screen initially renders with that nav bar state (white/dark), and only after I start scrolling does it correct itself and visually align with the header/background behind it. What I'm thinking is that maybe the detail screen initially renders with systemBackground, so the nav bar uses its default (standard) appearance on the first frame, and only after layout/interaction, once the image-derived background settles, does it switch to the correct scroll-edge/transparent style. One important thing, if I hide the nav bar on the detail screen using .toolbar(.hidden, for: .navigationBar), the issue disappears completely. So this seems specifically tied to the native nav bar’s initial render/appearance timing during the push, rather than just the layout or image loading. I’d prefer to keep the native nav bar and back button rather than implement a custom approach. Has anyone faced this issue before, or is there a correct way to structure edge-to-edge content under the nav bar so it renders properly on first push? Video of the issue: https://imgur.com/a/OYHtYbp NavigationStack { ScrollView { HeroView() } .ignoresSafeArea(edges: .top) .navigationTitle("Cinema") .toolbarTitleDisplayMode(.inlineLarge) .toolbarBackgroundVisibility(.automatic, for: .navigationBar) .navigationDestination(for: Route.self) { route in DetailView(movie: route.movie) } } var body: some View { ScrollView { HeaderPosterView() } .ignoresSafeArea(edges: .top) .navigationBarTitleDisplayMode(.inline) .toolbarBackgroundVisibility(.automatic, for: .navigationBar) } }
0
0
124
1w
Layout Bug: Button icon lags after keyboard dismissal in SwiftUI
Hello everyone, I am experiencing a layout issue in a SwiftUI project where an icon inside a button becomes laggy after the keyboard is dismissed. I have a custom input bar designed with an HStack containing a TextField and a Button with a microphone.fill icon. The entire HStack is styled using a .clipShape(.capsule) and a background color and I am using @FocusState to manage the keyboard focus. When the user taps the TextField, the keyboard appears, and the entire view moves up correctly to make room. But when the keyboard is dismissed by the button action isPromptFieldFocused = false, the capsule-shaped background and the text field return to their original position, but the icon on the button (and just the icon) doesn't. The microphone icon inside the button does not follow the movement. It remains stuck at the "keyboard-up" height for a moment until the view is refreshed, breaking the UI. And by the way, the icon correctly returns to its original position with the other UI elements if the user presses the return key on their keyboard. import SwiftUI struct ContentView: View { @State var userText: String = "" @FocusState var isTextFieldFocused: Bool var body: some View { HStack { TextField("Type here...", text: $userText) .focused($isTextFieldFocused) .textInputAutocapitalization(.sentences) .textFieldStyle(PlainTextFieldStyle()) .padding(.leading, 12) .padding(.trailing, 4) Button(action: { print("Microphone pressed") isPromptFieldFocused = false }) { Image(systemName: "microphone.fill") .font(.system(size: 22, weight: .semibold)) .foregroundStyle(.white) .padding(14) } .background(Color.black) .clipShape(Circle()) .padding(.trailing, 14) .padding(.vertical, 14) } .background(Color.lightGray) .clipShape(Capsule()) .padding() } } I've already tried using different animation types (e.g., .default, .spring) and explicitly setting the frame of the button. Has anyone encountered this specific behavior where an Image(systemName:) ignores the parent container's transition during keyboard dismissal? I would appreciate any insights on how to ensure the entire HStack and its children animate back down in sync.
0
0
122
1w
Initial presentation of popover hangs when shown from a button in the toolbar
I have a simple reproducer here: struct ContentView: View { @State private var isOn = false @State private var isPresented = false var body: some View { NavigationStack { Color.blue .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Press here") { isPresented = true } .popover(isPresented: $isPresented) { Color.green .frame(idealWidth: 400, idealHeight: 500) .presentationCompactAdaptation(.popover) } } } } } } When I tap on the button in the toolbar you can see there is a hang then the popover shows. Then every time after there is no longer a hang so this seems like a bug. Any ideas? I'm using Xcode 26.3 and a iPad Pro 13-inch (M5) (26.4) simulator.
3
3
182
1w
SwiftUI Text rendering with too small height / one line missing causing unexpected text truncation on iPhone devices
FB: FB22577211 The following trivial SwiftUI Text rendering causes wrong text layout and truncated text. The text should take the required height to render the text without truncation. Adding fixedSize does also not solve this. This bug only happens on devices and not on the simulator. Confirmed with iPhone 15 and iOS 26.4.1 but my colleague used another iPhone so it’s multiple iPhone devices. import SwiftUI let txt = """ Es sollte die erste Japan-Tournee von vielen werden, kein anderes Land – abgesehen von Österreich und der Schweiz – bereisten die Berliner Philharmoniker häufiger. Wie kam es zu dem überschäumend herzlichen Empfang, der dem Orchester bei seinem ersten Gastspiel in Tokio bereitet wurde und wie wurde das Land zu einer »zweiten Heimat« für die Berliner? Ein konkreter historischer Grundstein für das hohe Ansehen klassischer Musik »made in Germany« in Japan wurde bereits im 19. Jahrhunderts gelegt: Als Teil von umfassenden gesellschaftlichen Modernisierungsmaßnahmen vergab die Regierung ab 1868 Stipendien an junge japanische Intellektuelle, damit diese an den besten internationalen Instituten studieren konnten. Berlin wurde – neben Wien – als globales Zentrum der Musik betrachtet, und so erhielten viele japanische Studierende um die Jahrhundertwende die Gelegenheit, von Komponisten wie etwa Max Bruch zu lernen. Zurück in der Heimat, teilten sie ihre Begeisterung für die europäische Kunstmusik sowie das Wissen um die instrumentale und kompositorische Praxis der klassisch-romantischen Tradition. """ struct ContentView: View { var body: some View { VStack { Text(txt) } .padding(.leading, 20) .padding(.trailing, 20) .frame(maxWidth: .infinity) } } This is also enough: Text(txt) .padding(.horizontal, 20) .fixedSize(horizontal: false, vertical: true) Expected: Text is rendered without truncation / ellipsis. Actual: Text is rendered with too small height / missing one line so it’s truncated / with ellipsis.
Replies
0
Boosts
0
Views
74
Activity
7h
Navigation title scroll issue in iOS 26
Navigation title scroll along with the content in iOS 26. working fine in iOS 18 and below. One of my UI component is outside the scrollview which is causing the issue. var body: some View { VStack { Rectangle() .frame(maxWidth: .infinity) .frame(height: 60) .padding(.horizontal) .padding(.top) ScrollView { ForEach(0...5, id: \.self) { _ in RoundedRectangle(cornerRadius: 10) .fill(.green) .frame(maxWidth: .infinity) .frame(height: 100) .padding(.horizontal) } } } .navigationTitle("Hello World") } }
Replies
2
Boosts
0
Views
297
Activity
14h
Creating UTImportedTypeDeclarations entries yields duplicate Open menu entry
My iPadOS app can open .xml files. In my XMLApp.swift, I hooked up a: var body: some Scene { WindowGroup(id: "main") { .commands CommandGroup(replacing: .newItem) { ... Button(.openDot) { openXMLFile() } ... Next, I entered a new UTImportedTypeDeclarations / UTExportedTypeDeclarations in Project Settings -> Target -> Info -> Document Types, Exported Type Identifiers, Imported Type Identifiers, for the XML file-type: ... <key>UTImportedTypeDeclarations</key> <array> <dict> <key>UTTypeConformsTo</key> <array> <string>public.data</string> <string>public.xml</string> <string>public.content</string> </array> ... As soon as I do that, Xcode creates an additional Open... menu entry all the way at the bottom of the File menu. I cannot get rid of this additional menu entry. Its state is disabled (grayed out). I have my own Open (per the code above), which also responds to ⌘ - O. My menu entry works fine, as long as I disable the same keyboard shortcut so they don't collide. The extra Open entry is also displayed on the matching iPadOS simulator. From the same codebase, the Open is not displayed on the Mac (targeting macOS, not Catalyst). On macOS, only my Open is in the File menu, as expected. Why is there a duplicate Open menu entry and how do I get rid of it?
Replies
0
Boosts
0
Views
119
Activity
1d
Toolbar Display Bug When Using Zoom NavigationTransition with Swipe-Back Gesture
Could anyone help confirm if this is a bug and suggest possible solutions? Thanksssss In iOS 18, when using Zoom NavigationTransition, the toolbar from the destination view may randomly appear on the source view after navigating back with the swipe-back gesture. Re-entering the destination view and navigating back again can temporarily resolve the issue, but it may still occur intermittently. This bug only happens with Zoom NavigationTransition and does not occur when using a button tap to navigate back. import SwiftUI struct test: View { @Namespace private var namespace var body: some View { NavigationStack { NavigationLink { Image("img1") .resizable() .navigationTransition(.zoom(sourceID: 1, in: namespace)) .toolbar { ToolbarItem(placement: .bottomBar) { Text("destination noDisappear") } } } label: { Image("img1") .resizable() .frame(width: 100, height: 100) .matchedTransitionSource(id: 1, in: namespace) .toolbar { ToolbarItem(placement: .bottomBar) { Text("source toolbar") } } } } } }
Replies
2
Boosts
0
Views
333
Activity
1d
Why is the .opacity AnyTransition is marked as nonisolated(unsafe)
Because of this, in Swift 6 mode, Xcode complains about the access, and ask me to use unsafe keyword. To fix it, I need to do this: Anyone can explain this abrupt nonisolated(unsafe) change?
Replies
1
Boosts
0
Views
94
Activity
2d
View Navigation Title Disappears on watchOS Target When Built With Xcode 26+
I have a SwiftUI view in a watch companion app, and when I build my app with Xcode 26.2 or 26.3, the navigation title on a presented screen disappears after the watch screen goes dark. So, the navigation title is only visible when the screen is first presented and not again after the watch screen goes dark, for example when the user lowers their arm. Please see the screenshots for a better understanding. Notice that the "Bench Press" text is not visible in the third image. Also, I’ve confirmed that this does not happen when the app is built with Xcode 16.4. First Image (initial presentation of the screen): Second Image (watch screen goes dark): Third Image (watch screen goes back on, title missing): Although I've confirmed that this is related to Xcode versioning, and it happens on multiple screens, here is the redacted version of this SwiftUI view that is shown in the screenshots, in case it helps: var body: some View { NavigationStack(path: $viewModel.pushedViews) { TabView(selection: $selectedTab) { ... ZStack { List { ForEach(Array(viewModel.setModels.enumerated()), id: \.element) { index, setModel in VStack(spacing: 8.0) { SetContentView() } } ... } .listStyle(.plain) .buttonStyle(.plain) VStack { WatchRestTimerView(viewModel: viewModel.restTimerViewModel) Spacer() } } .tag(WatchExerciseLoggingTab.logExercise) // HERE IS THE TITLE SET .navigationTitle(viewModel.name) NowPlayingView().tag(WatchExerciseLoggingTab.nowPlaying) } .tabViewStyle(PageTabViewStyle()) .navigationDestination(for: WatchWeightAndSetExerciseSummaryPushedView.self, destination: { _ in RedactedView() }) } } This prevents me from migrating to Xcode 26, I would also appreciate if anyone has a work around until there is a fix for this, I mean I can stop using navigation title and add a Text at the top but it is not quite the same UI experience we get from the navigation title in a watch app.
Replies
0
Boosts
0
Views
27
Activity
4d
Embedded Collection View in SwiftUI offset issue
I have a collection view that covers all the screen and it is scrolling behavior is paging. This collection view is embedded in a UIViewRepresentable and used in a SwiftUI app. The issue is that when users rotate the devices, sometimes the CollectionView.contentOffset get miscalculated and shows 2 pages. This is the code that I'm using for the collectionView and collectionViewLayout: class PageFlowLayout: UICollectionViewFlowLayout { override class var layoutAttributesClass: AnyClass { UICollectionViewLayoutAttributes.self } private var calculatedAttributes: [UICollectionViewLayoutAttributes] = [] private var calculatedContentWidth: CGFloat = 0 private var calculatedContentHeight: CGFloat = 0 public weak var delegate: PageFlowLayoutDelegate? override var collectionViewContentSize: CGSize { return CGSize(width: self.calculatedContentWidth, height: self.calculatedContentHeight) } override init() { super.init() self.estimatedItemSize = .zero self.scrollDirection = .horizontal self.minimumLineSpacing = 0 self.minimumInteritemSpacing = 0 self.sectionInset = .zero } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func prepare() { guard let collectionView = collectionView, collectionView.numberOfSections > 0, calculatedAttributes.isEmpty else { return } estimatedItemSize = collectionView.bounds.size for item in 0..<collectionView.numberOfItems(inSection: 0) { let indexPath = IndexPath(item: item, section: 0) let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath) let itemOrigin = CGPoint(x: CGFloat(item) * collectionView.frame.width, y: 0) attributes.frame = .init(origin: itemOrigin, size: collectionView.frame.size) calculatedAttributes.append(attributes) } calculatedContentWidth = collectionView.bounds.width * CGFloat(calculatedAttributes.count) calculatedContentHeight = collectionView.bounds.size.height } override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { return calculatedAttributes.compactMap { return $0.frame.intersects(rect) ? $0 : nil } } override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { return calculatedAttributes[indexPath.item] } override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { guard let collectionView else { return false } if newBounds.size != collectionView.bounds.size { return true } if newBounds.size.width > 0 { let pages = calculatedContentWidth / newBounds.size.width // If the contentWidth matches the number of pages, // if not it requires to layout the cells let arePagesExact = pages.truncatingRemainder(dividingBy: 1) == 0 return !arePagesExact } return false } override func invalidateLayout() { calculatedAttributes = [] super.invalidateLayout() } override func shouldInvalidateLayout(forPreferredLayoutAttributes preferredAttributes: UICollectionViewLayoutAttributes, withOriginalAttributes originalAttributes: UICollectionViewLayoutAttributes) -> Bool { guard let collectionView, #available(iOS 18.0, *) else { return false } return preferredAttributes.size != collectionView.bounds.size } override func invalidateLayout(with context: UICollectionViewLayoutInvalidationContext) { guard let customContext = context as? UICollectionViewFlowLayoutInvalidationContext else { return } if let collectionView, let currentPage = delegate?.currentPage() { let delta = (CGFloat(currentPage) * collectionView.bounds.width) - collectionView.contentOffset.x customContext.contentOffsetAdjustment.x += delta } calculatedAttributes = [] super.invalidateLayout(with: customContext) } override func prepare(forAnimatedBoundsChange oldBounds: CGRect) { super.prepare(forAnimatedBoundsChange: oldBounds) guard let collectionView else { return } if oldBounds.width != collectionView.bounds.width { invalidateLayout() } } override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint) -> CGPoint { guard let collectionView, let currentPage = delegate?.currentPage() else { return .zero } let targetContentOffset = super.targetContentOffset(forProposedContentOffset: proposedContentOffset) let targetPage = targetContentOffset.x / collectionView.frame.width if targetPage != CGFloat(currentPage) { let xPosition = CGFloat(currentPage) * collectionView.frame.width return CGPoint(x: xPosition, y: 0) } return targetContentOffset } // This function updates the contentOffset in case is wrong override func finalizeCollectionViewUpdates() { guard let collectionView, let currentPage = delegate?.currentPage() else { return } let xPosition = CGFloat(currentPage) * collectionView.bounds.width if xPosition != collectionView.contentOffset.x { let offset = CGPoint(x: xPosition, y: 0) collectionView.setContentOffset(offset, animated: false) } } } The full implementation is attached in the .txt file: RotationTestView.txt
Replies
6
Boosts
0
Views
156
Activity
5d
TabView's Tab Label Image symbolEffect not allowed?
Hi, I'm using a TabView and for a given case I wish to have the icon of the Tab animated by symbolEffect to signify a state. The symbolEffect however doesn't seem to have an effect when used on a tab's label image. Is it really not possible? Tab(value: .hello) { EmptyView() } label: { Image(systemName: "hand.wave.fill") .symbolEffect(.wiggle, options: .repeating) } I still wish to use the TabView because it's amazing.
Replies
2
Boosts
0
Views
63
Activity
5d
fullScreenCover & Sheet modifier lifecycles
Hello everyone, I’m running into an issue where a partial sheet repeatedly presents and dismisses in a loop. Setup The main screen is presented using fullScreenCover From that screen, a button triggers a standard partial-height sheet The sheet is presented using .sheet(item:) Expected Behavior Tapping the button should present the sheet once and allow it to be dismissed normally. Actual Behavior After the sheet is triggered, it continuously presents and dismisses. What I’ve Verified The bound item is not being reassigned in either the parent or the presented view There is no .task, .onAppear, or .onChange that sets the item again The loop appears to happen without any explicit state updates Additional Context I encountered a very similar issue when iOS 26.0 was first released At that time, moving the .sheet modifier to a higher parent level resolved the issue The problem has now returned on iOS 26.4 beta I’m currently unable to reproduce this in a minimal sample project, which makes it unclear whether: this is a framework regression, or I’m missing a new presentation requirement Environment iOS: 26.4 beta Xcode: 26.4 beta I’ve attached a screen recording of the behavior. Has anyone else experienced this with a fullScreenCover → sheet flow on iOS 26.4? Any guidance or confirmation would be greatly appreciated. Thank you!
Replies
3
Boosts
0
Views
249
Activity
1w
iOS 26: Interactive sheet dismissal causes layout hitch in underlying SwiftUI view
I’ve been investigating a noticeable animation hitch when interactively dismissing a sheet over a SwiftUI screen with moderate complexity. This was not the case on iOS 18, so I’m curious if others are seeing the same on iOS 26 or have found any mitigations. When dismissing a sheet via the swipe gesture, there’s a visible hitch right after lift-off. The hitch comes from layout work in the underlying view (behind the sheet) The duration scales with the complexity of that view (e.g. number of TextFields/layout nodes) The animation for programmatic dismiss (e.g. tapping a “Done” button) is smooth, although it hangs for a similar amount of time before dismissing, so it appears that the underlying work still happens. SwiftUI is not reevaluating the body during this (validated with Self._printChanges()), so that is not the cause. Using Instruments, the hitch shows up as a layout spike on the main thread: 54ms UIView layoutSublayersOfLayer 54ms └─ _UIHostingView.layoutSubviews 38ms └─ SwiftUI.ViewGraph.updateOutputs 11ms ├─ partial apply for implicit closure #1 in closure #1 │ in closure #1 in Attribute.init<A>(_:) 4ms └─ -[UIView For the same hierarchy with varying complexity: ~3 TextFields in a List: ~25ms (not noticeable) ~20+ TextFields: ~60ms (clearly visible hitch) The same view hierarchy on iOS 18 did not exhibit a visible hitch. I’ve tested this on an iOS 26.4 device and simulator. I’ve also included a minimum reproducible example that illustrates this: struct ContentView: View { @State var showSheet = false var body: some View { NavigationStack { ScrollView { ForEach(0..<120) { _ in RowView() } } .navigationTitle("Repro") .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Present") { showSheet = true } } } .sheet(isPresented: $showSheet) { PresentedSheet() } } } } struct RowView: View { @State var first = "" @State var second = "" var body: some View { VStack(alignment: .leading, spacing: 12) { Text("Row") .font(.headline) HStack(spacing: 12) { TextField("First", text: $first) .textFieldStyle(.roundedBorder) TextField("Second", text: $second) .textFieldStyle(.roundedBorder) } HStack(spacing: 12) { Text("Third") Text("Fourth") Image(systemName: "chevron.right") } } } } struct PresentedSheet: View { @Environment(\.dismiss) private var dismiss var body: some View { NavigationStack { List {} .navigationTitle("Swipe To Dismiss Me") .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Done") { dismiss() } } } } } } Is anyone else experiencing this and have any mitigations been found beyond reducing view complexity? I’ve filed a feedback report under FB22501630.
Replies
1
Boosts
0
Views
144
Activity
1w
Detect hardware keyboard with SwiftUI
In an application we are developing, we would like to show a (non-interactable) textfield when a hardware keyboard is connected to the iPad. Therefore my question: Using SwiftUI, is it possible to detect the presence of a hardware keyboard and store that state inside a boolean like isHardwareKeyboardConnected?
Replies
1
Boosts
0
Views
95
Activity
1w
tvOS: Background audio + local caching works on Simulator but stops on real Apple TV device
Description: I’m developing a tvOS app using SwiftUI where we play background audio (music) in the Welcome screen, with support for offline playback via local caching. 🔹 Feature Overview App fetches audio metadata from API Starts streaming audio (HLS .m3u8) immediately In parallel, downloads the raw audio file (.mp3) Once download completes: Switches playback from streaming → local file On next launch (offline mode), app plays audio from local storage 🔹 Issue This flow works perfectly on the Simulator, but on a real Apple TV device: Audio plays for a few seconds (2–5 sec) and then stops Especially after switching from streaming → local file No explicit AVPlayer error is logged Playback sometimes stops after UI updates or periodic API refresh 🔹 Implementation Details Using AVPlayer with AVPlayerItem Background audio controlled via a shared manager (singleton) Files stored locally using FileManager (currently using .cachesDirectory) Switching playback using: player.replaceCurrentItem(with: AVPlayerItem(url: localURL)) player.play() 🔹 Observations Works reliably on Simulator On device: Playback stops silently Seems related to lifecycle, buffering, or file access No issues when continuously streaming (without switching to local) 🔹 Questions Is there any limitation or known issue with AVPlayer when switching from streaming (HLS) to local file playback on tvOS? Are there specific requirements for playing locally cached media files on tvOS (e.g., file location, permissions, or sandbox behavior)? What is the recommended storage location and size limit for cached media files on tvOS? We understand tvOS has limited persistent storage Is .cachesDirectory the correct approach for this use case? Are there known differences in AVPlayer behavior between Simulator and real Apple TV devices (especially regarding buffering or lifecycle)? What is the recommended approach for implementing offline background audio on tvOS apps? 🔹 Goal We want to implement a reliable system where: Audio streams initially Seamlessly switches to local file after download Continues playing without interruption Supports offline playback on subsequent launches Any guidance or best practices would be greatly appreciated. Thank you!
Replies
1
Boosts
0
Views
199
Activity
1w
Flutter iOS Project: WidgetKit Extension Not Embedding / Build Cycle Error
Hi, I need your opinion about an issue we faced while trying to implement an iOS widget in our Flutter app. Here is what we did and the problems we encountered: We created a Widget Extension (SwiftUI + WidgetKit) inside the existing Flutter iOS project. The widget files were generated correctly (Widget.swift, WidgetBundle.swift, Info.plist, etc.). However, during the integration, we faced multiple issues: Build Cycle Error We repeatedly got: “Cycle inside Runner; building could produce unreliable results” This was related to embedding the widget extension into the Runner target. Embed Problems Sometimes Xcode did not automatically create the “Embed App Extensions” phase. When we added it manually → build cycle errors appeared. When we removed it → the widget was not embedded at all (no PlugIns folder in Runner.app). Duplicate / Conflicting Embed The extension appeared both in: “Embed Foundation Extensions” “Frameworks, Libraries, and Embedded Content” Removing one often broke the build or removed the other as well. Widget Not Appearing Even when build succeeded: Widget did not appear on device PlugIns/Widget.appex was missing from build output Flutter Linking Errors In another test project, we got: Undefined symbol: _FlutterMethodChannel Undefined symbol: _FlutterBasicMessageChannel etc. This happened because the widget extension tried to link Flutter dependencies, which should not happen. App Group Confusion We also tried adding App Group (group.com.xxx), but behavior didn’t change. Conclusion: We suspect the root issue is: The Flutter template we are using was not designed for WidgetKit integration Xcode embedding phases and Flutter build scripts conflict with extension targets Question: In your opinion: Is this a known limitation with Flutter-based iOS projects? Is there a clean way to integrate WidgetKit without breaking the Runner target? Or is it better to create a separate native iOS module for the widget? Any guidance would be really appreciated. Thanks!
Replies
0
Boosts
0
Views
79
Activity
1w
tvOS: Background audio + local caching works on Simulator but stops on real Apple TV device
Description: I’m developing a tvOS app using SwiftUI where we play background audio (music) in the Welcome screen, with support for offline playback via local caching. Feature Overview: App fetches audio metadata from API Starts streaming audio (HLS .m3u8) immediately In parallel, downloads the raw audio file (.mp3) Once download completes: Switches playback from streaming → local file On next launch (offline mode), app plays audio from local storage Issue: This flow works perfectly on the Simulator, but on a real Apple TV device: Audio plays for a few seconds (2–5 sec) and then stops Especially after switching from streaming → local file No explicit AVPlayer error is logged Playback sometimes stops after UI updates or periodic API refresh Implementation Details: Using AVPlayer with AVPlayerItem Background audio controlled via a shared manager (singleton) Files stored locally using FileManager (currently using .cachesDirectory) Switching playback using: player.replaceCurrentItem(with: AVPlayerItem(url: localURL)) player.play() Observations: Works reliably on Simulator On device: -- Playback stops silently -- Seems related to lifecycle, buffering, or file access No issues when continuously streaming (without switching to local) Questions: Is there any limitation or known issue with AVPlayer when switching from streaming (HLS) to local file playback on tvOS? Are there specific requirements for playing locally cached media files on tvOS (e.g., file location, permissions, or sandbox behavior)? What is the recommended storage location and size limit for cached media files on tvOS? We understand tvOS has limited persistent storage Is .cachesDirectory the correct approach for this use case? Are there known differences in AVPlayer behavior between Simulator and real Apple TV devices (especially regarding buffering or lifecycle)? What is the recommended approach for implementing offline background audio on tvOS apps? Goal: We want to implement a reliable system where: Audio streams initially Seamlessly switches to local file after download Continues playing without interruption Supports offline playback on subsequent launches Any guidance or best practices would be greatly appreciated. Thank you!
Replies
0
Boosts
0
Views
125
Activity
1w
Navigation bar flickers when pushing to a different screen
Hi everyone, I’m building a SwiftUI app using NavigationStack and running into a weird nav bar issue. For the setup I have a 'home' screen with a vertical ScrollView and a large edge-to-edge header that extends under the top safe area (using .ignoresSafeArea(edges: .top)). I also have a 'detail' screen with a similar immersive layout, where the header/poster image sits at the top and the ScrollView also extends under the top area. I’m using the native navigation bar on both screens and default back button, not a custom nav bar, and I’m not manually configuring UINavigationBarAppearance, I'm just relying on SwiftUI’s default/automatic toolbar behavior. The problem I’m facing is when I push from home to the detail screen, the top nav area briefly flickers and shows the system navigation bar/material background (white in light mode, black in dark mode). It’s clearly the system material, not the poster/image underneath. The screen initially renders with that nav bar state (white/dark), and only after I start scrolling does it correct itself and visually align with the header/background behind it. What I'm thinking is that maybe the detail screen initially renders with systemBackground, so the nav bar uses its default (standard) appearance on the first frame, and only after layout/interaction, once the image-derived background settles, does it switch to the correct scroll-edge/transparent style. One important thing, if I hide the nav bar on the detail screen using .toolbar(.hidden, for: .navigationBar), the issue disappears completely. So this seems specifically tied to the native nav bar’s initial render/appearance timing during the push, rather than just the layout or image loading. I’d prefer to keep the native nav bar and back button rather than implement a custom approach. Has anyone faced this issue before, or is there a correct way to structure edge-to-edge content under the nav bar so it renders properly on first push? Video of the issue: https://imgur.com/a/OYHtYbp
Replies
1
Boosts
0
Views
107
Activity
1w
How to let Appkit Scrollview get under sidebar or inspctor?
If I use a SwiftUI Scrollview and scroll horizontally, for example, the scroll content goes underneath the inspector or sidebar views on macOS 26 (probably on older versions as well) But by default, the AppKit scrollviews don't exhibit this behaviour. How do I adapt this to match SwiftUI behavior?
Replies
1
Boosts
0
Views
51
Activity
1w
Interactive Sheet dismiss laggy on iOS26
On iOS 26 I’m seeing a small stutter when dismissing a SwiftUI .sheet with the swipe-down gesture. The same code was smooth on iOS 18. Has anyone else experienced this issue?
Replies
2
Boosts
0
Views
180
Activity
1w
Navigation bar flickers when pushing to a different screen
Hi everyone, I’m building a SwiftUI app using NavigationStack and running into a weird nav bar issue. For the setup I have a 'home' screen with a vertical ScrollView and a large edge-to-edge header that extends under the top safe area (using .ignoresSafeArea(edges: .top)). I also have a 'detail' screen with a similar immersive layout, where the header/poster image sits at the top and the ScrollView also extends under the top area. I’m using the native navigation bar on both screens and default back button, not a custom nav bar, and I’m not manually configuring UINavigationBarAppearance, I'm just relying on SwiftUI’s default/automatic toolbar behavior. The problem I’m facing is when I push from home to the detail screen, the top nav area briefly flickers and shows the system navigation bar/material background (white in light mode, black in dark mode). It’s clearly the system material, not the poster/image underneath. The screen initially renders with that nav bar state (white/dark), and only after I start scrolling does it correct itself and visually align with the header/background behind it. What I'm thinking is that maybe the detail screen initially renders with systemBackground, so the nav bar uses its default (standard) appearance on the first frame, and only after layout/interaction, once the image-derived background settles, does it switch to the correct scroll-edge/transparent style. One important thing, if I hide the nav bar on the detail screen using .toolbar(.hidden, for: .navigationBar), the issue disappears completely. So this seems specifically tied to the native nav bar’s initial render/appearance timing during the push, rather than just the layout or image loading. I’d prefer to keep the native nav bar and back button rather than implement a custom approach. Has anyone faced this issue before, or is there a correct way to structure edge-to-edge content under the nav bar so it renders properly on first push? Video of the issue: https://imgur.com/a/OYHtYbp NavigationStack { ScrollView { HeroView() } .ignoresSafeArea(edges: .top) .navigationTitle("Cinema") .toolbarTitleDisplayMode(.inlineLarge) .toolbarBackgroundVisibility(.automatic, for: .navigationBar) .navigationDestination(for: Route.self) { route in DetailView(movie: route.movie) } } var body: some View { ScrollView { HeaderPosterView() } .ignoresSafeArea(edges: .top) .navigationBarTitleDisplayMode(.inline) .toolbarBackgroundVisibility(.automatic, for: .navigationBar) } }
Replies
0
Boosts
0
Views
124
Activity
1w
Layout Bug: Button icon lags after keyboard dismissal in SwiftUI
Hello everyone, I am experiencing a layout issue in a SwiftUI project where an icon inside a button becomes laggy after the keyboard is dismissed. I have a custom input bar designed with an HStack containing a TextField and a Button with a microphone.fill icon. The entire HStack is styled using a .clipShape(.capsule) and a background color and I am using @FocusState to manage the keyboard focus. When the user taps the TextField, the keyboard appears, and the entire view moves up correctly to make room. But when the keyboard is dismissed by the button action isPromptFieldFocused = false, the capsule-shaped background and the text field return to their original position, but the icon on the button (and just the icon) doesn't. The microphone icon inside the button does not follow the movement. It remains stuck at the "keyboard-up" height for a moment until the view is refreshed, breaking the UI. And by the way, the icon correctly returns to its original position with the other UI elements if the user presses the return key on their keyboard. import SwiftUI struct ContentView: View { @State var userText: String = "" @FocusState var isTextFieldFocused: Bool var body: some View { HStack { TextField("Type here...", text: $userText) .focused($isTextFieldFocused) .textInputAutocapitalization(.sentences) .textFieldStyle(PlainTextFieldStyle()) .padding(.leading, 12) .padding(.trailing, 4) Button(action: { print("Microphone pressed") isPromptFieldFocused = false }) { Image(systemName: "microphone.fill") .font(.system(size: 22, weight: .semibold)) .foregroundStyle(.white) .padding(14) } .background(Color.black) .clipShape(Circle()) .padding(.trailing, 14) .padding(.vertical, 14) } .background(Color.lightGray) .clipShape(Capsule()) .padding() } } I've already tried using different animation types (e.g., .default, .spring) and explicitly setting the frame of the button. Has anyone encountered this specific behavior where an Image(systemName:) ignores the parent container's transition during keyboard dismissal? I would appreciate any insights on how to ensure the entire HStack and its children animate back down in sync.
Replies
0
Boosts
0
Views
122
Activity
1w
Initial presentation of popover hangs when shown from a button in the toolbar
I have a simple reproducer here: struct ContentView: View { @State private var isOn = false @State private var isPresented = false var body: some View { NavigationStack { Color.blue .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Press here") { isPresented = true } .popover(isPresented: $isPresented) { Color.green .frame(idealWidth: 400, idealHeight: 500) .presentationCompactAdaptation(.popover) } } } } } } When I tap on the button in the toolbar you can see there is a hang then the popover shows. Then every time after there is no longer a hang so this seems like a bug. Any ideas? I'm using Xcode 26.3 and a iPad Pro 13-inch (M5) (26.4) simulator.
Replies
3
Boosts
3
Views
182
Activity
1w