Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.

All subtopics
Posts under UI Frameworks topic

Post

Replies

Boosts

Views

Activity

How to get the frame or insets of the new iPadOS 26 window control buttons (close, minimize, fullscreen)?
In iPadOS 26, Apple introduced macOS-style window control buttons (close, minimize, fullscreen) for iPad apps running in a floating window. I'm working on a custom toolbar (UIView) positioned near the top of the window, and I'd like to avoid overlapping with these new controls. However, I haven't found any public API that exposes the frame, layout margins, or safe area insets related to this new UI region. I've checked the window's safeAreaInsets, additionalSafeAreaInsets, and UIWindowSceneDelegate APIs, but none of them seem to reflect the area occupied by these buttons. Is there an officially supported way to: Get the layout information (frame, insets, or margins) of the window control buttons on iPadOS 26? Or, is there a system-defined guideline or padding value we should use to avoid overlapping this new UI? Any clarification or guidance would be appreciated!
6
1
593
Aug ’25
SwiftData document based on iOS18 shows blank screen
I have some apps using SwiftData document based. They work as expected under iOS17, but not under iOS18: install the app on a iPad 11 pro (first gen) from my MacBook open the app and open an existing fils (perfect under iOS17) it shows a blank, white screen, no data I can create a new document, blank screen, no data When I open that newly created file on a iOS 17 iPad pro, it works perfect, as expected The apps were created from scratch under macOS 14.7 with the corresponding Xcode/Swift/UI version. iOS devices under iOS17 Are there any known problems with document based SwiftData-apps under iOS18, are there any changes one has to made? Thank You so much for any help!
6
0
779
Apr ’25
Slider .rotationEffect broken in MacOS 14.5
In a SwiftUI app for MacOS, vertical sliders that I'd created using a rotationEffect of 90° disappeared when I upgraded to Sonoma 14.5 (23F79). With rotations less than 90°, the slider is still visible, but its button is enlarged, growing in size as the rotation angle approaches 90°. Note that the sliders still work, even when rotated by 90° and invisible! The screenshot and code below demonstrates the problem, which did not exist in MacOS 14.2.1 struct ContentView: View { @State var speed = CGFloat(1) var body: some View { HStack { let angle: [Double] = [0, 45, 80, 85, 90] ZStack { ForEach(0...4, id: \.self) { i in ZStack () { Rectangle() Slider(value: $speed, in: 0...10 ) } .frame(width: 100, height: 10) .rotationEffect(.degrees(angle[i])) .offset(x: CGFloat(i * 100) - 180) } } } .padding() .frame(width: 600, height: 200) } } #Preview { ContentView() }
Topic: UI Frameworks SubTopic: SwiftUI
6
1
915
Feb ’25
TextKit 2 calls NSTextLayoutFragment's draw method too often
The following is verbatim of a feedback report (FB19809442) I submitted, shared here as someone else might be interested to see it (I hate the fact that we can't see each other's feedbacks). On iOS 16, TextKit 2 calls NSTextLayoutFragment's draw(at:in:) method once for the first paragraph, but for every other paragraph, it calls it continuously on every scroll step in the UITextView. (The first paragraph is not cached; its draw is called again when it is about to be displayed again, but then it is again called only once per its lifecycle.) On iOS 17, the behavior is similar; the draw method gets called once for the 1st and 2nd paragraph, and for every other paragraph it again gets called continuously as a user scrolls a UITextView. On iOS 18 (and iOS 26 beta 4), TextKit 2 calls the layout fragment's draw(at:in:) on every scroll step in the UITextView, for all paragraphs. This results in terrible performance. TextKit 2 is promised to bring many performance benefits by utilizing the viewport - a new concept that represents the visible area of a text view, along with a small overscroll. However, having the draw method being constantly called almost negates all the performance benefits that viewport brings. Imagine what could happen if someone needs to add just a bit of logic to that draw method. FPS drops significantly and UX is terribly degraded. I tried optimizing this by only rendering those text line fragments which are in the viewport, by using NSTextViewportLayoutController.viewportBounds and converting NSTextLineFragment.typographicBounds to the viewport-relative coordinate space (i.e. the coordinate space of the UITextView itself). However, this patch only works on iOS 18 where the draw method is called too many times, as the viewport changes. (I may have some other problems in my implementation, but I gave up on improving those, as this can't work reliably on all OS versions since the underlying framework isn't calling the method consistently.) Is this expected? What are our options for improving performance in these areas?
6
0
211
Aug ’25
Should SwiftUI view models in Swift 6 be both @Observable and @MainActor?
Hi, In the WWDC25 session Elevate an app with Swift concurrency (timestamps: 8:04 and later), the StickerViewModel is shown annotated with @Observable but not @MainActor. The narration mentions that updates happen on the main thread, but that guarantee is left implicit in the calling code. In Swift 6, though, one of the major benefits is stronger compiler enforcement against data races and isolation rules. If a view model were also annotated with @MainActor, then the compiler could enforce that observable state is only updated on the main actor, preventing accidental background mutations or updates that can cause data races between nonisolated and main actor-isolated uses. Since @Observable already signals that state changes are intended to be observed (and in practice, usually by views), it seems natural that such types should also be main-actor isolated. Otherwise, we’re left with an implicit expectation that updates will always come from the main thread, but without the compiler’s help in enforcing that rule. This also ties into the concept of local reasoning that was emphasized in other Swift 6 talks (e.g. Beyond the basics of structured concurrency). With @MainActor, I can look at a view model and immediately know that all of its state is main-actor isolated. With only @Observable, that guarantee is left out, which feels like it weakens the clarity that Swift 6 is trying to promote. Would it be considered a best practice in Swift 6 to use both @Observable and @MainActor for UI-facing view models? Or is the intention that SwiftUI developers should rely on calling context to ensure main-thread updates, even if that means the compiler cannot enforce isolation? Thanks!
6
0
282
Aug ’25
Swift Charts: How to prevent scroll position jump when loading more data dynamically
I'm implementing infinite scrolling with Swift Charts where additional historical data loads when scrolling near the beginning of the dataset. However, when new data is loaded, the chart's scroll position jumps unexpectedly. Current behavior: Initially loads 10 data points, displaying the latest 5 When scrolling backwards with only 3 points remaining off-screen, triggers loading of 10 more historical points After loading, the scroll position jumps to the 3rd position of the new dataset instead of maintaining the current view Expected behavior: Scroll position should remain stable when new data is loaded User's current view should not change during data loading Here's my implementation logic using some mock data: import SwiftUI import Charts struct DataPoint: Identifiable { let id = UUID() let date: Date let value: Double } class ChartViewModel: ObservableObject { @Published var dataPoints: [DataPoint] = [] private var isLoading = false init() { loadMoreData() } func loadMoreData() { guard !isLoading else { return } isLoading = true let newData = self.generateDataPoints( endDate: self.dataPoints.first?.date ?? Date(), count: 10 ) self.dataPoints.insert(contentsOf: newData, at: 0) self.isLoading = false print("\(dataPoints.count) data points.") } private func generateDataPoints(endDate: Date, count: Int) -> [DataPoint] { var points: [DataPoint] = [] let calendar = Calendar.current for i in 0..<count { let date = calendar.date( byAdding: .day, value: -i, to: endDate ) ?? endDate let value = Double.random(in: 0...100) points.append(DataPoint(date: date, value: value)) } return points.sorted { $0.date < $1.date } } } struct ScrollableChart: View { @StateObject private var viewModel = ChartViewModel() @State private var scrollPosition: Date @State private var scrollDebounceTask: Task<Void, Never>? init() { self.scrollPosition = .now.addingTimeInterval(-4*24*3600) } var body: some View { Chart(viewModel.dataPoints) { point in BarMark( x: .value("Time", point.date, unit: .day), y: .value("Value", point.value) ) } .chartScrollableAxes(.horizontal) .chartXVisibleDomain(length: 5 * 24 * 3600) .chartScrollPosition(x: $scrollPosition) .chartXScale(domain: .automatic(includesZero: false)) .frame(height: 300) .onChange(of: scrollPosition) { oldPosition, newPosition in scrollDebounceTask?.cancel() scrollDebounceTask = Task { try? await Task.sleep(for: .milliseconds(300)) if !Task.isCancelled { checkAndLoadMoreData(currentPosition: newPosition) } } } } private func checkAndLoadMoreData(currentPosition: Date?) { guard let currentPosition, let earliestDataPoint = viewModel.dataPoints.first?.date else { return } let timeInterval = currentPosition.timeIntervalSince(earliestDataPoint) if timeInterval <= 3 * 24 * 3600 { viewModel.loadMoreData() } } } I attempted to compensate for this jump by adding: scrollPosition = scrollPosition.addingTimeInterval(10 * 24 * 3600) after viewModel.loadMoreData(). However, this caused the chart to jump in the opposite direction by 10 days, rather than maintaining the current position. What's the problem with my code and how to fix it?
6
0
538
Jun ’25
A specific image fails to load using UIImageView on iOS 16, but loads normally on systems below iOS 16.
A specific image fails to load properly using UIImageView on iOS 16 and later systems, but loads normally on iOS 15 and earlier versions. Similarly, on Mac computers, this image cannot be opened on MacOS 13 and later, whereas it opens without issue on MacOS 12 and earlier. I am curious about the reasons behind this differing behavior on both iPhone and Mac.
6
0
486
Feb ’25
SwiftUI View cannot conform custom Equatable protocol in Swift 6.
In Swift 6, stricter concurrency rules can lead to challenges when making SwiftUI views conform to Equatable. Specifically, the == operator required for Equatable must be nonisolated, which means it cannot access @MainActor-isolated properties. This creates an error when trying to compare views with such properties: Error Example: struct MyView: View, Equatable { let title: String let count: Int static func ==(lhs: MyView, rhs: MyView) -> Bool { // Accessing `title` here would trigger an error due to actor isolation. return lhs.count == rhs.count } var body: some View { Text(title) } } Error Message: Main actor-isolated operator function '==' cannot be used to satisfy nonisolated protocol requirement; this is an error in the Swift 6 language mode. Any suggestions? Thanks FB: FB15753655 (SwiftUI View cannot conform custom Equatable protocol in Swift 6.)
6
0
978
Mar ’25
Issue with .itemProvider on macOS 15.1
I have a List with draggable items. According to this thread (https://developer.apple.com/forums/thread/664469) I had to use .itemProvider instead of .onDrag, because otherwise the selection of the list will not work anymore. The items in my list refer to a file URL. So the dragging allowed to copy the files to the destination of the drag & drop. Therefore I used this code .itemProvider { let url = ....... // get the url with an internal function return NSItemProvider(object: url as NSURL) } Since the update to macOS 15.1 this way isn't working anymore. It just happens nothing. I also tried to use .itemProvider { let url = .... return NSItemProvider(contentsOf: url) ?? NSItemProvider(object: url as NSURL) } but this doesn't work too. The same way with .onDrag works btw. .onDrag { let url = ....... // get the url with an internal function return NSItemProvider(object: url as NSURL) } but as I wrote, this will break the possibility to select or to use the primaryAction of the .contextMenu. Is this a bug? Or is my approach wrong and is there an alternative?
6
0
486
Feb ’25
UIDocumentPickerViewController does not allow picking folders on connected servers on iOS26
Hey there, I have an app that allows picking any folder via UIDocumentPickerViewController. Up until iOS18 users were able to pick folders from connected servers (servers connected in the Files app) as well. On iOS26, the picker allows for browsing into the connected servers, but the Select button is greyed out and does nothing when tapped. Is this a known issue? This breaks the whole premise of my file syncronization application.
6
0
237
Nov ’25
NSRulerView's background color and transparency (macOS 26)
When I compiled my legacy project with Tahoe's macOS 26 SDK, NSRulerViews are showing a very different design: Under prior macOS versions the horizontal and verrical ruler's background were blurring the content view, which was extending under the rulers, showing through their transparency. With Tahoe the horizontal ruler is always reflecting the scrollview's background color, showing the blurred content view beneath. And the vertical ruler is always completely transparent (without any blurring), showing the content together with the ruler's markers and ticks. It's difficult to describe, I'll try to replicate this behavior with a minimal test project, and probably file a bug report / enhancement request. But before I take next steps, can anyone confirm this observation? Maybe it is an intentional design decision by Apple?
6
0
300
Nov ’25
iOS 26 regression: Slider does not respect step parameter
In iOS 26, the Slider control no longer respects the step parameter. For example, import SwiftUI struct ContentView: View { @State private var sliderValue: CGFloat = 16 var body: some View { Slider( value: $sliderValue, in: 0...100, step: 5, onEditingChanged: { editing in print(sliderValue) } ) } } In iOS 18, this prints values like 5, 35, 60, 95, etc. In iOS 26.0 (release version), this prints floats that are not rounded to the nearest 5, and the slider does not snap to values ending in 5. Feedback report number: FB20320542
Topic: UI Frameworks SubTopic: SwiftUI
6
4
315
Nov ’25
In SwiftUI in iOS 18.1, `SectionedFetchRequest` is not refreshed when changes are done to the fetched entity's attributes.
Hi, This issue started with iOS 18, in iOS 17 it worked correctly. I think there was a change in SectionedFetchRequest so maybe I missed it but it did work in iOS 17. I have a List that uses SectionedFetchRequest to show entries from CoreData. The setup is like this: struct ManageBooksView: View { @SectionedFetchRequest<Int16, MyBooks>( sectionIdentifier: \.groupType, sortDescriptors: [SortDescriptor(\.groupType), SortDescriptor(\.name)] ) private var books: SectionedFetchResults<Int16, MyBooks> var body: some View { NavigationStack { List { ForEach(books) { section in Section(header: Text(section.id)) { ForEach(section) { book in NavigationLink { EditView(book: book) } label: { Text(book.name) } } } } } .listStyle(.insetGrouped) } } } struct EditView: View { private var book: MyBooks init(book: MyBooks) { print("Init hit") self.book = book } } Test 1: So now when I change name of the Book entity inside the EditView and do save on the view context and go back, the custom EditView is correctly hit again. Test 2: If I do the same changes on a different attribute of the Book entity the custom init of EditView is not hit and it is stuck with the initial result from SectionedFetchResults. I also noticed that if I remove SortDescriptor(\.name) from the sortDescriptors and do Test 1, it not longer works even for name, so it looks like the only "observed" change is on the attributes inside sortDescriptors. Any suggestions will be helpful, thank you.
6
0
1.4k
Jan ’25
On iPadOS 26 beta, the navigation bar can appear inset underneath the status bar (FB18241928)
On iPadOS 26 beta, the navigation bar can appear inset underneath the status bar (FB18241928) This bug does not happen on iOS 18. This bug occurs when a full screen modal view controller without a status bar is presented, the device orientation changes, and then the full screen modal view controller is dismissed. This bug appears to happen only on iPad, and not on iPhone. This bug happens both in the simulator and on the device. Thank you for investigating this issue.
6
0
426
Aug ’25
SwiftUi Picker in WatchOS throws Scrollview Error when using Digital Crown
The following WatchOs App example is very short, but already not functioning as it is expected, when using Digital Crown (full code): import SwiftUI struct ContentView: View { let array = ["One","Two","Three","Four"] @State var selection = "One" var body: some View { Picker("Array", selection: $selection) { ForEach(array, id: \.self) { Text($0) } } } } The following 2 errors are thrown, when using Digital Crown for scrolling: ScrollView contentOffset binding has been read; this will cause grossly inefficient view performance as the ScrollView's content will be updated whenever its contentOffset changes. Read the contentOffset binding in a view that is not parented between the creator of the binding and the ScrollView to avoid this. Error: Error Domain=NSOSStatusErrorDomain Code=-536870187 "(null)" Any help appreciated. Thanks a lot.
6
5
1.2k
Mar ’25
SwiftUI @State Updates Not Reflecting in UI Until View Reconstruction (Xcode Preview & Device)
Issue Description I'm experiencing a bizarre SwiftUI state update issue that only occurs in Xcode development environment (both Canvas preview and device debugging), but does not occur in production builds downloaded from App Store. Symptom: User taps a button that modifies a @State variable inside a .sheet Console logs confirm the state HAS changed But the UI does not update to reflect the new state Switching to another file in Xcode and back to ContentView instantly fixes the issue The production build (same code) works perfectly fine Environment Xcode: 16F6 (17C52) iOS: 26.2 (testing on iPhone 13) macOS: 25.1.0 (Sequoia) SwiftUI Target: iOS 15.6+ Issue: Present in both Xcode Canvas and on-device debugging Production: Same code works correctly in App Store build (version 1.3.2) Code Structure Parent View (ContentView.swift) struct ContentView: View { @State private var selectedSound: SoundTheme = .none @State private var showSoundSheet = false var body: some View { VStack { // Display button shows current selection SettingButton( title: "Background Sound", value: getLocalizedSoundName(selectedSound) // ← Not updating ) { showSoundSheet = true } } .sheet(isPresented: $showSoundSheet) { soundSelectionView } } private var soundSelectionView: some View { ForEach(SoundTheme.allCases) { sound in Button { selectedSound = sound // ← State DOES change (confirmed in console) // Audio starts playing correctly audioManager.startAmbientSound(sound) } label: { Text(sound.name) } } } private func getLocalizedSoundName(_ sound: SoundTheme) -> String { // Returns localized name return sound.localizedName }} What I've Tried Attempt 1: Adding .id() modifier SettingButton(...) .id(selectedSound) // Force re-render when state changes Result: No effect Attempt 2: Moving state modification outside withAnimation // Before (had animation wrapper):withAnimation { selectedSound = sound}// After (removed animation):selectedSound = sound Result: No effect Attempt 3: Adding debug print() statements selectedSound = soundprint("State changed: (selectedSound)") // ← Adding this line FIXES the issue! Result: Mysteriously fixes the issue! But removing print() breaks it again. This suggests a timing/synchronization issue in Xcode's preview system. Observations What works: ✅ Console logs confirm state changes correctly ✅ Switching files in Xcode triggers view reconstruction → everything works ✅ Production build from App Store works perfectly ✅ Adding print() statements "fixes" it (likely changes execution timing) What doesn't work: ❌ Initial file load in Xcode ❌ Hot reload / incremental updates ❌ Both Canvas preview and on-device debugging Workaround that works: Click another file in Xcode Click back to ContentView.swift Everything works normally Key Question Is this a known issue with Xcode 16's SwiftUI preview/hot reload system? The fact that: Same exact code works in production Adding print() "fixes" it File switching triggers reconstruction that fixes it ...all suggest this is an Xcode tooling issue, not a code bug. However, it makes development extremely difficult as I can't reliably test changes without constantly switching files or killing the app. What I'm Looking For Confirmation: Is this a known Xcode 16 issue? Workaround: Any better solution than constantly switching files? Root cause: What's causing this state update timing issue? Any insights would be greatly appreciated!
Topic: UI Frameworks SubTopic: SwiftUI
6
0
336
6d
NavigationSplitView not fully supported on smaller (SE) iPhones
My SwiftUI code runs fine on macOS, iOS(iPad) and larger iPhones, but will not display the detail view on smaller iPhones. Is there a way to force the smaller iPhones to display the detail view? And if not, When I put the App on the Apple store, for sale, will the Apple store be smart enough to flag the App as not appropriate for smaller iPhones, such as the SE (2nd and 3rd gen.) and prevent downloads? Thanks in advance for any guidance.
6
0
1.1k
Jul ’25