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

NSTextView and TextField becomes non clickable after a alert/menu is shown
I have a NSViewController as the root view and have a switui view embedded in it via NSHostingView. override func loadView() { self.view = NSHostingView(rootView: SwiftUiView()) } } In the SwiftUiView, I have a TextField and an NSTextView embedded using NSViewRepresentable, along with a few buttons. There is also a menu: Menu { ForEach(menuItems), id: \.self) { item in Button { buttonClicked() } label: { Text(item) } } } label: { Image("DropDown") .contentShape(Rectangle()) .frame(maxWidth: .infinity) .frame(maxHeight: .infinity) } The NSTextView and TextField work fine, and I can type in them until I click on the menu or show an alert. After that, I can no longer place my cursor in the text fields. I am able to select the text but not type in it. When I click on the NSTextView or TextField, nothing happens. At first, I thought it was just a cursor visibility issue and tried typing, but I received an alert sound. I've been trying to fix this for a couple of days and haven't found any related posts. Any help would be greatly appreciated.
1
0
267
Mar ’25
Entire view re-renders when updating dictionary
I'm trying to create a form which reads and writes data to a dictionary. when I type something in a field whole form seems to update. Is there anyway to only update the field I'm typing? Android compose have something called SnapshotStateMap which allows smart re-rendering.
Topic: UI Frameworks SubTopic: SwiftUI
1
0
120
Mar ’25
Setting launch screen image through info.plist - image stretches to cover full screen
I am developing an app in swiftUI using Xcode 12.3, deployment target iOS 14.0. The launch screen is setup through info.plist by specifying 'background color' and 'image name'. The file used in 'image name' is from Assets catalog. (PNG format, size300 x 300 and corresponding @2x and @3x resolutions) What I have observed, when the app is installed for the first time the launch image is centered and have original resolutions but all subsequent launches show launch images stretched to cover full screen. Any ideas why this is happening and how to have more consistent behavior either way? I have tried 'respect safe area' option but it does not make a difference. Thank you.
12
2
14k
Mar ’25
Crash on removal of QLPreviewController and _EXRemoteViewController
I have a controller that displays a pdf using UIDocumentInteractionController as the presented view. When users open it up, it shows fine. User gets the app backgrounded and session timed out. After timed out, when the app is brought to foreground, I bring our loginVC by removing the old VC used to show the UIDocumentInteractionController. All the crashes are happening at this point. I am not able to reproduce it, but our alert systems show we have crashes happening. The code that shows the pdf is straight forward documentViewController = UIDocumentInteractionController() documentViewController?.delegate = self documentViewController?.url = url documentViewController?.presentPreview(animated: true) and we reset it to nil in delegate documentInteractionControllerDidEndPreview Based on the crash trace, it seems like the crash happens when our login VC replaces it and only when pdf was displayed. The reason of stressing ONLY because when we have other viewcontroller present and they are removed in a similar way, we do not see any issue. So we always replace first and then add a new one childViewController.willMove(toParent: nil) childViewController.viewIfLoaded?.removeFromSuperview() childViewController.removeFromParent() addChild(childViewController) view.addSubview(childViewController.view) childViewController.view.frame = view.bounds childViewController.didMove(toParent: self) Raised a ticket with Apple, but I haven't heard back, and it's been a month. Posting here in case anyone experiences the same and has any solutions. I saw some related posts, and solution was to remove the pdf the moment the app goes to the background, but I am trying to find some alternate solution if possible.
Topic: UI Frameworks SubTopic: UIKit
0
0
223
Mar ’25
Apple Intelligence + scrolling stuck
Hey, It seems that when Apple Intelligence is enabled, scrolling can become completely broken when using an app. This is affecting several apps, including telegram: https://github.com/TelegramMessenger/Telegram-iOS/issues/1570?reload=1 It seems that UIPanGesture is affected by this. (MapKit stop being able to scroll too). Killing + Relaunching the app fix the problem. Bug report ID, containing a video: FB16780431
2
1
215
Mar ’25
business
import SwiftUI struct Product: Identifiable { let id = UUID() let name: String let pricePerKg: Double } struct ContentView: View { @State private var selectedProduct: Product? @State private var quantity: Double = 1.0 @State private var orderDate = Date() @State private var showingConfirmation = false let products = [ Product(name: "Lamb", pricePerKg: 15.0), Product(name: "Beef", pricePerKg: 20.0), Product(name: "Chicken", pricePerKg: 10.0) ] var body: some View { NavigationView { Form { Section(header: Text("Select Meat")) { Picker("Meat Type", selection: $selectedProduct) { ForEach(products) { product in Text(product.name).tag(product as Product?) } } } if let selectedProduct = selectedProduct { Section(header: Text("Quantity (kg)")) { Stepper(value: $quantity, in: 0.5...10, step: 0.5) { Text("\(quantity, specifier: "%.1f") kg") } } Section(header: Text("Delivery Date")) { DatePicker("Select Date", selection: $orderDate, in: Date()..., displayedComponents: .date) } Section(header: Text("Total Price")) { Text("$\(selectedProduct.pricePerKg * quantity, specifier: "%.2f")") } Button("Confirm Order") { showingConfirmation = true } .alert(isPresented: $showingConfirmation) { Alert(title: Text("Order Confirmed"), message: Text("You have ordered \(quantity, specifier: "%.1f") kg of \(selectedProduct.name) for \(orderDate.formatted(date: .long, time: .omitted))."), dismissButton: .default(Text("OK"))) } } } .navigationTitle("Halal Butcher") } } } @main struct HalalButcherApp: App { var body: some Scene { WindowGroup { ContentView() } } }
2
0
218
Mar ’25
Can't find or decode availabilityDetailedInfo warning when start editing textField
Whenever I start editing TextField or while editing TextField, Xcode shows this worning, and takes a few seconds to show the keyboard. There is no 'availabilityDetailedInfo' in my source code, and I could not find similar errors on the internet. Can't find or decode availabilityDetailedInfo unavailableReasonsHelper: Failed to get or decode availabilityDetailedInfo Can't find or decode reasons unavailableReasonsHelper: Failed to get or decode unavailable reasons as well Can't find or decode availabilityDetailedInfo unavailableReasonsHelper: Failed to get or decode availabilityDetailedInfo Can't find or decode reasons unavailableReasonsHelper: Failed to get or decode unavailable reasons as well
14
29
8.3k
Mar ’25
How can I use specify the anchor used to display an item that a user scrolls to ?
I have a scrollview displaying a sequence of circles, which a user should be able to scroll through to select an item. When the user stops scrolling and the animation comes to rest the circle selected should display screen-centered. I had hoped to achieve this using .scrollPosition(id: selectedItem, anchor: .center) but it appears that the anchor argument is ignored when scrolled manually. (BTW - I searched but didn't locate this aspect in the Apple documentation so I'm not confident that this observation is really correct). https://youtu.be/TpXDTuL5yPQ The video shows the user-scrolling behaviour, and also the snap-to-anchor that I would like to achieve, but I would like this WITHOUT forcing a button press. I could juggle the container size and size of the circles so that they naturally fit centered into the screen, but I would prefer a more elegant solution. How can I force the scrolling to come to rest such that the circle glides to rest in the center of the screen/container? struct ItemChooser: View { @State var selectedItem: Int? var body: some View { VStack { Text("You have picked: \(selectedItem ?? 0)") ScrollHorizontalItemChooser(selectedItem: $selectedItem) } } } #Preview { ItemChooser(selectedItem: 1) } struct ScrollHorizontalItemChooser: View { @Binding var selectedItem: Int? @State var scrollAlignment: UnitPoint? = .center let ballSize: CGFloat = 150 let items = Array(1...6) @State var scrollPosition: ScrollPosition = ScrollPosition() var body: some View { VStack { squareUpButton ScrollView(.horizontal) { HStack(spacing: 10) { showBalls } .scrollTargetLayout() } .scrollPosition(id: $selectedItem, anchor: scrollAlignment ) .overlay{ crosshairs } } } var crosshairs: some View { Image(systemName: "scope").scaleEffect(3.0).opacity(0.3) } @ViewBuilder var showBalls: some View { let screenWidth: CGFloat = UIScreen.main.bounds.width var emptySpace: CGFloat {screenWidth / 2 - ballSize / 2 - 10} Spacer(minLength: emptySpace) ForEach(items, id: \.self) { item in poolBall( item) .id(item) } Spacer(minLength: emptySpace) } @ViewBuilder private func poolBall(_ item: Int) -> some View { Text("Item \(item)") .background { Circle() .foregroundColor(Color.green) .frame(width: ballSize, height: ballSize) } .frame(width: ballSize, height: ballSize) } @ViewBuilder var squareUpButton: some View { var tempSelected: Int? = nil Button("Square up with Anchor") { tempSelected = selectedItem selectedItem = 0 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { selectedItem = tempSelected ?? 0 } } } }
Topic: UI Frameworks SubTopic: SwiftUI
1
0
243
Mar ’25
Custom SwiftUI view with localization support similar to the SwiftUI Text view
I'd like to create a custom SwiftUI view that supports extracting its title string along with the localization comment into a string catalog. Like the SwiftUI Text view does. I have a view with an init similar to the localization init of Text. But it looks like I'm missing something obvious. Two questions: How do I get the actual localized string using a LocalizedStringKey? Why is the comment not picked up and added to the string catalog? // 1) My custom view with localization support: // I'd like to build a view which supports extraction of strings into a string catalog like the SwiftUI `Text` view does. struct MyLocalizableView: View { private var localizedTitle: String init (_ titleKey: LocalizedStringKey, table: String? = nil, bundle: Bundle? = nil, comment: StaticString? = nil) { // PROBLEM I: // The following line does not work. I is a fantasy call. It depicts my idea how I would expect it to work. // My question is: How do I get the actual localized string using a `LocalizedStringKey`? self.localizedTitle = String(localizedKey: titleKey, table: table, bundle: bundle, comment: comment) } var body: some View { // At this point I want to do an operation on an actual string and not on a LocalizedStringKey. So I can't just pass the LocalizedStringKey value along. // Do `isEmpty` or some other operation on an actual string: if localizedTitle.isEmpty { Text("Show one thing") } else { Text("Show another thing") Text("** \(localizedTitle) **") } } } // 2) The call site: struct ContentView: View { var body: some View { // PROBLEM II: "My title key" is picked up and is extracted into the string catalog of the app. But the comment is NOT! MyLocalizableView("My title key", comment: "The title of the view...") .padding() } }
1
0
326
Mar ’25
Selecting TextField Causes Application Hang on Device
I'm struggling with an elusive issue, where selecting a TextField, which then shows the onscreen keyboard, causes a later application hang, but only on an actual device (not in preview, not in the simulator). I've narrowed my code down to the simplest repro. If you run the following code, you can try both the repro case and a case that avoids the issue, where the only difference between the two is whether you select a TextField, which displays the onscreen keyboard. Even if you just dismiss the keyboard, the hang still happens. To repro, select the "Press Here To Show Keyboard To Cause Hang" TextField, then select the "Press Here Before Showing Keyboard To Not Hang" link, then follow through with Create New Group, Add Member, Create New Member. The app will hang when you select Create New Member. If you start with the "Press Here Before Showing Keyboard to Not Hang", everything works. You can even select the Group Name TextField before selecting Add Member without issue. I'm looking for any ideas or suggestions, thanks. Here's the code: import SwiftUI class Member : Identifiable { let id = UUID() var name = "" } class Group : Identifiable { let id = UUID() var name = "" var members = [Member]() var memberIds = [UUID]() } struct MemberView : View { @Environment(\.dismiss) private var dismiss @Binding private var groups: [Group] @Binding private var members: [Member] @State private var member: Member init(groups: Binding<[Group]>, members: Binding<[Member]>, member: Member? = nil) { _groups = groups _members = members _member = .init(wrappedValue: member ?? Member()) } var body: some View { Form { Section(header: Text("Member Data")) { TextField("Member Name", text: $member.name) } } } } struct MembersView : View { @Environment(\.dismiss) private var dismiss @Binding private var groups: [Group] @Binding private var members: [Member] init(groups: Binding<[Group]>, members: Binding<[Member]>) { _groups = groups _members = members } var body: some View { if members.isEmpty { NavigationLink("Create New Member") { MemberView(groups: $groups, members: $members) } } else { List(members) { member in Text(member.name) } } } } struct GroupView : View { @Binding private var groups: [Group] @Binding private var members: [Member] @State private var group = Group() @State private var selectedMemberId: UUID? init(groups: Binding<[Group]>, members: Binding<[Member]>) { _groups = groups _members = members } var body: some View { Form { Section(header: Text("Group Data")) { TextField("Group Name", text: $group.name) } Section(header: Text("Members")) { List(members) { member in if group.memberIds.contains(member.id) { NavigationLink { MemberView(groups: $groups, members: $members, member: member) } label: { Text(member.name) } } } NavigationLink { MembersView(groups: $groups, members: $members) } label: { Text("Add Member") } } } } } struct GroupsView : View { @Binding private var groups: [Group] @Binding private var members: [Member] init(groups: Binding<[Group]>, members: Binding<[Member]>) { _groups = groups _members = members } var body: some View { if groups.isEmpty { NavigationLink("Create New Group") { GroupView(groups: $groups, members: $members) } } else { List(groups) { group in Text(group.name) } } } } struct MainView : View { @State private var groups: [Group] @State private var members: [Member] @State private var settings: [String] @State private var setting = "" init() { _groups = .init(wrappedValue: []) _members = .init(wrappedValue: []) _settings = .init(wrappedValue: []) } var body: some View { NavigationStack { if settings.isEmpty { VStack { TextField("Press Here To Show Keyboard To Cause Hang (Whether Or Not You Type Anything)", text: $setting) { settings.append("Hang") } Button("Press Here Before Showing Keyboard To Not Hang") { settings.append("No Hang") } } } else { GroupsView(groups: $groups, members: $members) } } } } #Preview { MainView() } @main struct TestApp: App { var body: some Scene { WindowGroup { MainView() } } }
Topic: UI Frameworks SubTopic: SwiftUI
3
0
390
Mar ’25
How to replace default user location annotation with custom avatar in SwiftUI Map with selection parameter?
I'm implementing a Map with user location customization in SwiftUI using iOS 17+ MapKit APIs. When using the selection parameter with Map, the default blue dot user location becomes tappable but shows an empty annotation view. However, using UserAnnotation makes the location marker non-interactive. My code structure: import SwiftUI import MapKit struct UserAnnotationSample: View { @State private var position: MapCameraPosition = .userLocation(fallback: .automatic) @State private var selectedItem: MapSelection<MKMapItem>? var body: some View { Map(position: $position, selection: $selectedItem) { // UserAnnotation() } .mapControls { MapUserLocationButton() } } } Key questions: How can I replace the empty annotation view with a custom avatar when tapping the user location? Is there a way to make UserAnnotation interactive with selection? Should I use tag modifier for custom annotations? What's the proper way to associate selections?
0
0
330
Mar ’25
Can't find any realistic example of how to use NavigationPath
Like many applications, mine involves navigation where the user starts a process on one screen and then progresses through several more steps to reach a conclusion. When he confirms that choice, I need to dismiss the entire stack. In my case, he's browsing contacts, selecting one, and then selecting a communication method from those offered by the contact. This still appears to be a PITA in SwiftUI. NavigationPath is supposed to provide a way to programmatically control a stack of views. Well... I can't find a single example of how to use it for this, except with absurdly shallow (as in a single level) of child views that all take the same datatype. Nowhere do I see how to use the path as users proceed through your view hierarchy with NavigationLinks. I have not seen any example of how elements get added to the path or how they are related to each added view. Nor can I find an example of popping views off the stack by removing related elements from the path. I created a class that encloses a NavigationPath: @Observable class NavPathController { var path: NavigationPath init() { path = NavigationPath() } func popOne() { path.removeLast() } func popAll() { path.removeLast(path.count) } } In my root view, I pass a binding to this controller's NavigationPath when creating the NavigationStack: @State private var viewStack = NavPathController() var body: some View { NavigationStack(path: $viewStack.path) { VStack() { NavigationLink(destination: UserFindingView(viewPathController: viewStack), label: { Text("Pick a recipient") }) } } And likewise each view passes the same view-path controller object to each child view that's invoked with a NavigationLink (instead of using an environment variable, because I find those hokey). But in the end, the path is empty; not surprisingly, clearing it does not pop the views. So how is one supposed to make this work?
Topic: UI Frameworks SubTopic: SwiftUI
1
0
207
Mar ’25
Strange behavior when pushing UIViewController
This is a very strange behavior when pushing vc that I have never seen since I started coding. The pushed ViewController is transparent and only navBarTitle is shown. After the push, you can't control anything unless you go back to the home screen. STEPS TO REPRODUCE Long press currency change button below.(currencyWrapper) Call selectCountry and this bug happens. SourceCode let currencyWrapper = UIView() private func configureCurrencyCard(){ //The strange behavior shows up after long pressing this currencyWrapper.backgroundColor = .white currencyWrapper.addTarget(self, action: #selector(changeCurrency)) currencyWrapper.setWidth(currencyChangeIcon.follow(by: 16, x: true)) currencyWrapper.setCenterX(w1/2) currencyWrapper.setHeight(currencyLabel.follow(by: 12, x: false)) currencyWrapper.roundToCircle(true) view.addSubview(currencyWrapper) } private func selectCountry(country: Country){ let vc = CountryViewController(country: country) vc.hidesBottomBarWhenPushed = true navigationController?.pushViewController(vc, animated: true) }
Topic: UI Frameworks SubTopic: UIKit Tags:
2
0
244
Mar ’25
AppKit: presentAsModalWindow doesn't center the presented window on macOS 15
When I present a view controller, whose view is a SwiftUI View, via presentAsModalWindow(_:) the presented window is no longer centered horizontally to the screen, but rather its origin is there. I know this issue occurs for macOS 15.2+, but can't tell if it is from 15.0+. I couldn't find any documentation on why was this changed. Here's an example code that represents my architecture: class RootViewController: NSViewController { private lazy var button: NSButton = NSButton( title: "Present", target: self, action: #selector(presentView)) override func viewDidLoad() { super.viewDidLoad() // Add button to tree } @objc func presentView() { presentAsModalWindow(PresentedViewController()) } } class PresentedViewController: NSViewController { override loadView() { view = NSHostingView(rootView: MyView()) } } struct MyView: View { /* impl */ }
Topic: UI Frameworks SubTopic: AppKit Tags:
0
0
195
Mar ’25
SensorKit Data Not Retrieving
I have received permission from Apple to access SensorKit data for my app. I have granted all necessary permissions, but no data is being retrieved. The didCompleteFetch method is being called, but I’m unsure where to find event data like Device Usage and Ambient Light. Additionally, the didFetchResult method is never called. Could anyone please assist me in resolving this issue? Any guidance or troubleshooting steps would be greatly appreciated. import SensorKit class ViewController: UIViewController, SRSensorReaderDelegate { let store = SRSensorReader(sensor: .deviceUsageReport) override func viewDidLoad() { super.viewDidLoad() requestSensorAuthorization() } func requestSensorAuthorization() { var sensors: Set<SRSensor> = [ .accelerometer, .deviceUsageReport, .messagesUsageReport, .visits, .keyboardMetrics, .phoneUsageReport, .ambientLightSensor ] if #available(iOS 16.4, *) { sensors.insert(.mediaEvents) } SRSensorReader.requestAuthorization(sensors: sensors) { error in if let error = error { print("Authorization failed: \(error.localizedDescription)") } else { self.store.startRecording() self.requestSensorData() print("Authorization granted for requested sensors.") } } } func requestSensorData() { let fromTime = SRAbsoluteTime.fromCFAbsoluteTime(_cf: Date().addingTimeInterval(-60 * 60).timeIntervalSinceReferenceDate) let toTime = SRAbsoluteTime.fromCFAbsoluteTime(_cf: Date().timeIntervalSinceReferenceDate) let request = SRFetchRequest() request.from = fromTime request.to = toTime request.device = SRDevice.current store.fetch(request) store.delegate = self } func sensorReader(_ reader: SRSensorReader, didCompleteFetch fetchRequest: SRFetchRequest) { print("Fetch request completed: \(fetchRequest.from) to \(fetchRequest.to)") Task { do { let samples = try await reader.fetch(fetchRequest) print("Samples count: \(samples)") } catch { print("Error Fetching Data: \(error.localizedDescription)") } } } func sensorReader(_ reader: SRSensorReader, fetching fetchRequest: SRFetchRequest, didFetchResult result: SRFetchResult<AnyObject>) -> Bool { print(result) return true } }
0
0
248
Mar ’25
NavigationSplitView hide sidebar toggle button
I'm trying to implement the same UI used by the Settings app on iPad: a split view with two columns that are visible at all times. This code produces the layout i want, but I would like to hide the "toggle sidebar visibility" button that the system introduces. Is there a SwiftUI API I can use to hide this button? Maybe an alternate way to setup views that tells the system that the button is not necessary? struct SomeView: View { var body: some View { NavigationSplitView( columnVisibility: .constant(.all), sidebar: { Text("sidebar") }, detail: { Text("detail") } ) .navigationSplitViewStyle(.balanced) } }
7
3
8.3k
Mar ’25
Ellipsis getting added in the toolbar text when font is set on attributed string
In my project, I am getting some text from backend which could have html tags. For this, I am converting the string to attributed string. However I noticed that when the string has html tags with color in it and when the text is displayed in toolbar, then the text displays with an ellipsis towards the end. Sharing code below: import SwiftUI struct ContentViewA: View { @State private var displayText: AttributedString? var body: some View { NavigationStack { VStack { Text(displayText ?? "") } .toolbar { ToolbarItem(placement: .cancellationAction) { Button { } label: { Text("Done").font(.body.bold()) } } ToolbarItem(placement: .principal) { Text(displayText ?? "") } } .onAppear { let string = "<div><p><span style=\"color:#FF0000;\">Hello World</span></p></div>" displayText = string.convertToAttributedString /// Note: If I don't set the font, then the ellipsis are not displayed in the toolbar, but I need this font style. displayText?.font = .body.bold() } } } } extension String { var convertToAttributedString: AttributedString? { guard let data = data(using: .utf8) else { return nil } var attributedString: AttributedString? if let nsAttributedString = try? NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil) { attributedString = try? AttributedString(nsAttributedString, including: \.uiKit) } return attributedString } } I am printing displayText in the body of the view and am not seeing ellipsis at the end of the string, but in toolbar, I am seeing ellipsis. I am unable to figure out what's causing this and what can be the fix for it. However, if I avoid setting the font on attributed string, then the ellipsis are not displayed in toolbar. However, I need to set the string to a specific font style. How can I avoid ellipsis in toolbar and while also setting the required font on the string?
Topic: UI Frameworks SubTopic: SwiftUI
7
0
353
Mar ’25
SwiftData predicate for many to many relationships?
Hello, I have a Task model in my application which has an optional many to many relationship to a User model. task.assignedUsers user.tasks I am looking to construct a SwiftData predicate to fetch tasks which either have no assigned users or assigned users does not contain specific user. Here is a partially working predicate I have now: static func assignedToOthersPredicate() -> Predicate<Task> { let currentUserGUID = User.currentUserGUID return #Predicate<Task> { task in task.assignedUsers.flatMap { users in users.contains(where: { $0.guid != currentUserGUID }) } == true } } This only returns tasks assigned to others, but not those which have no assigned users. If combine it with this: static func notAssignedPredicate() -> Predicate<Task> { return #Predicate<Task> { task in task.assignedUsers == nil } } Then I get a run time crash: "to-many key not allowed here" What is the proper way to do this? Thanks.
1
0
352
Mar ’25