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

Scrolling to a `Section` cuts off header
Hello I was wondering if this is expected behavior or if there is a way I can fix this to get the behavior I am expecting. I have a Form that has many sections in it and when the content of the section is selected I would like that section to be scrolled to the top to make it easier for the user to know that they selected that section. But when the Section is selected, it is anchored to the top of the form but the header of the Section is cut off. When the Section is anchored to the top I would like the whole section to be seen (the header, content, and footer). I also tried applying an ID to the section and using that to scroll to and that also didn't work. Any help would be appreciated. Here is some code to repo this: struct ContentView: View { @State private var selectionSectionContent: SectionContent? var body: some View { ScrollViewReader { proxy in Form { ForEach(contents, id: \.self) { content in Section { Text(content.text) .onTapGesture { selectionSectionContent = content } } header: { Text("Header") } footer: { Text("Footer") } } } .onChange(of: selectionSectionContent) { _, newValue in if let newValue { // When text is tapped, scroll that section to the top. withAnimation { proxy.scrollTo(newValue, anchor: .top) } } } .padding() } } let contents: [SectionContent] = [ SectionContent(), SectionContent(), SectionContent(), SectionContent(), SectionContent(), SectionContent(), SectionContent(), SectionContent(), SectionContent(), SectionContent(), SectionContent(), SectionContent(), SectionContent(), SectionContent(), SectionContent() ] } class SectionContent: Hashable { let text = "Fun Section" public var id: ObjectIdentifier { ObjectIdentifier(self) } static func == (lhs: SectionContent, rhs: SectionContent) -> Bool { lhs.id == rhs.id } func hash(into hasher: inout Hasher) { hasher.combine(id) } } Here is a GIF of the header getting cut off when it is pinned to the top.
1
2
386
Jan ’25
Scroll to bottom after reload row issue
Im creating a chat using uiTableView. The response is send as streaming so I need to reload last cell até every response update. However when I do reload row and scroll to bottom, the content of the last cell seems to be drag to the bottom instead of looking as a regular scroll.
Topic: UI Frameworks SubTopic: UIKit Tags:
3
0
290
Jan ’25
Unable to Use DeviceActivityReport to Show Screen Time in App
Hi team. I am working on an app that uses the Screen Time API. I got access to the family controls (distribution) capability through the request process for my main app. I added a DeviceActivityReport extension in XCode, but haven't been able to get the extension to show up on the screen. I noticed that the extension only has the development version of the family controls capability available. Is this the source of my errors? I was able to get the screen time displayed in a test app I built where both the main app and extension used the development version of the capability, which led me to believe that discrepancy could be the issue. Let me know if there is anything I can provide to help in the debugging process. I didn't send a minimal example in this request due to the fact that I would have to remove most of my functionality to create a "minimal" example (since the signing is only for my main app), but I can do that if needed. Thanks! I looked through the logs in the console for the phone (I'm testing on a real iPhone 13 Pro Max), but didn't see anything that popped out after looking (not exactly sure what to look for though). STEPS TO REPRODUCE: Create an app with the Family Controls, Distribution capability. Then create the DeviceActivityReport with the Family Control, Development capability. Attempt to see the DeviceActivityReport in the main app. NOTE: I was successfully able to create a minimal test app completely separately that used the Development versions of the capabilities for both with the exact same extension code. That's why I think the issue could be due to the capability version discrepancy.
5
0
408
Jan ’25
Cannot mimic fullscreen behavior when using custom event loop
Hi, we are developing a cross-platform library for creating desktop applications in C++: https://github.com/aseprite/laf For this reason, in macOS, we cannot rely on the default NSApplication.run() event loop, so we decided to implement our custom event loop using the nextEventMatchingMask method. Then, when a window is in fullscreen mode, for some reason the window stops receiving mouseMove events when the mouse pointer enters an area at the top of the window. You can see this issue in action by trying the following example project: https://github.com/martincapello/custom-event-loop-issue This project just opens one window and uses a custom event loop, it displays the current mouse position at every mouseMove event received, and when the aforementioned area is entered it suddenly stops updating. There is also a video showing how to reproduce it. I was able to see that when the position stops updating, we still receive mouseMove events, but for a different window, a borderless window that is added to the NSApplication.windows collection when switching to fullscreen, and which seems to be taken the mouseMove events before reaching the main window. Also, this issue doesn't happen when using the default NSApplication.run method, despite the borderless windows being added as well.
8
0
647
Jan ’25
Widget AppIntent perform network request
I had write a widget after iOS 17+, It had a Toggle to perform a appintent . When switch the toggle, the appintent will perfrom , just like ` func perfrom() async throws -> some IntentResult { // first let first = try await getFristValue() let second = try await getSecondValue(by: first) let third = try awiat getThirdValue(by: second) return .result() } ` and I found, it will work when I am debugging connect with Xcode. But, when I don't connect xcode, it will not work. How can I fixed it ?
4
1
442
Jan ’25
Magnification Gesture conflicts with UIPageViewController scroll gesture
The Problem I am trying to implement a pinch-to-zoom feature on images within a UIPageViewController. However, often times when trying to pinch to zoom, the magnification gesture gets overridden by the scrolling gesture built into the UIPageViewController. I'm not sure how to get around this. The Apple Photos app seems to allow pinch to zoom on photos inside a full-page scrolling view without any issue, so I believe it should be possible. Versions: iOS 17.2.1 - iOS 18.2.1, Swift (SwiftUI), Xcode 15.1 Steps to Reproduce Run this sample Xcode project on a physical device: https://drive.google.com/file/d/1tB1QyY6QPEp-WLzdHxgDdkM45xCAELLr/view?usp=share_link Try pinching to zoom on the image. After a few goes at it, you'll likely find that one time it will scroll instead of pinching to zoom. It might take up to a dozen pinches to experience this issue. What I've Tried Making the magnification gesture a high priority gesture. Having only one page in the paging view controller. Subclassing UIScrollView and conforming to the UIGestureRecognizerDelegate in that subclass, as explained here: https://stackoverflow.com/a/51070947/12218938 Using the iOS 17 ScrollView instead. Unfortunately it has the same issue but even worse! It's possible that since this is a native SwiftUI view, people might have solutions to this, but from a brief search I couldn't find any. If you set the data source to nil (which indicates that there are no other pages for the paging view controller to scroll to), it does work, but it's not a workable solution since the time you'd want to set the data source to nil is when the user pinches the screen, but you can't know when the user pinches the screen if the gesture doesn't work! Other Ideas/Workarounds We could have some "zoom" mode that temporarily cancels the ability to scroll while zooming. But this seems like not too nice/intuitive of a solution. If there is no paging view that Apple provides which could be made compatible with a pinch-to-zoom gesture, it's possible we would have to make a completely custom paging view. But that would be a lot of work I presume, so it's probably not something we would have time for right now.
0
0
448
Jan ’25
macOS Menu Bar
Xcode 16.2 Swift 6 macOS Sequoia 15.1 SwiftUI I am a beginner. If I understand we can add buttons to the default Menu Bar but not delete them. Am I right? If you do not need most of the buttons, how do you solve that? I can add a button: import SwiftUI @main struct NouMenuProvesApp: App { var body: some Scene { WindowGroup { ContentView() } .commands { CommandMenu("Custom") { Button("Custom Action") { print("Custom Action performed") } } } } } Can I delete a Menu Button or create a new simpler Menu Bar?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
1
0
306
Jan ’25
WidgetKit widgets vanish in Montery with Xcode 16
We have recently added WidgetKit widgets to an existing product, and they've been working great on Macs using Big Sur and later. Recently, when installing a build on a Montery Mac, the widgets were no longer in Notification Center. After some trial and error, we discovered that if we build the project with Xcode 15.4, the widgets appear, but if we build with Xcode 16, the widgets vanish. This seems to happen on Macs running Big Sur or Monterey. The project is being built on Macs running Sonoma (both Apple Silicon and Intel). Is there a build setting in Xcode 16 that may have this effect?
3
1
467
Jan ’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
Open an specific view or sheet of the app from a control widget button
Hi everyone. I'm trying to use the new ControlWidget API introduced on iOS 18 to open a sheet that contains a form when the user taps on the button on the control center. This is my current code. It opens the app, but I haven't found how to do an action inside the app when the app is opened. @available(iOS 18, *) struct AddButtonWidgetControl: ControlWidget { var body: some ControlWidgetConfiguration { StaticControlConfiguration(kind: "com.example.myapp.ButtonWidget") { ControlWidgetButton(action: LaunchAppIntent()) { Label("Add a link", systemImage: "plus") } } .displayName("Add a link") .description("Creates a link.") } } @available(iOS 18, *) struct LaunchAppIntent: AppIntent { static var title: LocalizedStringResource { "Launch app" } static var openAppWhenRun: Bool = true func perform() async throws -> some IntentResult { return .result() } }
2
0
679
Jan ’25
TextKit 2 Background drawing incorrect
Hi I am drawing TextKit2 managed NSAttributedStrings into a NSBitmapImageRep successfully, enumerating the Text Layout Fragments is giving me bogus background drawing This is the core drawing code, its pretty simple: I manage the flipped property myself since NSTextLayoutManager assumes a flipped coordinate. if let context = NSGraphicsContext(bitmapImageRep: self.textImageRep!) { NSGraphicsContext.current = context let rect = NSRect(origin: .zero, size: self.outputSize) NSColor.clear.set() rect.fill() // Flip the context context.cgContext.saveGState() context.cgContext.translateBy(x: 0, y: self.outputSize.height) context.cgContext.scaleBy(x: 1.0, y: -1.0) let textOrigin = CGPoint(x: 0.0, y: 0.0 ) let titleRect = CGRect(origin: textOrigin, size: self.themeTextContainer.size) NSColor.orange.withAlphaComponent(1).set() titleRect.fill() self.layoutManager.enumerateTextLayoutFragments(from: nil, using: { textLayoutFragment in // Get the fragment's rendering bounds let fragmentBounds = textLayoutFragment.layoutFragmentFrame print("fragmentBounds: \(fragmentBounds)") // Render the fragment into the context textLayoutFragment.draw(at: fragmentBounds.origin, in: context.cgContext) return true }) context.cgContext.restoreGState() } NSGraphicsContext.restoreGraphicsState() I have a mutable string which has various paragraph styles which I add to the layout manager / text storage like so let titleParagraphStyle = NSMutableParagraphStyle() titleParagraphStyle.alignment = .center titleParagraphStyle.lineBreakMode = .byWordWrapping titleParagraphStyle.lineBreakStrategy = .standard var range = NSMakeRange(0, self.attributedProgrammingBlockTitle.length) self.attributedProgrammingBlockTitle.addAttribute(.foregroundColor, value: NSColor(red: 243.0/255.0, green: 97.0/255.0, blue: 97.0/255.0, alpha: 1.0), range:range) self.attributedProgrammingBlockTitle.addAttribute(.backgroundColor, value: NSColor.cyan, range:range) self.attributedProgrammingBlockTitle.addAttribute(.font, value: NSFont.systemFont(ofSize: 64), range:range) self.attributedProgrammingBlockTitle.addAttribute(.paragraphStyle, value:titleParagraphStyle, range:range) range = NSMakeRange(0, self.attributedThemeTitle.length) self.attributedThemeTitle.addAttribute(.foregroundColor, value: NSColor.white, range:range ) self.attributedThemeTitle.addAttribute(.backgroundColor, value: NSColor.purple, range:range) self.attributedThemeTitle.addAttribute(.font, value: NSFont.systemFont(ofSize: 48), range:range) self.attributedThemeTitle.addAttribute(.paragraphStyle, value:NSParagraphStyle.default, range:range) range = NSMakeRange(0, self.attributedText.length) self.attributedText.addAttribute(.foregroundColor, value: NSColor.white, range:range ) self.attributedText.addAttribute(.backgroundColor, value: NSColor.yellow, range:range) self.attributedText.addAttribute(.font, value: NSFont.systemFont(ofSize: 36), range:range) self.attributedText.addAttribute(.paragraphStyle, value:NSParagraphStyle.default, range:range) let allText = NSMutableAttributedString() allText.append(self.attributedProgrammingBlockTitle) allText.append(NSAttributedString(string: "\n\r")) allText.append(self.attributedThemeTitle) allText.append(NSAttributedString(string: "\n\r")) allText.append(self.attributedText) self.textStorage.textStorage?.beginEditing() self.textStorage.textStorage?.setAttributedString(allText) self.textStorage.textStorage?.endEditing() self.layoutManager.ensureLayout(for: self.layoutManager.documentRange) however, i get incorrect drawing for the background color font attributes. Its origin is zero, and not correctly aligned at all with the text. How can I get correct rendering of backgrounds from TextKit2? Here is an image of my output:
3
0
971
Jan ’25
No insert animation after `insert` when using SwiftData.
Hi, After running the Xcode template "New project > (SwiftUI, SwiftData)" I noticed that there is no insert animation into the list. The project is a pure vanilla project created from Xcode (Version 16.2 (16C5032a)) and the code is a simple as it gets: // // ContentView.swift // import SwiftUI import SwiftData struct ContentView: View { @Environment(\.modelContext) private var modelContext @Query private var items: [Item] var body: some View { NavigationSplitView { List { ForEach(items) { item in NavigationLink { Text("Item at \(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))") } label: { Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard)) } } .onDelete(perform: deleteItems) } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { EditButton() } ToolbarItem { Button(action: addItem) { Label("Add Item", systemImage: "plus") } } } } detail: { Text("Select an item") } } private func addItem() { withAnimation { let newItem = Item(timestamp: Date()) modelContext.insert(newItem) } } private func deleteItems(offsets: IndexSet) { withAnimation { for index in offsets { modelContext.delete(items[index]) } } } } #Preview { ContentView() .modelContainer(for: Item.self, inMemory: true) } As you see the template's code does have withAnimation inside addItem but there is no animation. The new added item appears without animation in the the List Here is a short video. Is this a known bug?
4
0
873
Jan ’25
iOS 18: “Settings” button on location permission alert does nothing, logs BUG IN CLIENT OF UIKIT warning
Hello everyone, I’m encountering a problem on the latest iOS 18 related to location permissions. When the user denies location access, my app triggers the standard system prompt asking them to enable location from Settings. On iOS 17 and below, tapping the “Settings” button in this system alert would successfully navigate the user to my app’s Settings page. However, on iOS 18, nothing happens. Instead, I see the following warning in the Xcode console: Warning : BUG IN CLIENT OF UIKIT: The caller of UIApplication.openURL(:) needs to migrate to the non-deprecated UIApplication.open(:options:completionHandler:). Force returning false (NO). Important details and context: In my own code, I have already replaced all calls to openURL(:) with open(:options:completionHandler:). I searched the entire codebase for usage of openURL: and didn’t find any. The alert that appears is the system location alert (iOS-generated), not a custom UIAlertController. Thus, I have no direct control over the underlying call. On iOS 17 (and below), tapping “Settings” in the same system dialog works perfectly and takes the user to the app’s permission page. The console message implies that somewhere—likely inside the system’s own flow—the deprecated API is being called and blocked on iOS 18. What I’ve tried: Verified I am not calling openURL: anywhere in my code. Confirmed that UIApplication.openSettingsURLString works when I programmatically open it in a custom alert. Tested multiple times on iOS 17 and iOS 18 to confirm the behavior difference. Steps to reproduce: Install the app on a device running iOS 18 Beta. Deny location permission when prompted. Trigger a piece of code that relies on location (e.g., loading a map screen) so that the OS automatically shows its standard “Location is disabled” alert, which includes a “Settings” button. Tap “Settings.” On iOS 17, this navigates to the app’s Settings. On iOS 18 Beta, it does nothing, and the console logs the BUG IN CLIENT OF UIKIT warning. Questions: Is this a known iOS 18 bug where the system’s own alert is still using the deprecated openURL: call? If so, are there any workarounds besides presenting a custom alert that manually calls open(_:options:completionHandler:)? Thank you in advance. Any guidance or confirmation would be appreciated!
1
1
1k
Jan ’25
Cannot preview in this file, failed to launch
I am not able to use SwiftUI Preview Here is the report I get while trying to see the issue: Here is the report of the issue: And here is the call and code preview: import SwiftUI struct ContentView: View { var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") } .padding() } } #Preview { ContentView() } Please update.
2
0
855
Jan ’25
SwiftUI TabVIew Faulting while switching between Tabs
I'm working on a SwiftUI based application for MacOS. I have a TabView component with two child Tab components. These Tab components display a List, each derived from an array of elements. While the application is running, clicking on the tabs in the TabView should switch between the views of different Lists. What I'm experiencing is that switching between the tabs causes a FAULT. With errors: Row index 1 out of row range (numberOfRows: 1) for <SwiftUI.SwiftUIOutlineListView: 0x1299d2000> Followed by: ( 0 CoreFoundation 0x000000019e096e80 __exceptionPreprocess + 176 1 libobjc.A.dylib 0x000000019db7ecd8 objc_exception_throw + 88 2 AppKit 0x00000001a1c744e8 -[NSTableRowData _availableRowViewWhileUpdatingAtRow:] + 0 3 SwiftUI 0x00000001cd8953f4 $s7SwiftUI0A17UIOutlineListViewC11removeItems2at8inParent13withAnimationy10Foundation8IndexSetV_ypSgSo07NSTableeL7OptionsVtF + 1232 ... ... ) And finally: FAULT: NSTableViewException: Row index 1 out of row range (numberOfRows: 1) for <SwiftUI.SwiftUIOutlineListView: 0x1299d2000>; (user info absent) This error happens when switching between the two tabs, defined thusly: @main struct MyApp: App { @State var rootDirectory: URL @State var selectedItem: URL @State var projectNavItems: [NavigationItem] = [] @State var jotNavItems: [NavigationItem] = [] @State var importerIsPresented: Bool = false let fileManager = FileManager.default init() { rootDirectory = URL(string: FileManager.default.currentDirectoryPath)! selectedItem = URL(string: FileManager.default.currentDirectoryPath)!.appendingPathComponent("README.md") } var body: some Scene { WindowGroup { NavigationSplitView { TabView { Tab("Projects", systemImage: "tray.and.arrow.down.fill") { List(projectNavItems, selection: $selectedItem) { // Changing this NavigationLink line to Text($0.title) makes no difference NavigationLink($0.title, value: $0.id) } } Tab("Jots", systemImage: "tray.and.arrow.up.fill") { List(jotNavItems, selection: $selectedJot) { // Can be written as Text($0.title) with no change in behavior NavigationLink($0.title, value: $0.id) } } } } detail: { Editor(for: selectedItem) } .fileImporter( isPresented: $importerIsPresented, allowedContentTypes: [UTType.folder], allowsMultipleSelection: false ) { result in // Code that gets a security scoped resource and populates the // projectNavItems: [NavItem] and jotNavItems: [NavItem] // arrays } } .commands(content: { CommandGroup (before: .newItem) { Button("Open Journal...") { importerIsPresented.toggle() } } }) } } The error only happens when both Tab views are populated by a List. If the Tab view have different child components, say a List, and a ForEach of Text components, switching between the tabs doesn't produce this error. List views with Text child components also produce this error. Here are screenshots of the running application Once the user selects a directory, we see the first Tab > List component populated by contents from the projectNavItems array: Clicking on the 'Jots' tab switches to the appropriate tab and correctly lists the items in the jotNavItems array, except there are additional lines, seemingly showing that there's an issue. Clicking back on the 'Projects' tab switches back, but now the List shows only one of the items from the projectNavItems array. Finally, clicking on 'Jots' again causes the errors to print in the console and interactivity with the tab components ceases. Last screenshot is representative of this state as the application FAULTS. This seems like a bug in SwifUI, wondering what workarounds I might be able to implement. I can provide the full backtrace, I cropped it for content length.
2
0
460
Jan ’25
Swift UI , Buttons change appearance when pressed.
I have a calculator app with lots of buttons. Some of the buttons change appearance when pressed. Others do not. Some of those that do not change the state of a display text field and others do not. The display change is that the button goes white when pressed. I have no explicit code to make a change in appearance in any of the buttons. The display consists of a TextField followed by 4 rows of 6 buttons followed by 4 rows of 6 buttons. What is the explanation for this behavior.
Topic: UI Frameworks SubTopic: SwiftUI
2
0
209
Jan ’25