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

swiftui fileimporter inside UIHostingController
I'm working on an old iOS app that started with objective-C + UIKit and has being migrated to Swift + SwiftUI. Currently its code is mostly Swift + SwiftUI but it has still some objective-C and some UIKit ViewControllers. One of the SwiftUI views uses fileImporter to open Files App and select a file from the device. This has been working well until iOS 18 is launched. With iOS 18 the file picker is not launching correctly and is frozen in every simulator (the unique real device I've could test with iOS 18 seemed to work correctly). I managed to clone my project and leave it with the minimal amount of files to reproduce this error. This is the code: AppDelegate.h #import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> {} @property (strong, nonatomic) UIWindow *window; @end AppDelegate.m #import "AppDelegate.h" #import "MyApp-Swift.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; FirstViewBuilder *viewBuilder = [[FirstViewBuilder alloc] init]; [viewBuilder show]; return YES; } @end FirstViewBuilder.swift import SwiftUI @objc class FirstViewBuilder: NSObject { private var view: UIHostingController<FirstView> @objc override init() { self.view = MyHostingController(rootView: FirstView()) } @objc func show() { let app = UIApplication.shared.delegate as? AppDelegate let window = app?.window window?.backgroundColor = .white // Use navigationController or view directly depending on use window?.rootViewController = view } } FirstView.swift import SwiftUI struct FirstView: View { @State var hasToOpenFilesApp = false var body: some View { VStack(alignment: .leading, spacing: 0) { Button("Open Files app") { hasToOpenFilesApp = true }.fileImporter(isPresented: $hasToOpenFilesApp, allowedContentTypes: [.text]) { result in switch result { case .success(let url): print(url.debugDescription) case .failure(let error): print(error.localizedDescription) } } } } } And finally, MyHostingController import SwiftUI class MyHostingController<Content>: UIHostingController<Content> where Content: View { override init(rootView: Content) { super.init(rootView: rootView) } @objc required dynamic init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() navigationItem.hidesBackButton = true } } Launching this in an iPhone 13 Pro (18.2) simulator I click on Open Files App, it takes 2 seconds to open it, and it opens full screen (not like a modal). Buttons on the top are behind the status bar and buttons at the bottom are behind the Home indicator. But it's worse because the user can't interact with this view, it's frozen. I created a fresh SwiftUI project just with this unique view and the fileimport worked as expected so I thought the problem was due to embed the SwiftUI view inside the UIHostingController. So I made these modifications to the minimal project: Remove the files AppDelegate, FirstViewBuilder and MyHostingController. Create this SwiftUI App file import SwiftUI @main struct MyApp: App { var body: some Scene { WindowGroup { FirstView() } } } And again the same problem with iOS 18. But if I launch this exact project in an iPhone 13 Pro (17.4) simulator and open the files apps (now it opens almost instantly) it works OK and shows the file picker as a modal, as expected, and I can interact with it and select files. Last thing I've tried is removing LaunchScreen.xib from my project and Launch screen interface file base name key from my info.plist but the problem keeps happening. I guess it must be due to my project configuration (too old) but I have no more ideas of where to look at. The possibility of having a fresh SwiftUI project and "move" the old project to the new one could take me several weeks and I discard it by the moment. Could I use another method to select files from SwiftUI views with iOS 18?
2
0
500
Feb ’25
Removing SwiftUI View from hierarchy
In a UIKit application, removing a view from the hierarchy is straightforward—we simply call myView.removeFromSuperview(). This not only removes myView from the UI but also deallocates any associated memory. Now that I'm transitioning to SwiftUI, I'm struggling to understand the recommended way to remove a view from the hierarchy, given SwiftUI's declarative nature. I understand that in SwiftUI, we declare everything that should be displayed. However, once a view is rendered, what is the correct way to remove it? Should all UI elements be conditionally controlled to determine whether they appear or not? Below is an example of how I’m currently handling this, but it doesn’t feel like the right approach for dynamically removing a view at runtime. Can someone guide me on the best way to remove views in SwiftUI? struct ContentView: View { @State private var isVisible = true var body: some View { VStack { if isVisible { // set this to false to remove TextView? Text("Hello, SwiftUI!") .padding() } Button("Toggle View") { ... } } } }
1
0
272
Mar ’25
Push Button captions not properly written to PDF document using PDFKit
The Problem Push buttons (created as a PDFAnnotation using PDFKit) do not properly write the associated caption's key-value pair (within the annotation's appearance characteristics dictionary) to a PDF document. What is Happening Push button widget annotations can have a caption that is displayed as the button’s label. In the PDF 1.7 specification (ISO PDF32000-2008, s. 12.5.6.19), a widget annotation can have an ‘appearance characteristics dictionary’ (MK) with properties to construct the appearance of the widget. The caption property (CA) is used to construct a button’s caption/label. PDFKit uses the PDFAnnotation .caption property to set the value of a push button’s caption as a string. Observation 1: In an open PDF document (using PDFView), a push button widget annotation can be created and added to a PDFPage using the following code: let pushButton = PDFAnnotation(bounds: pushButtonBounds, forType: .widget, withProperties: nil) pushButton.widgetFieldType = .button pushButton.widgetControlType = .pushButtonControl pushButton.caption = "My Button" page.addAnnotation(pushButton) The PDFAnnotation .caption property is used to set the caption to the required string. As a result, the push button is correctly displayed on the PDFPage with the correct label being display on the button. While the PDF document remains open, the appearance characteristics dictionary (an PDFAppearanceCharacteristics object) retains a key-value pair for the caption with the correct value as expected. On saving/writing to the PDF file, however, the key-value pair for the caption in the appearance characteristics dictionary is not written to the PDF document’s file. Resulting PDF markup: 6 0 obj << /Rect [ 256 299.8977 356 399.8977 ] /Border [ 0 0 0 ] /T (button23) /F 4 /Subtype /Widget /DA (/.AppleSystemUIFont 13 Tf 0 g) /MK 8 0 R /C [ 0 ] /AP 9 0 R /V /Off /M (D:20250330154918Z00'00') /FT /Btn /Type /Annot /Ff 65536 >> endobj 9 0 obj << /N 10 0 R >> endobj 8 0 obj << /BG [ 0.75 ] >> endobj 10 0 obj << /Filter /FlateDecode /Type /XObject /Subtype /Form /FormType 1 /BBox [0 0 100 100] /Resources 11 0 R /Length 170 >> stream x }ê1 Ç0 Öw~≈ ahÈ KÈ q1q0\‚`ú Ÿ¿ 8¯Ôm% u0óª‰.Ô{yπ åP°H-}ª‡à y3 ¸ %≠¡‰ %› g¨$•µMVXø‡Hé†Ö ”î“¿˜® BI•L ˆ†b A pü‰Ã @ÓpB∫ †æœs ãÙ:d8Éwÿr»/}” €∂I÷Bõ B;'+gm Ô˝„ mÙ~ L*>• endstream endobj On closing the PDF document, the assigned value for the push button’s caption is not written to the file and is lost. Observation 2: On reopening the PDF document, and assigning a new value for the already-created push button’s caption, a key-value pair for the caption is again correctly added to the PDFAnnotation appearance characteristics dictionary. On saving/writing to the PDF file, this time, the caption key-value pair in the appearance characteristics dictionary is correctly written/saved to the PDF document file. Resulting PDF markup: 6 0 obj << /Border [ 0 0 0 ] /Rect [ 256 299.8977 356 399.8977 ] /T (button23) /F 4 /BS 8 0 R /Subtype /Widget /DA (/.AppleSystemUIFont 13 Tf 0 g) /MK 9 0 R /C [ 0 ] /AP 10 0 R /V /Off /M (D:20250330154918Z00'00') /FT /Btn /Type /Annot /Ff 65536 >> endobj 10 0 obj << /N 11 0 R >> endobj 9 0 obj << /BG [ 0.75 ] /CA (My Button) >> endobj 8 0 obj << /W 0 >> endobj 11 0 obj << /Filter /FlateDecode /Type /XObject /Subtype /Form /FormType 1 /BBox [0 0 100 100] /Resources 12 0 R /Length 163 >> stream x uè1 ¬@ Ö˜˛ä7∂√]ì´◊Î≠ ¡A 8à”a∑Vj·ø˜jë™ !ÅÑ|y/=ˆËA1òʺ]pDá|=0¬“Œb ø+Õ gùf2E≤∞Ê≈N` û·Xm©-BãZ†H Ÿ ¿≈ºPÄ= Ø míãp •¡ ÈÓÅ˙>é “kó· Ÿb#—¬ Ûã¶2∂Ñ2fiΠ;óDÌiÓ?ü>LÁûÊy;} endstream endobj Impact on User Experience: Push button captions may not be properly saved to the PDF document’s file. This may result in an application redrawing a push button without a caption/label. More so, an application that uses the caption value to “read” a button’s label (e.g., for accessibility purposes) will not be able to do so.
1
0
98
Apr ’25
SwiftUI FileDocument: Modify the default save dialog
Is it possible to change the default save dialog that appears when creating a document based MacOS app in SwiftUI? I have a basic FileDocument struct that gets called to a view using a DocumentGroup scene. struct MyFile: FileDocument { static let readableContentTypes: [UTType] = [.myFileType] static let writeableContentTypes: [UTType] = [.myFileType] var list: [String] init(configuration: ReadConfiguration) throws { let data = configuration.file.regularFileContents! let JSONDecoder = JSONDecoder() do { try list = JSONDecoder.decode([String].self, from: data) } catch { throw CocoaError(.fileReadCorruptFile) } } func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper { let JSONEncoder = JSONEncoder() JSONEncoder.outputFormatting = .prettyPrinted do { data = try JSONEncoder.encode(self.list) } catch { print(error.localizedDescription) throw CocoaError(.fileWriteUnknown) } return .init(regularFileWithContents: data) } } This gets called at the DocumentGroup DocumentGroup(newDocument: MyFile(), editor: { document in ContentView(document: document.$document) }) But when I save the file, I want the save dialog that appears to have something like a 'Tags' textField that can also store information about the file. Something similar to this: (https://i.sstatic.net/AJQ3YNb8.png) From what I can find, there isn't much information about this other than manually creating an NSSavePanel class and overriding the current save function
1
0
472
Mar ’25
Is UIApplication.setAlternateIconName still available to use?
I writing swift code to change the app icon using setAlternateIconName and flutter MethodChannel to invoke swift. UIApplication.shared.setAlternateIconName(iconName) { error in if let error = error { print("Error setting alternate icon: \(error.localizedDescription)") result(FlutterError(code: "ICON_CHANGE_ERROR", message: error.localizedDescription, details: nil)) // Send error back to Flutter } else { print("App icon changed successfully!") result(nil) // Success! } } But I got an error message the requested operation couldn't be completed because the feature is not supported when using it on iOS 17+. So, Is setAlternateIconName still available? PS. In XCode, the code hinting shows that setAlternateIconName is still not deprecated.
Topic: UI Frameworks SubTopic: UIKit Tags:
1
0
306
Feb ’25
Widgets and App extensions
Hi, I have few questions regarding the widgets. I would like to know whether widget and app extensions are same ? This link(https://developer.apple.com/app-extensions/) says widget is type of app extension but I am not quite sure as few link in web says they are different. so need to confirm here :) Can a widget share same bundle id as the main app ? so basically can we use the same provisioning profile as the main app? If we use the same bundle id and provisioning profile, will there be any issue during the app store submission process.?
1
0
670
Mar ’25
UIContextMenuInteraction not working if view is originally offscreen
I’m having a weird UIKit problem. I have a bunch of views in a UIScrollView and I add a UIContextMenuInteraction to all of them when the view is first loaded. Because they're in a scroll view, only some of the views are initially visible. The interaction works great for any of the views that are initially on-screen, but if I scroll to reveal new subviews, the context menu interaction has no effect for those. I used Xcode's View Debugger to confirm that my interaction is still saved in the view's interactions property, even for views that were initially off-screen and were then scrolled in. What could be happening here?
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
105
Mar ’25
How do you pass a view builder into a view?
I'm making a custom control, specifically a checkbox next to a "label." I want the label parameter, like many in Apple's built-in controls, to take a view-building closure. But I can't figure out the correct syntax. I looked at the declaration of Apple's NavigationLink control for clues: public struct NavigationLink<Label, Destination> : View where Label : View, Destination : View { /// Creates a navigation link that presents the destination view. /// - Parameters: /// - destination: A view for the navigation link to present. /// - label: A view builder to produce a label describing the `destination` /// to present. public init(@ViewBuilder destination: () -> Destination, @ViewBuilder label: () -> Label) But when I mimic this, the compiler complains about the body() function: struct CheckboxItem<Label> : View where Label : View { let stateCheck: () -> Bool let label: () -> any View let boxSize: CGFloat init(withStateCheck: @escaping () -> Bool, boxSize: CGFloat, @ViewBuilder label: @escaping () -> Label) { stateCheck = withStateCheck self.label = label self.boxSize = boxSize } var body: some View { HStack { <-- ERROR: "Type 'any View' cannot conform to 'View'" Image(systemName: stateCheck() ? "checkmark.square" : "square") .resizable() .aspectRatio(contentMode: .fit) .frame(width: boxSize, height: boxSize) .foregroundColor(AppStyle.labelColor) .opacity(0.75) label() } } } Also, note that I had to put @escaping before my label parameter, but that's not seen in Apple's. Any ideas?
Topic: UI Frameworks SubTopic: SwiftUI
1
0
211
Mar ’25
Performing simulations in the UI elements in uikit
I wanted to perform simulation in my application as a self tour guide for my user. For this I want to programatically simulate various user interaction events like button click, keypress event in the UITextField or moving the cursor around in the textField. These are only few examples to state, it can be any user interaction event or other events. I wanted to know what is the apple recommendation on how should these simulations be performed? Is there something that apple offers like creating an event which can be directly executed for simulations. Is there some library available for this purpose?
Topic: UI Frameworks SubTopic: UIKit Tags:
2
0
316
Feb ’25
Putting buttons over SwiftUI map view
Has anyone gotten custom buttons to work on top of tvOS Map()? I've tried many variations of FocusState focusSection .defaultFocus() and as soon as the map appears at startup the buttons never get focus again. They are on a ZStack over the map. I could post code but truthfully nothing works for me. I'm wondering if anyone has successfully put focusable buttons on top of the map view.
0
0
236
Mar ’25
Why my app clips is Unavailable
My App Clip is associated with three domains: • nfc.ttwifi.net • qr.ttwifi.net Currently, I’m experiencing an issue where scanning a QR code from qr.ttwifi.net correctly launches my App Clip. However, when I scan a QR code from nfc.ttwifi.net, it successfully displays the App Clip card but then shows the message “App Clip unavailable.” I checked the Website Status in App Store Connect, and both domains have their Debugging Status and Cache Status marked as Verified. One important detail to note: Yesterday, while submitting a new version for review, I noticed that nfc.ttwifi.net showed “Unable to connect to AASA file” in the Cache Status in App Store Connect. The cache status update time was March 27, 2025, at 6:52 PM. However, when I checked today, both domains appeared to be fine, and the cache status update time was March 27, 2025, at 7:07 PM. How can I restore the App Clip functionality for my nfc.ttwifi.net domain?
6
0
208
Apr ’25
WidgetKit: add new widget to bundle
Hi, I have an existing Mac app on the App Store with a couple of widgets as part of the app. I want to now add a new widget to the WidgetBundle. When I build the updated app with Xcode, and then run the updated app, the widgets list doesn't seem to get updated in Notification Center or in the WidgetKit Simulator. I do have the App Store version installed in the /Applications folder as well, so there might be some conflict. What's the trick to getting the widgets list to run the debug version?
0
0
100
Mar ’25
Mixing NavigationLink types (value: and non-value: types)
Hello, I was wondering if someone could clear-up my thinking here. e.g. consider the code below... It has a rootView with a navlink to a childView which in turn has navlinks to GrandchildViews. The root view uses basic navLInks NavigationLink{View} label: {View} The child view uses type-based navLinks navigationLink(value:) {View} and .navigationDestination(for:) {View} I would expect the basic navlinks to work in the root view and the type-based ones to work in the child view. However it appears that both are active when one taps on a link in the child view. e.g. User actions: Start -> RootView is only view on the stack -> (tap on ‘Child View’) -> ChildView is top of the stack -> tap on ‘Alice’ -> a second ChildView is top of the stack with a GrandchildView underneath…. Why does this happen, why are the basic links also applied to the childView's links? Thanks. struct Thing: Identifiable, Hashable { let id = UUID() let name: String } struct RootView: View { var body: some View { NavigationStack { List { NavigationLink { ChildView() } label: { Label("Child View", systemImage: "figure.and.child.holdinghands") } NavigationLink { Text("Hello") } label: { Label("Another navLink item in the list", systemImage: "circle") } } .padding() } } } struct ChildView: View { private var things = [ Thing(name: "Alice"), Thing(name: "Bob"), Thing(name: "Charlie"), ] var body: some View { Text("This is the child view") List { ForEach(things) { thing in NavigationLink(value: thing) { Text(thing.name) } } } .navigationTitle("Child View") .navigationDestination(for: Thing.self) { thing in GrandchildView(thing: thing) } } } struct GrandchildView: View { let thing: Thing var body: some View { Text("This is the GrandchildView: \(thing.name)") } }
Topic: UI Frameworks SubTopic: SwiftUI
0
0
131
Mar ’25
SWIFTUI: chartLegend alignment 'Centering' option
SWIFTUI : Chart control / view is there way to align the Legends to align the center I see there only 2 options, .chartLegend(position: .bottom, alignment: .leading,spacing: 10) .leading or .trailing code : Chart{ ..... SectorMark.. } .chartLegend(position: .bottom, alignment: .leading,spacing: 10)
Topic: UI Frameworks SubTopic: SwiftUI
2
0
284
Mar ’25
SwiftUI: How to change `contentInset` of `List`
Hi, Is there any way of changing the contentInset (UIKit variant) of a List in SwiftUI? I do not see any APIs for doing so, the closest I gotten is to use safeAreaInset . While visually that works the UX is broken as you can no longer "scroll" from the gap made by the .safeAreaInset(edge:alignment:spacing:content:) I have subbmited a feedback suggestion: FB16866956
0
0
182
Mar ’25
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
249
Mar ’25
Foundation (?) mangles diacriticals in Greek Extended (U+1F54)
(NOTE: In sum, this is destructive of user data.) The client is a professor of Classics in constant need of properly-rendered glyphs that represent legitimate code points. As an example, the correct spelling might be: εὔτρητος It is spelled and rendered as intended. A file by this name will be correctly spelled by ls in the Terminal. Note that two diacritics are applied to the second letter, an upsilon (ὔ) However, the Finder displays that file as ἐύτρητος and iterating the string reveals that the accents are improperly distributed over the two. This would never be correct. This handicaps digital-humanities researchers from college to postdoctoral work. A Character by Character iteration demonstrates the mangling.: intended (εὔτρητος) displayed (ἐύτρητος) 3B5 (ε) 1F10 (ἐ) GREEK SMALL LETTER EPSILON, GREEK SMALL LETTER EPSILON WITH PSILI 1F54 (ὔ) 3CD (ύ) GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA GREEK SMALL LETTER UPSILON WITH TONOS 3C4 (τ) 3C4 (τ) (back in sync) 3C1 (ρ) 3C1 (ρ) 3B7 (η) 3B7 (η) 3C4 (τ) 3C4 (τ) 3BF (ο) 3BF (ο) 3C2 (ς) 3C2 (ς) I don't want to muddy the waters by guessing where and how the mistake is made, just see for yourself.
1
0
382
Feb ’25