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

Playground SwiftUI on iPad wont save .png image using fileExporter.
The SwiftUI Playground code below demonstrates that a .jpeg image can be read and written to the iOS file system. While, a.png image can only be read; the writing request appears to be ignored. Can anyone please tell me how to code to save a .png image using SwiftUI to the iOS file system. Code: import SwiftUI import UniformTypeIdentifiers /* (Copied from Playground 'Help' menu popup.) UIImage Summary An object that manages image data in your app. You use image objects to represent image data of all kinds, and the UIImage class is capable of managing data for all image formats supported by the underlying platform. Image objects are immutable, so you always create them from existing image data, such as an image file on disk or programmatically created image data. An image object may contain a single image or a sequence of images for use in an animation. You can use image objects in several different ways: Assign an image to a UIImageView object to display the image in your interface. Use an image to customize system controls such as buttons, sliders, and segmented controls. Draw an image directly into a view or other graphics context. Pass an image to other APIs that might require image data. Although image objects support all platform-native image formats, it’s recommended that you use PNG or JPEG files for most images in your app. Image objects are optimized for reading and displaying both formats, and those formats offer better performance than most other image formats. Because the PNG format is lossless, it’s especially recommended for the images you use in your app’s interface. Declaration class UIImage : NSObject UIImage Class Reference */ @main struct MyApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct ImageFileDoc: FileDocument { static var readableContentTypes = [UTType.jpeg, UTType.png] static var writableContentTypes = [UTType.jpeg, UTType.png] var someUIImage: UIImage = UIImage() init(initialImage: UIImage = UIImage()) { self.someUIImage = initialImage } init(configuration: ReadConfiguration) throws { guard let data = configuration.file.regularFileContents, let some = UIImage(data: data) else { throw CocoaError(.fileReadCorruptFile) } self.someUIImage = some } func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper { switch configuration.contentType { case UTType.png: if let data = self.someUIImage.pngData() { return .init(regularFileWithContents: data) } case UTType.jpeg: if let data = self.someUIImage.jpegData(compressionQuality: 1.0) { return .init(regularFileWithContents: data) } default: break } throw CocoaError(.fileWriteUnknown) } } struct ContentView: View { @State private var showingExporterPNG = false @State private var showingExporterJPG = false @State private var showingImporter = false @State var message = "Hello, World!" @State var document: ImageFileDoc = ImageFileDoc() @State var documentExtension = "" var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundColor(.accentColor) Text(message) Button("export") { if documentExtension == "png" { message += ", showingExporterPNG is true." showingExporterPNG = true } if documentExtension == "jpeg" { message += ", showingExporterJPG is true." showingExporterJPG = true } } .padding(20) .border(.white, width: 2.0) .disabled(documentExtension == "") Button("import") { showingImporter = true } .padding(20) .border(.white, width: 2.0) Image(uiImage: document.someUIImage) .resizable() .padding() .frame(width: 300, height: 300) } // exporter .png .fileExporter(isPresented: $showingExporterPNG, document: document, contentType: UTType.png) { result in switch result { case .success(let url): message += ", .\(documentExtension) Saved to \(url.lastPathComponent)" case .failure(let error): message += ", Some error saving file: " + error.localizedDescription } } // exporter .jpeg .fileExporter(isPresented: $showingExporterJPG, document: document, contentType: UTType.jpeg) { result in switch result { case .success(let url): message += ", .\(documentExtension) Saved to \(url.lastPathComponent)" case .failure(let error): message += ", Some error saving file: " + error.localizedDescription } } // importer .fileImporter(isPresented: $showingImporter, allowedContentTypes: [.png, .jpeg]) { result in switch result { case .failure(let error): message += ", Some error reading file: " + error.localizedDescription case .success(let url): let gotAccess = url.startAccessingSecurityScopedResource() if !gotAccess { message += ", Unable to Access \(url.lastPathComponent)" return } documentExtension = url.pathExtension guard let fileContents = try? Data(contentsOf: url) else { message += ",\n\nUnable to read file: \(url.lastPathComponent)\n\n" url.stopAccessingSecurityScopedResource() return } url.stopAccessingSecurityScopedResource() message += ", Read file: \(url.lastPathComponent)" message += ", path extension is '\(documentExtension)'." if let uiImage = UIImage(data: fileContents) { self.document.someUIImage = uiImage }else{ message += ", File Content is not an Image." } } } } }
0
0
372
Feb ’25
iOS 18.4 App updates crashes the widget and the only solution is to restart the device or change the device language
App update in which there were no changes regarding the widget. Just after it updated, the widget turns black in some cases. It also appears black in the widget gallery. Removing and adding it again did not work in this case, only after an iOS restart it works fine again This is the log 2025-03-20 02:14:05.961611 +0800 Content load failed: unable to find or unarchive file for key: [com.aa.bb::com.aa.bb.widget:cc_widget:systemMedium::360.00/169.00/23.00:(null)~(null)] on no host. The session may still produce one shortly. Error: Using url file:///private/var/mobile/Containers/Data/PluginKitPlugin/51C5E4F2-6F1F-4466-A428-73C73B9CC887/SystemData/com.apple.chrono/placeholders/cc_widget/systemMedium----360.00w--169.00h--23.00r--1f--0.00t-0.00l-0.00b0.00t.chrono-timeline ... Error Domain=NSCocoaErrorDomain Code=4 "file“systemMedium----360.00w--169.00h--23.00r--1f--0.00t-0.00l-0.00b0.00t.chrono-timeline”not exist。" UserInfo={NSFilePath=/private/var/mobile/Containers/Data/PluginKitPlugin/51C5E4F2-6F1F-4466-A428-73C73B9CC887/SystemData/com.apple.chrono/placeholders/cc_widget/systemMedium----360.00w--169.00h--23.00r--1f--0.00t-0.00l-0.00b0.00t.chrono-timeline, NSUnderlyingError=0xa693d3a80 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
0
0
115
Mar ’25
Closure with typed throws stored as a View property crashes on iOS 17
I've encountered an issue where storing a throws(PermissionError) closure as a property inside a SwiftUI View causes a runtime crash on iOS 17, while it works correctly on iOS 18. Here’s an example of the affected code: enum PermissionError: Error { case denied } struct PermissionCheckedView<AllowedContent: View, DeniedContent: View>: View { var protectedView: () throws(PermissionError) -> AllowedContent var deniedView: (PermissionError) -> DeniedContent init( @ViewBuilder protectedView: @escaping () throws(PermissionError) -> AllowedContent, @ViewBuilder deniedView: @escaping (PermissionError) -> DeniedContent ) { self.protectedView = protectedView self.deniedView = deniedView } public var body: some View { switch Result(catching: protectedView) { case .success(let content): content case .failure(let error): deniedView(error) } } } @main struct TestApp: App { var body: some Scene { WindowGroup { PermissionCheckedView { } deniedView: { _ in } } } } Specifically this is the stack trace (sorry for the picture I didn't know how to get the txt): If I use var protectedView: () throws -> AllowedContent without typed throws it works.
2
0
300
Feb ’25
macos 15, savepanel return the wrong path when saving files occasionally
macOS: 15.0 macFUSE: 4.8.3 I am using rclone + macFUSE and mount my netdisk where it has created three subdirectories in its root directory: /user, /share, and /group. When I save a file to /[root]/user using NSSavePanel and name it test.txt, I expect the file to be saved as: /[root]/user/test.txt However, occasionally, the delegate method: - (BOOL)panel:(id)sender validateURL:(NSURL *)url error:(NSError **)outError { } returns an incorrect path: /[root]/test.txt This issue only occurs when selecting /user. The same operation works correctly for /share and /group. Is there any logs I could provide to help solving this issue? Many thanks!
Topic: UI Frameworks SubTopic: AppKit Tags:
0
0
390
Feb ’25
Conflict between offerCodeRedemption and Camera
Hello, I implemented offerCodeRedemption recently on my app in my subscription/onboarding flow. When I did, it broke my camera functionality (elsewhere in the app; totally unrelated code). I was able to fix the issue when implementing the old "AppStore.presentOfferCodeRedeemSheet" code with UIKit. I'm not sure why this is happening, but it seemed like a bug to me.
Topic: UI Frameworks SubTopic: SwiftUI
0
0
149
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
666
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
99
Mar ’25
Unable to open mach-O at path - metallib Error:2
When I toggle a panel like navigationsidebar, I get a message in the console. I guess it's not a big issue, but is there a way to fix this message? because it appears in every project. Unable to open mach-O at path: /AppleInternal/Library/BuildRoots/d187757d-b9a3-11ef-83e5-aabfac210453/Library/Caches/com.apple.xbs/Binaries/RenderBox/install/TempContent/Root/System/Library/PrivateFrameworks/RenderBox.framework/Versions/A/Resources/default.metallib Error:2
1
0
497
Mar ’25
Detect change to apps Screen Time Access
I'm creating an app which gamifies Screen Time reduction. I'm running into an issue with apples Screen Time setting where the user can disable my apps "Screen Time access" and get around losing the game. Is there a way to detect when this setting is disabled for my app? I've tried using AuthorizationCenter.shared.authorizationStatus but this didn't do the trick. Does anyone have an ideas?
0
0
426
Feb ’25
ShareLink of a movie is inconsistent
In my app, I have a ShareLink that attempts to share a movie. struct MovieTransferable: Transferable { let url: URL let writeMovie: (URL) -&gt; () static var transferRepresentation: some TransferRepresentation { DataRepresentation( exportedContentType: .movie, exporting: { (movie) in // Write the movie into documents. movie.writeMovie(movie.url) return try! Data(contentsOf: movie.url) }) FileRepresentation( exportedContentType: .movie, exporting: { (movie) in // Write the movie into documents. movie.writeMovie(movie.url) return SentTransferredFile(movie.url) }) } } The ShareLink works if you try to share the movie with the Photos app, Air Drop, and iMessage. If I share to WhatsApp, the movie shows up as empty (zero length), but there's a movie. If I share to Discord, the movie is not displayed at all (only the comment). Instagram posts a dialog saying it won't allow movies and to use the app (why are they even in the ShareLink option for movies?). YouTube processes for a bit and then does nothing (no upload). Are there things that I can do to make the Transferable accepted at more of the end points? It's at fps 30 and I've tried most of the available codec's. The size is the same as the iPhone's screen, so the aspect ratio is a bit odd. However, if I go directly to the app (Discord, etc...) upload from my phone works fine. Any help would be appreciated to make this more viable.
2
0
372
Mar ’25
.fileImporter not working on iPhone
I've been running into an issue using .fileImporter in SwiftUI already for a year. On iPhone simulator, Mac Catalyst and real iPad it works as expected, but when it comes to the test on a real iPhone, the picker just won't let you select files. It's not the permission issue, the sheet won't close at all and the callback isn't called. At the same time, if you use UIKits DocumentPickerViewController, everything starts working as expected, on Mac Catalyst/Simulator/iPad as well as on a real iPhone. Steps to reproduce: Create a new Xcode project using SwiftUI. Paste following code: import SwiftUI struct ContentView: View { @State var sShowing = false @State var uShowing = false @State var showAlert = false @State var alertText = "" var body: some View { VStack { VStack { Button("Test SWIFTUI") { sShowing = true } } .fileImporter(isPresented: $sShowing, allowedContentTypes: [.item]) {result in alertText = String(describing: result) showAlert = true } VStack { Button("Test UIKIT") { uShowing = true } } .sheet(isPresented: $uShowing) { DocumentPicker(contentTypes: [.item]) {url in alertText = String(describing: url) showAlert = true } } .padding(.top, 50) } .padding() .alert(isPresented: $showAlert) { Alert(title: Text("Result"), message: Text(alertText)) } } } DocumentPicker.swift: import SwiftUI import UniformTypeIdentifiers struct DocumentPicker: UIViewControllerRepresentable { let contentTypes: [UTType] let onPicked: (URL) -> Void func makeCoordinator() -> Coordinator { Coordinator(self) } func makeUIViewController(context: Context) -> UIDocumentPickerViewController { let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: contentTypes, asCopy: true) documentPicker.delegate = context.coordinator documentPicker.modalPresentationStyle = .formSheet return documentPicker } func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: Context) {} class Coordinator: NSObject, UIDocumentPickerDelegate { var parent: DocumentPicker init(_ parent: DocumentPicker) { self.parent = parent } func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { print("Success!", urls) guard let url = urls.first else { return } parent.onPicked(url) } func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) { print("Picker was cancelled") } } } Run the project on Mac Catalyst to confirm it working. Try it out on a real iPhone. For some reason, I can't attach a video, so I can only show a screenshot
1
0
455
Feb ’25
progress view does not work
I have an app that run Monte Carlo simulations. I run thousands of simulations in the app and a simulation runs can take on the order of 30 seconds to a minute to complete. I would like to have a progress view that tracks the number of simulation runs. How can I implement this in swiftui?
0
0
173
Mar ’25
Disable collapsing Sidebar/NavigationSplitView
I want to keep the sidebar fixed in NavigationSplitView. I don’t want the user to be able to open or close the sidebar. I removed the toggle button, but I still couldn’t make the sidebar stay fixed. It can still be closed using Cmd + Alt + S or by dragging. What I want is just to disable the resize feature of the sidebar. Isn’t it possible with SwiftUI? NavigationSplitView is kind of blackhole :) LeftSidebarView() .environmentObject(detailView) .toolbar(removing: .sidebarToggle) .navigationSplitViewColumnWidth(240)
1
0
220
Mar ’25
SwiftUI: Sheet presented from List row is not removed from screen when row is removed
I noticed if I show a sheet from a List row, then remove the row the sheet isn't removed from the screen like it is if using VStack or LazyVStack. I'd be interested to know the reason why the sheet isn't removed from the screen in the code below. It only occurs with List/Form. VStack/LazyVStack gives the expected result. I was wondering if it is an implementation issue, e.g. since List is backed by UICollectionView maybe the cells can't be the presenter of the sheet for some reason. Launch on iPhone 16 Pro Simulator iOS 18.2 Tap "Show Button" Tap "Show Sheet" What is expected: The sheet should disappear after 5 seconds. And I don't mean it should dismiss, I just mean removed from the screen. Similarly if the View that showed the sheet was re-added and its show @State was still true, then the sheet would be added back to the screen instantly without presentation animation. What actually happens: Sheet remains on screen despite the row that presented the sheet being removed. Xcode 16.2 iOS Simulator 18.2. struct ContentView: View { @State var showButton = false var body: some View { Button("\(showButton ? "Hide" : "Show" ) Button") { showButton = true Task { try? await Task.sleep(for: .seconds(5)) self.showButton = false } } //LazyVStack { // does not have this problem List { if showButton { SheetButton() } } } } struct SheetButton: View { @State var sheet = false @State var counter = 0 var body: some View { Text(counter, format: .number) Button("\(sheet ? "Hide" : "Show") Sheet") { counter += 1 sheet.toggle() } .sheet(isPresented: $sheet) { Text("Wait... This should auto-hide in 5 secs. Does not with List but does with LazyVStack.") Button("Hide") { sheet = false } .presentationDetents([.fraction(0.3)]) } // .onDisappear { sheet = false } // workaround } } I can work around the problem with .onDisappear { sheet = false } but I would prefer the behaviour to be consistent across the container controls.
2
0
393
Feb ’25
SwiftUI: How do you do CoreData backup and restore?
Hi, I am trying to create a local backup + restore when using SwiftUI and CoreData but I am facing errors left and right. the latest error I am stuck on is: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'executeFetchRequest:error: A fetch request must have an entity.' Here is what am trying to do: Creating a backup (already solved using NSPersistentStoreCoordinator.migratePersistentStore(_:to:options:type:)) Create a new NSPersistentContainer and call its NSPersistentContainer.loadPersistentStores(completionHandler:) (already solved, load is successful) Update the .environment(.managedObjectContext, viewModel.context) so that SwiftUI uses the new context. (HERE is where the error appears) Any help would be appreciated. Here is some sample code of SwiftUI part of the main view: class ViewModel: ObservableObject { @Published var context: NSManagedObjectContext } @main struct MyApp: App { @StateObject var viewModel: ViewModel var body: some Scene { WindowGroup { ContentView() .environment(\.managedObjectContext, viewModel.context) } } }
Topic: UI Frameworks SubTopic: SwiftUI
0
0
244
Mar ’25
Crash in __UIKitSharedArtworkManager
Hi, We have received reports about crash when creating a UIButton: let button = UIButton(type: .infoLight) The exception is bad access: Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000074 Exception Codes: 0x0000000000000001, 0x0000000000000074 VM Region Info: 0x74 is not in any region. Bytes before following region: 4298211212 REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL UNUSED SPACE AT START ---> __TEXT 100318000-100324000 [ 48K] r-x/r-x SM=COW /var/containers/Bundle/Application/E8912E1B-FFD8-49AF-A78A-7AA8805FDB95/My App/My App Termination Reason: SIGNAL 11 Segmentation fault: 11 Terminating Process: exc handler [550] and the main thread is crashing with the following stack trace: Thread 0 name: Dispatch queue: com.apple.main-thread Thread 0 Crashed: 0 UIKitCore 0x197e27a58 ____UIKitSharedArtworkManager_block_invoke + 116 1 libdispatch.dylib 0x19cfe2fa8 _dispatch_client_callout + 20 2 libdispatch.dylib 0x19cfe47f4 _dispatch_once_callout + 32 3 UIKitCore 0x197c3bb10 __UIKitSharedArtworkManager + 64 4 UIKitCore 0x197c3b5b0 _UIImageWithNameAndTraitCollection + 172 5 UIKitCore 0x197cbc180 _UIImageWithName + 44 6 UIKitCore 0x197c3be80 +[UIImage _systemImageNamed:fallback:withConfiguration:] + 132 7 UIKitCore 0x197a8c550 +[UIButton _defaultImageForType:andState:withConfiguration:] + 360 8 UIKitCore 0x197c1bc38 +[UIButton buttonWithType:] + 124 9 MapboxMaps 0x105f23fdc InfoButtonOrnament.init() + 400 10 MapboxMaps 0x105f2424c @objc InfoButtonOrnament.init() + 20 11 MapboxMaps 0x105fd8d80 MapView.setupManagers() + 1476 12 MapboxMaps 0x105fd8788 MapView.commonInit(mapInitOptions:overridingStyleURI:) + 1284 13 MapboxMaps 0x105fe2bcc specialized MapView.init(frame:mapInitOptions:) + 1500 14 MapboxMaps 0x105fd78cc MapView.init(frame:mapInitOptions:) + 20 15 mapbox_maps_flutter 0x10858c1dc MapboxMapController.init(withFrame:mapInitOptions:channelSuffix:registrar:pluginVersion:eventTypes:) + 496 16 mapbox_maps_flutter 0x10858f274 specialized MapboxMapFactory.create(withFrame:viewIdentifier:arguments:) + 2312 17 mapbox_maps_flutter 0x10858e8e8 @objc MapboxMapFactory.create(withFrame:viewIdentifier:arguments:) + 128 18 Flutter 0x10a99eb88 0x10a980000 + 125832 19 Flutter 0x10af474bc 0x10a980000 + 6059196 20 Flutter 0x10a9c3d38 0x10a980000 + 277816 21 libdispatch.dylib 0x19cfe1248 _dispatch_call_block_and_release + 32 22 libdispatch.dylib 0x19cfe2fa8 _dispatch_client_callout + 20 23 libdispatch.dylib 0x19cff1a34 _dispatch_main_queue_drain + 984 24 libdispatch.dylib 0x19cff164c _dispatch_main_queue_callback_4CF + 44 25 CoreFoundation 0x19529abcc __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16 26 CoreFoundation 0x1952971c0 __CFRunLoopRun + 1996 27 CoreFoundation 0x1952e9284 CFRunLoopRunSpecific + 588 28 GraphicsServices 0x1e25554c0 GSEventRunModal + 164 29 UIKitCore 0x197e32674 -[UIApplication _run] + 816 30 UIKitCore 0x197a58e88 UIApplicationMain + 340 31 My App 0x1003244e8 main + 64 32 dyld 0x1bb541de8 start + 2724 Has anyone experienced this? Could it be a bug in UIKit? Cheers, Roman Laitarenko
Topic: UI Frameworks SubTopic: UIKit
4
0
333
Feb ’25
SwiftUI refresh while alert is visible
Does causing a swiftui view refresh via modifying observed properties while an alert is visible allowed? I am seeing a warning 'Presenting view controller <SwiftUI.PlatformAlertController> from detached view controller is not supported, and may result in incorrect safe area insets and a corrupt root presentation. Make sure <SwiftUI.PlatformAlertController> is in the view hierarchy before presenting from it. Will become a hard exception in a future release.' and the warning 'Attempt to present <SwiftUI.PlatformAlertController> on (from ) while a presentation is in progress'. The second warning occurs more often.
5
0
315
Mar ’25