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
How to have different colors in Charts with AreaMark
I would like to have different fill colors in my chart. What I want to achieve is that if the values drop below 0 the fill color should be red. If they are above the fill color should be red. My code looks as follows: import SwiftUI import Charts struct DataPoint: Identifiable {     let id: UUID = UUID()     let x: Int     let y: Int } struct AlternatingChartView: View {          enum Gradients {         static let greenGradient = LinearGradient(gradient: Gradient(colors: [.green, .white]), startPoint: .top, endPoint: .bottom)         static let blueGradient = LinearGradient(gradient: Gradient(colors: [.white, .blue]), startPoint: .top, endPoint: .bottom)     }          let data: [DataPoint] = [         DataPoint(x: 1, y: 10),         DataPoint(x: 2, y: -5),         DataPoint(x: 3, y: 20),         DataPoint(x: 4, y: -8),         DataPoint(x: 5, y: 15),     ]               var body: some View {         Chart {             ForEach(data) { data in                 AreaMark(                     x: .value("Data Point", data.x),                     y: .value("amount", data.y))                 .interpolationMethod(.catmullRom)                 .foregroundStyle(data.y < 0 ? Color.red : Color.green)                                  LineMark(                 x: .value("Data Point", data.x),                 y: .value("amount", data.y))                 .interpolationMethod(.catmullRom)                 .foregroundStyle(Color.black)                 .lineStyle(StrokeStyle.init(lineWidth: 4))                              }         }         .frame(height: 200)     } } #Preview {     AlternatingChartView() } The result looks like this: I also tried using foregroundStyle(by:) and chartForegroundStyleScale(_:) but the result was, that two separate areas had been drawn. One for the below and one for the above zero datapoints. So, what would be the right approach to have two different fill colors?
0
0
103
Jun ’25
UISplitViewController changes behavior of `viewControllers` property on iOS 26
I am attempting to start my application on iOS 26 with Xcode 26. It uses an UISplitViewController that is instantiated through a Storyboard. It uses the "Unspecified" style, which is a holdover from a previous version of iOS. I'm not sure if this is a bug in iOS, or if I am supposed to change it now. The viewControllers property only has the primary view controller on iOS, although it has the primary and detail view controllers on iPadOS. When I start the application on iOS 18.5, it has both primary and detail controllers on both platforms.
0
0
132
Jun ’25
PKPass Framework
I am trying to work with the data inside the barcode string in shared PKPass. The documentation shows that is should look for @property (nonatomic, readonly, nullable) PKBarcode *primaryBarcode; I have tried to use it like this guard let code = pass.primaryBarcode?.message else { return } I get a constant message that PKPass has no member primaryBarcode The PKPass.h file in my IOS SDK does not seem to include the @property primaryBarcode or @property barcode. I am running Xcode 16.4 (16F6) and my app target is 17.6 + Is there a restriction on this property? I cannot find an SDK later than mine - the App Store does not offer one. I am unsure of this is a public or private issue - does anyone know? Thanks for reading this. Max
Topic: UI Frameworks SubTopic: SwiftUI
0
0
97
Jun ’25
LazyHstack in SwiftUI not supporting varying height views
In SwiftUI I want to create a list with LazyVstack and each row item in the LazyVstack is a LazyHstack of horizontally scrollable list of images with some description with line limit of 3 and width of every item is fixed to 100 but height of every item is variable as per description text content. But in any of the rows if the first item has image description of 1 line and the remaining items in the same row has image description of 3 lines then the LazyHStack is truncating all the image descriptions in the same row to one line making all the items in that row of same height. Why LazyHStack is not supporting items of varying height ? Expected behaviour should be that height of every LazyHStack should automatically adjust as per item content height. But it seems SwiftUI is not supporting LazyHstack with items of varying height. Will SwiftUI ever support this feature?
Topic: UI Frameworks SubTopic: SwiftUI
0
0
267
Feb ’25
In navigationLink closure, FocusState doesn't work in sheet
Hello, I have a question about FocusState, navigationLink and sheet, the code which in navigationLink closure doesn’t work, but work without navigationLink, just like the following code struct ContentView: View { var body: some View { NavigationStack { // this work interView() // this doesn't work NavigationLink { interView() } label: { Text("into interView") } } } } struct interView: View { @FocusState var focusStateA : Int? @State var show : Bool = false @State var text: String = "" var body: some View { ScrollView { VStack { coreView Button("Detail") { show.toggle() } } .sheet(isPresented: $show, content: { coreView }) } } } extension interView { var coreView : some View { VStack { VStack { putdown TextField("hi", text: $text) .focused($focusStateA , equals: 1) } } } var putdown : some View { Button(action: { if focusStateA != nil { focusStateA = nil print("OK") } else { print("It's nil") } }, label: { Text("Put down the keyboard") }) } } and there are some strange phenomena, I must put all view into a scrollview, otherwise, it even doesn’t work without navigationLink This problem has existed in IOS 18, and now in IOS26 still doesn’t be settled, is it a problem or some character?
Topic: UI Frameworks SubTopic: SwiftUI
0
0
56
Jun ’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
NSTextLists not rendered when NSTextContentStorageDelegate textContentStorage (_:, textParagraphWith:) is implemented
I have a UITextView that contains paragraphs with text bullet lists (via NSTextList). I also implement NSTextContentStorageDelegate.textContentStorage(_:, textParagraphWith:) in order to apply some custom attributes to the text without affecting the underlying attributed text. My implementation returns a new NSParagraph that modifies the foreground color of the text. I based this on the example in the WWDC 21 session "Meet Text Kit 2". UITextView stops rendering the bullets when I implement the delegate function and return a custom paragraph. Why? func textContentStorage(_ textContentStorage: NSTextContentStorage, textParagraphWith range: NSRange) -> NSTextParagraph? { guard let originalText = textContentStorage.textStorage?.attributedSubstring(from: range) else { return nil } let updatedText = NSMutableAttributedString(attributedString: originalText) updatedText.addAttribute(.foregroundColor, value: UIColor.green, range: NSRange(location: 0, length: updatedText.length)) let paragraph = NSTextParagraph(attributedString: updatedText) // Verify that the text still contains NSTextList if let paragraphStyle = paragraph.attributedString.attribute(.paragraphStyle, at: 0, effectiveRange: nil) as? NSParagraphStyle { assert(!paragraphStyle.textLists.isEmpty) } else { assertionFailure("Paragraph has lost its text lists") } return paragraph }
0
0
253
May ’25
Is it safe to access NSPrinter.printerNames on a background thread?
I'm working on a macOS application that needs to query the list of available printers using NSPrinter.printerNames. For performance reasons, I'd like to perform this operation on a background thread. However, since NSPrinter is part of AppKit, and AppKit is generally not thread-safe unless explicitly stated, I want to confirm: Is it safe to call NSPrinter.printerNames from a background thread? I couldn’t find explicit guidance in the documentation regarding the thread-safety of printerNames, so any clarification or best practices would be appreciated. Thanks in advance! Note: I tested this api on a background thread in code and it did not give any error.
Topic: UI Frameworks SubTopic: AppKit Tags:
0
0
124
May ’25
openURL:options:completionHandler: Not Opening tel:// Link on iPad with Cellular Data
We are using openURL:options:completionHandler: to open a tel:// number in the dialer to place a call. This works on iPhones and WiFi-only iPads (tested with a iPad Mini 6th Gen), but it is failing to open on an iPad 8th Gen (WiFi + Cellular) running iPadOS 18.5 being used by a customer. Prior to updating the iPad to iPadOS 18, the call worked on iPadOS 15.2 and opened the call in FaceTime as expected. Despite not opening the dialer in iPadOS 18, the completionHandler returns the success parameter as true. canOpenUrl also returns true. We created a small test application that reproduces the issue using the code snippet below in a new application, with the tel schema added to the info.plist Queried URL Schemes. We are currently using Xcode 16.3. Test Steps: Create a new blank application and replace ContentView.swift with the code snippet below Run the test app on a physical iPad 8th Gen (WiFi + Cellular) Tap the "place a test call" button Expected Results: The user is prompted to call the number and is taken to FaceTime to attempt the call. The user may then receive an alert telling them an iPhone must be paired if not already. Alternatively: return success = false in the completionHandler. Actual Results: No action occurs that is visible to the user, and the completionHandler returns success = true. Separately, we should be able to have some method of checking if the device can actually complete a call, i.e. if an iPhone is paired, so that we can correctly show or hide a phone icon in the app based on if the user can place a call. canOpenUrl returns true even if there is not a device paired and the call cannot actually be placed, and there doesn't seem to be a proper method for making that check. Code Snippet: import SwiftUI struct ContentView: View { @State private var showAlert = false var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") Button("Place a test call") { if let url = URL(string: "tel://5555554567") { UIApplication.shared.open(url) { success in if success { print("Call initiated successfully.") } else { showAlert = true } } } } } .padding() .alert("Call Failed", isPresented: $showAlert) { Button("OK") { showAlert = false } } message: { Text("The call could not be initiated.") } } } #Preview { ContentView() }
0
1
165
Jun ’25
tvOS: Using .onExitCommand to Navigate to Home Tab Before Exiting — Is This Acceptable?
Hi Apple Developer Team, In my tvOS app built with SwiftUI, I have a tab-based interface with several sections. The first tab (index 0) is the Home tab. Other tabs include Contact, WiFi, Welcome, etc. I want to handle the remote's Menu / Back button (.onExitCommand) so that: If the user is on any tab other than Home (tabs 1, 2, 3, etc.), pressing the Menu button takes them back to the Home tab. If the user is already on the Home tab, then pressing the TV/Home button (not Menu) behaves as expected — suspending or exiting the app (handled by the system, no code involved). Here's a simplified version of what I implemented: .onExitCommand { if selectedTab != 0 { selectedTab = 0 focusedTab = 0 } else { // Let system handle the exit when user presses the TV/Home button } } This behavior ensures users don’t accidentally exit the app when they're browsing other tabs, and provides a consistent navigation experience. Question: Is this an acceptable and App Store-compliant use of .onExitCommand on tvOS? I'm not calling exit(0) or trying to force-terminate the app — just using .onExitCommand for in-app navigation purposes. Any official guidance or best practices would be greatly appreciated! Thanks, Prashant
Topic: UI Frameworks SubTopic: SwiftUI Tags:
0
0
97
May ’25
Crash due to likely infinitely recursive call in SwiftUI `Color.Resolved.init`
So I'm dealing with a really obtuse crash that appears to be a stack overflow in an internal SwiftUI code path creating a Color.Resolved. I haven't found anyone one else with this issue online, and I cannot get it to reproduce on my own device. Interestingly enough, it is only happening on 1 device in the field (according to XCode crash logs). Here are some lines from the crashed thread. You can see that my code is never called, and it appears to be starting in some Array equality check checking the equality of colors (which I can't think of anywhere in my app I am doing anyway). You can see from this trace here that it appears to be a recursive call through Color.Resolved and NSColor.withColorAppearance. I don't have any idea how to solve this, but it keeps happening with at least one in-the-field device across multiple app updates. So my whole app is open source on github at https://github.com/msdrigg/roam, but I don't even use NSColor explicitly anywhere except for here which doesn't match the stack trace. I also tried changing the accent color of the app with defaults write com.msdrigg.roam AppleAccentColor -integer 1 to see if that somehow caused the crash, but my app opened up totally fine (and respected the change). Besides this, the only places I think I could be using dynamic colors is I when define an AccentColor and a WidgetBackground color for my app using xcassets, and then I use these colors from SwiftUI. In most of my app I stick to the system colors (Color.gray and such). Thread 0 Crashed: 0 libsystem_pthread.dylib 0x000000018601213c ___chkstk_darwin + 60 1 CoreFoundation 0x0000000186108434 -[NSArray isEqualToArray:] + 52 (NSArray.m:454) 2 AppKit 0x000000018a21fcd4 -[NSCoreUICatalogColor resolvedCUINamedColorForAppearance:] + 164 (NSColor.m:5057) 3 AppKit 0x0000000189c32cd4 -[NSCoreUICatalogColor resolvedColor] + 48 (NSColor.m:5148) 4 AppKit 0x0000000189c31e74 -[NSDynamicNamedColor colorUsingColorSpace:] + 32 (NSColor.m:4410) 5 SwiftUICore 0x0000000221ca9fd8 CoreColorPlatformColorGetComponents + 116 (CoreColorFunctions.m:149) 6 SwiftUICore 0x0000000221faaf28 specialized Color.Resolved.init(platformColor:) + 92 (CoreColor.swift:14) 7 SwiftUICore 0x0000000221faa5b0 Color.Resolved.init(platformColor:) + 16 (<compiler-generated>:0) 8 SwiftUI 0x00000001b53b1dc4 closure #1 in NSColor.resolve(in:) + 20 (AppKitColorConversions.swift:156) 9 SwiftUI 0x00000001b53b222c partial apply for closure #1 in static NSColor.withColorAppearance(in:_:) + 32 (<compiler-generated>:0) 10 SwiftUI 0x00000001b46b1e54 closure #1 in SubmitTriggerSource.dispatchUpdate(_:) + 28 (PlatformViewCoordinator.swift:12) 11 SwiftUI 0x00000001b5484488 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0) 12 AppKit 0x0000000189c174a4 +[NSAppearance _performWithCurrentAppearance:usingBlock:] + 72 (NSAppearance.m:2408) 13 SwiftUI 0x00000001b53b2088 specialized static NSColor.withColorAppearance(in:_:) + 324 (AppKitColorConversions.swift:142) 14 SwiftUI 0x00000001b53b1e7c protocol witness for ColorProvider.resolve(in:) in conformance NSColor + 68 (<compiler-generated>:151) 15 SwiftUICore 0x0000000222436e6c ColorBox.resolve(in:) + 124 (Color.swift:288) 16 SwiftUICore 0x0000000222435e30 Color.resolve(in:) + 72 (Color.swift:87) 17 SwiftUI 0x00000001b53b1c88 closure #1 in NSColor.init(_:) + 196 (AppKitColorConversions.swift:124) 18 SwiftUI 0x00000001b4542714 thunk for @escaping @callee_guaranteed (@guaranteed NSAppearance) -> (@owned NSColor) + 56 (<compiler-generated>:0) 19 AppKit 0x0000000189c31e74 -[NSDynamicNamedColor colorUsingColorSpace:] + 32 (NSColor.m:4410) //// ... Repeating for 500 lines 500 SwiftUICore 0x0000000221ca9fd8 CoreColorPlatformColorGetComponents + 116 (CoreColorFunctions.m:149) 501 SwiftUICore 0x0000000221faaf28 specialized Color.Resolved.init(platformColor:) + 92 (CoreColor.swift:14) 502 SwiftUICore 0x0000000221faa5b0 Color.Resolved.init(platformColor:) + 16 (<compiler-generated>:0) 503 SwiftUI 0x00000001b53b1dc4 closure #1 in NSColor.resolve(in:) + 20 (AppKitColorConversions.swift:156) 504 SwiftUI 0x00000001b53b222c partial apply for closure #1 in static NSColor.withColorAppearance(in:_:) + 32 (<compiler-generated>:0) 505 SwiftUI 0x00000001b46b1e54 closure #1 in SubmitTriggerSource.dispatchUpdate(_:) + 28 (PlatformViewCoordinator.swift:12) 506 SwiftUI 0x00000001b5484488 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0) 507 AppKit 0x0000000189c174a4 +[NSAppearance _performWithCurrentAppearance:usingBlock:] + 72 (NSAppearance.m:2408) 508 SwiftUI 0x00000001b53b2088 specialized static NSColor.withColorAppearance(in:_:) + 324 (AppKitColorConversions.swift:142) 509 SwiftUI 0x00000001b53b1e7c protocol witness for ColorProvider.resolve(in:) in conformance NSColor + 68 (<compiler-generated>:151) 510 SwiftUICore 0x0000000222436e6c ColorBox.resolve(in:) + 124 (Color.swift:288) full-log.crash
0
0
118
May ’25
Debugging Snapshot Thread Confinement Warning in UITableViewDiffableDataSource
I first applied a snapshot on the main thread like this: var snapshot = NSDiffableDataSourceSnapshot<Section, MessageViewModel>() snapshot.appendSections([.main]) snapshot.appendItems([], toSection: .main) dataSource.applySnapshotUsingReloadData(snapshot) After loading data, I applied the snapshot again using: Task { @MainActor in await dataSource.applySnapshotUsingReloadData(snapshot) } On an iPhone 13 mini, I received the following warning: Warning: applying updates in a non-thread confined manner is dangerous and can lead to deadlocks. Please always submit updates either always on the main queue or always off the main queue However, this warning did not appear when I ran the same code on an iPhone 16 Pro simulator. Can anyone explain it to me? Thank you
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
98
May ’25
About CarPlay entitlement of EV
I'm developing a CarPlay version of my app, with the CarPlay EV Charging App entitlement (com.apple.developer.carplay-charging). However, I would like to use the Search template to searching for charging stations — but it seems this template is only available for Navigation Apps(maps). In this case, what is the recommended approach? Is it possible to apply both entitlements simultaneously and use the Search template only?
0
0
76
Jun ’25
ssue with Session Sharing Between Safari and ASWebAuthenticationSession
We are experiencing an issue with session sharing on iOS and would appreciate your guidance. We operate and control our own OpenID Connect (OIDC) server. Our iOS application uses ASWebAuthenticationSession to authenticate users. We're unable to get the authentication session to be shared between the Safari app and the app's ASWebAuthenticationSession. This results in users having to re-authenticate despite being logged in via Safari. We've attempted various configurations related to cookie SameSite settings. These adjustments resolved the session sharing issue on Android using Chrome Custom Tabs. However, no changes we've tried have enabled session sharing to work as expected on iOS. According to documentation from Apple, Microsoft, Okta, and Auth0, session sharing between Safari and ASWebAuthenticationSession should work. Question: Are there any additional settings, configurations, or platform limitations we should be aware of that could impact session sharing on iOS? Where else can we look to resolve this issue?
Topic: UI Frameworks SubTopic: General
0
0
131
May ’25
FamilyActivityTitleView Label has wrong text color when app is using different than system theme
Hello, In a new app I am working on I noticed the FamilyActivityTitleView that displays "ApplicationToken" has wrong (black) color when phone is set to light mode but app is using dark mode via override. We display user's selected apps and the labels are rendered correctly at first, but then when user updates selection with FamilyActivityPicker, then those newly added apps are rendered with black titles. The problem goes away when I close the screen and open it again. It also doesn't happen when phone is set to dark theme. I am currently noticing the issue on iOS 18.4.1. I have tried various workarounds like forcing white text in the custom label style, forcing re-render with custom .id value but nothing helped. Is there any way how to fix this?
0
0
125
May ’25
Updating sort order of items in a LazyVGrid
I have a grid setup where I'm displaying multiple images which is working fine. Images are ordered by the date they're added, newest to oldest. I'm trying to set it up so that the user can change the sort order themselves but am having trouble getting the view to update. I'm setting the fetch request using oldest to newest as default when initialising the view, then when its appears updating the sort descriptor struct ProjectImagesListView: View { @Environment(\.managedObjectContext) private var viewContext var project : Project let columns = [ GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible()) ] @FetchRequest var pictures: FetchedResults<Picture> var body: some View { ScrollView { LazyVGrid(columns: columns) { ForEach(pictures) { picture in NavigationLink(destination: ProjectImageDetailView(picture: picture)) { if let pictureData = picture.pictureThumbnailData, let uiImage = UIImage(data: pictureData) { Image(uiImage: uiImage) .resizable() .scaledToFit() .frame(height: 100) } else { Image("missing") .resizable() .scaledToFit() .frame(height: 100) } } } } } .navigationBarTitle("\(project.name ?? "") Images", displayMode: .inline) .onAppear() { guard let sortOrder = getSettingForPhotoOrder() else { return } guard let sortOrderValue = sortOrder.settingValue else { return } NSLog("sortOrderPhotos: \(String(describing: sortOrder.settingValue))") if sortOrderValue == "Newest" { NSLog("sortOrderPhotos: Change from default") let newSortDescriptor = NSSortDescriptor(keyPath: \Picture.dateTaken, ascending: false) pictures.nsSortDescriptors = [newSortDescriptor] } } } func getSettingForPhotoOrder() -> Setting? { let fetchRequest: NSFetchRequest<Setting> = Setting.fetchRequest() fetchRequest.predicate = NSPredicate(format: "name = %@", "photoSortOrder") fetchRequest.fetchLimit = 1 do { let results = try viewContext.fetch(fetchRequest) return results.first } catch { print("Fetching Failed") } return nil } init(project: Project) { self.project = project _pictures = FetchRequest( entity: Picture.entity(), sortDescriptors: [ NSSortDescriptor(keyPath: \Picture.dateTaken, ascending: true) ], predicate: NSPredicate(format: "project == %@", project) ) } }
Topic: UI Frameworks SubTopic: SwiftUI
0
0
87
May ’25