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

Identifying SwiftUI list cells in XCUITest
In my macOS app I have a SwiftUI list that starts like this: List(selection: $selection) { HStack { Label("Staging", systemImage: "arrow.up.square") Spacer() WorkspaceStatusBadge(unstagedCount: model.statusCounts.unstaged, stagedCount: model.statusCounts.staged) } (where WorkspaceStatusBadge is a custom view that just contains a Text) I'm trying to set the accessibility ID of that first cell so I can find it in XCUITest. If I apply the accessibilityIdentifier() modifier to the HStack, it instead sets the ID of the two static text elements inside it, and the cell still has no ID. I could find the cell based on the ID of the child staticText, but I have some other cases where this doesn't work as well. If I use .accessibilityElement() on the HStack, then XCUI sees a cell containing a Group element with the ID. This might be workable, but it's certainly not ideal. So how do I set the ID of the cell itself?
3
0
469
Jan ’25
iOS 18 Button with accented image is broken(cannot tap) in desktop widget.
In iOS 18 widget, button is broken when it's has an accented desaturated image as content, the button's AppIntent will not trigger perform function. checkout the code below: ` struct WidgetExtEntryView : View { var entry: Provider.Entry var body: some View { VStack { Text("count:") Text("\(WidgetExtAppIntent.count)") HStack { // button can not be tapped Button(intent: WidgetExtAppIntent(action: "+1")) { VStack { Image(systemName: "plus.square.fill").resizable() .widgetAccentedRenderingMode(.accentedDesaturated) // <-- here .frame(width: 50, height: 50) Text("Broken") } }.tint(.red) // button can be tapped Button(intent: WidgetExtAppIntent(action: "+1")) { VStack { Image(systemName: "plus.square.fill").resizable() .widgetAccentedRenderingMode(.fullColor) // <-- here .frame(width: 50, height: 50) Text("OK").frame(width: 50, alignment: .center) } }.tint(.green) } .minimumScaleFactor(0.5) } } } ` check out the full demo project: ButtonInWidgetBrokenIOS18
2
0
336
Jan ’25
Suggestion to Add Performance Metrics for SwiftUI in XCTest
As SwiftUI adoption grows, developers face challenges in effectively measuring and optimizing SwiftUI app performance within automated tests. Currently, the only viable approach to analyzing SwiftUI performance is through Profiling (Instruments), which, while powerful, lacks the ability to be incorporated into automated testing workflows. It would be incredibly valuable if XCTest could introduce new performance metrics specifically tailored for SwiftUI, allowing us to write tests against common performance bottlenecks. Suggested Metrics: View Body Evaluation Count – Tracks how often a SwiftUI body is recomputed to detect unnecessary re-renders. Slow View Bodies – Flags SwiftUI views that take a significant amount of time to compute their body. These metrics would help developers identify inefficiencies early, enforce performance best practices through CI/CD pipelines, and ensure a smooth user experience. I believe adding these performance metrics would be a game-changer for SwiftUI development. Thank you for your time and consideration!
1
0
428
Feb ’25
SwiftUI crashes EXC_BREAKPOINT at _dispatch_semaphore_dispose
Based on crash reports for our app in production, we're seeing these SwiftUI crashes but couldn't figure out why it is there. These crashes are pretty frequent (>20 crashed per day). Would really appreciate it if anyone has any insight on why this happens. Based on the stacktrace, i can't really find anything that links back to our app (replaced with MyApp in the stacktrace). Thank you in advance! Crashed: com.apple.main-thread 0 libdispatch.dylib 0x39dcc _dispatch_semaphore_dispose.cold.1 + 40 1 libdispatch.dylib 0x4c1c _dispatch_semaphore_signal_slow + 82 2 libdispatch.dylib 0x2d30 _dispatch_dispose + 208 3 SwiftUICore 0x77f788 destroy for StoredLocationBase.Data + 64 4 libswiftCore.dylib 0x3b56fc swift_arrayDestroy + 196 5 libswiftCore.dylib 0x13a60 UnsafeMutablePointer.deinitialize(count:) + 40 6 SwiftUICore 0x95f374 AtomicBuffer.deinit + 124 7 SwiftUICore 0x95f39c AtomicBuffer.__deallocating_deinit + 16 8 libswiftCore.dylib 0x3d783c _swift_release_dealloc + 56 9 libswiftCore.dylib 0x3d8950 bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 160 10 SwiftUICore 0x77e53c StoredLocation.deinit + 32 11 SwiftUICore 0x77e564 StoredLocation.__deallocating_deinit + 16 12 libswiftCore.dylib 0x3d783c _swift_release_dealloc + 56 13 libswiftCore.dylib 0x3d8950 bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 160 14 MyApp 0x1673338 objectdestroyTm + 6922196 15 libswiftCore.dylib 0x3d783c _swift_release_dealloc + 56 16 libswiftCore.dylib 0x3d8950 bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 160 17 SwiftUICore 0x650290 _AppearanceActionModifier.MergedBox.__deallocating_deinit + 32 18 libswiftCore.dylib 0x3d783c _swift_release_dealloc + 56 19 libswiftCore.dylib 0x3d8950 bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 160 20 SwiftUICore 0x651b44 closure #1 in _AppearanceActionModifier.MergedBox.update()partial apply + 28 21 libswiftCore.dylib 0x3d783c _swift_release_dealloc + 56 22 libswiftCore.dylib 0x3d8950 bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 160 23 libswiftCore.dylib 0x3b56fc swift_arrayDestroy + 196 24 libswiftCore.dylib 0xa2a54 _ContiguousArrayStorage.__deallocating_deinit + 96 25 libswiftCore.dylib 0x3d783c _swift_release_dealloc + 56 26 libswiftCore.dylib 0x3d8950 bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 160 27 SwiftUICore 0x4a6c4c type metadata accessor for _ContiguousArrayStorage<CVarArg> + 120 28 libswiftCore.dylib 0x3d783c _swift_release_dealloc + 56 29 libswiftCore.dylib 0x3d8950 bool swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1>>::doDecrementSlow<(swift::PerformDeinit)1>(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 160 30 SwiftUICore 0x4a5d88 static Update.dispatchActions() + 1332 31 SwiftUICore 0xa0db28 closure #2 in closure #1 in ViewRendererHost.render(interval:updateDisplayList:targetTimestamp:) + 132 32 SwiftUICore 0xa0d928 closure #1 in ViewRendererHost.render(interval:updateDisplayList:targetTimestamp:) + 708 33 SwiftUICore 0xa0b0d4 ViewRendererHost.render(interval:updateDisplayList:targetTimestamp:) + 556 34 SwiftUI 0x8f1634 UIHostingViewBase.renderForPreferences(updateDisplayList:) + 168 35 SwiftUI 0x8f495c closure #1 in UIHostingViewBase.requestImmediateUpdate() + 72 36 SwiftUI 0xcc700 thunk for @escaping @callee_guaranteed () -> () + 36 37 libdispatch.dylib 0x2370 _dispatch_call_block_and_release + 32 38 libdispatch.dylib 0x40d0 _dispatch_client_callout + 20 39 libdispatch.dylib 0x129e0 _dispatch_main_queue_drain + 980 40 libdispatch.dylib 0x125fc _dispatch_main_queue_callback_4CF + 44 41 CoreFoundation 0x56204 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16 42 CoreFoundation 0x53440 __CFRunLoopRun + 1996 43 CoreFoundation 0x52830 CFRunLoopRunSpecific + 588 44 GraphicsServices 0x11c4 GSEventRunModal + 164 45 UIKitCore 0x3d2eb0 -[UIApplication _run] + 816 46 UIKitCore 0x4815b4 UIApplicationMain + 340 47 SwiftUI 0x101f98 closure #1 in KitRendererCommon(_:) + 168 48 SwiftUI 0xe2664 runApp<A>(_:) + 100 49 SwiftUI 0xe5490 static App.main() + 180 50 MyApp 0x8a7828 main + 4340250664 (MyApp.swift:4340250664) 51 ??? 0x1ba496ec8 (Missing)
0
0
530
Jan ’25
SwiftUI TabVIew Faulting while switching between Tabs
I'm working on a SwiftUI based application for MacOS. I have a TabView component with two child Tab components. These Tab components display a List, each derived from an array of elements. While the application is running, clicking on the tabs in the TabView should switch between the views of different Lists. What I'm experiencing is that switching between the tabs causes a FAULT. With errors: Row index 1 out of row range (numberOfRows: 1) for <SwiftUI.SwiftUIOutlineListView: 0x1299d2000> Followed by: ( 0 CoreFoundation 0x000000019e096e80 __exceptionPreprocess + 176 1 libobjc.A.dylib 0x000000019db7ecd8 objc_exception_throw + 88 2 AppKit 0x00000001a1c744e8 -[NSTableRowData _availableRowViewWhileUpdatingAtRow:] + 0 3 SwiftUI 0x00000001cd8953f4 $s7SwiftUI0A17UIOutlineListViewC11removeItems2at8inParent13withAnimationy10Foundation8IndexSetV_ypSgSo07NSTableeL7OptionsVtF + 1232 ... ... ) And finally: FAULT: NSTableViewException: Row index 1 out of row range (numberOfRows: 1) for <SwiftUI.SwiftUIOutlineListView: 0x1299d2000>; (user info absent) This error happens when switching between the two tabs, defined thusly: @main struct MyApp: App { @State var rootDirectory: URL @State var selectedItem: URL @State var projectNavItems: [NavigationItem] = [] @State var jotNavItems: [NavigationItem] = [] @State var importerIsPresented: Bool = false let fileManager = FileManager.default init() { rootDirectory = URL(string: FileManager.default.currentDirectoryPath)! selectedItem = URL(string: FileManager.default.currentDirectoryPath)!.appendingPathComponent("README.md") } var body: some Scene { WindowGroup { NavigationSplitView { TabView { Tab("Projects", systemImage: "tray.and.arrow.down.fill") { List(projectNavItems, selection: $selectedItem) { // Changing this NavigationLink line to Text($0.title) makes no difference NavigationLink($0.title, value: $0.id) } } Tab("Jots", systemImage: "tray.and.arrow.up.fill") { List(jotNavItems, selection: $selectedJot) { // Can be written as Text($0.title) with no change in behavior NavigationLink($0.title, value: $0.id) } } } } detail: { Editor(for: selectedItem) } .fileImporter( isPresented: $importerIsPresented, allowedContentTypes: [UTType.folder], allowsMultipleSelection: false ) { result in // Code that gets a security scoped resource and populates the // projectNavItems: [NavItem] and jotNavItems: [NavItem] // arrays } } .commands(content: { CommandGroup (before: .newItem) { Button("Open Journal...") { importerIsPresented.toggle() } } }) } } The error only happens when both Tab views are populated by a List. If the Tab view have different child components, say a List, and a ForEach of Text components, switching between the tabs doesn't produce this error. List views with Text child components also produce this error. Here are screenshots of the running application Once the user selects a directory, we see the first Tab > List component populated by contents from the projectNavItems array: Clicking on the 'Jots' tab switches to the appropriate tab and correctly lists the items in the jotNavItems array, except there are additional lines, seemingly showing that there's an issue. Clicking back on the 'Projects' tab switches back, but now the List shows only one of the items from the projectNavItems array. Finally, clicking on 'Jots' again causes the errors to print in the console and interactivity with the tab components ceases. Last screenshot is representative of this state as the application FAULTS. This seems like a bug in SwifUI, wondering what workarounds I might be able to implement. I can provide the full backtrace, I cropped it for content length.
2
0
424
Jan ’25
Swift UI , Buttons change appearance when pressed.
I have a calculator app with lots of buttons. Some of the buttons change appearance when pressed. Others do not. Some of those that do not change the state of a display text field and others do not. The display change is that the button goes white when pressed. I have no explicit code to make a change in appearance in any of the buttons. The display consists of a TextField followed by 4 rows of 6 buttons followed by 4 rows of 6 buttons. What is the explanation for this behavior.
Topic: UI Frameworks SubTopic: SwiftUI
2
0
205
Jan ’25
App Clip No Available
1.APPStore Arraignment passed. Not yet released. The diagnostic link configuration is not available. Firstly,We filled in the configuration of the corresponding domain name, and the verification was successful. My AASA file is configured correctly (general deep links work with it, as well as some app clip URLs) and is also configured for app clips. "applinks": { "apps": [], "details": [ { "appID": "xxx.com.xx.easyshare", "paths": [ "*" ] }, { "appID": "xxx.com.xx.easyshareExport", "paths": [ "*" ] } ] }, "appclips": { "apps": [ "xxx.com.xx.easyshare.Clip" ] } } Well,I used https://es.xx.com/send or https://es.xx.com to get diagnostic information is wrong My TestFight config is ok Another problem is that using NFT jumps directly to Safire.
1
0
338
Jan ’25
Unable to Use DeviceActivityReport to Show Screen Time in App
Hi team. I am working on an app that uses the Screen Time API. I got access to the family controls (distribution) capability through the request process for my main app. I added a DeviceActivityReport extension in XCode, but haven't been able to get the extension to show up on the screen. I noticed that the extension only has the development version of the family controls capability available. Is this the source of my errors? I was able to get the screen time displayed in a test app I built where both the main app and extension used the development version of the capability, which led me to believe that discrepancy could be the issue. Let me know if there is anything I can provide to help in the debugging process. I didn't send a minimal example in this request due to the fact that I would have to remove most of my functionality to create a "minimal" example (since the signing is only for my main app), but I can do that if needed. Thanks! I looked through the logs in the console for the phone (I'm testing on a real iPhone 13 Pro Max), but didn't see anything that popped out after looking (not exactly sure what to look for though). STEPS TO REPRODUCE: Create an app with the Family Controls, Distribution capability. Then create the DeviceActivityReport with the Family Control, Development capability. Attempt to see the DeviceActivityReport in the main app. NOTE: I was successfully able to create a minimal test app completely separately that used the Development versions of the capabilities for both with the exact same extension code. That's why I think the issue could be due to the capability version discrepancy.
5
0
400
Jan ’25
Keyboard will not show when setting focus on a SwiftUI text field from a button in an ornament on visionOS
Using a button that is placed in the bottom ornament to set focus on a text field will not display the keyboard properly while a button embedded in the view will behave as expected. To demonstrate the issue, simply run the attached project on Vision Pro with visionOS 1.1 and tap the Toggle 2 button in the bottom ornament. You’ll see that the field does have focus but the keyboard is now visible. Run the same test with Toggle 1 and the field will get focus and the keyboard will show as expected. import SwiftUI import RealityKit import RealityKitContent struct ContentView: View { @State private var text = "" @State private var showKeyboard = false @FocusState private var focusedField: FocusField? private enum FocusField: Hashable { case username case password } var body: some View { VStack { TextField("Test", text: $text) .focused($focusedField, equals: .username) Text("Entered Text: \(text)") .padding() Button("Toggle 1") { // This button will work and show the keyboard if focusedField != nil { focusedField = nil } else { focusedField = .username } } Spacer() } .padding() .toolbar { ToolbarItem(placement: .bottomOrnament) { Button("Toggle 2") { // This button will set focus properly but not show the keyboard if focusedField != nil { focusedField = nil } else { focusedField = .username } } } } } } Is there a way to work around this? FB13641609
1
0
757
Jan ’25
SwiftUI and UIImage memory leak
I’m experiencing significant performance and memory management issues in my SwiftUI application when displaying a large number of images using LazyVStack within a ScrollView. The application uses Swift Data to manage and display images. Here’s the model I’m working with: @Model final class Item { var id: UUID = UUID() var timestamp: Date = Date.now var photo: Data = Data() init(photo: Data = Data(), timestamp: Date = Date.now) { self.photo = photo self.timestamp = timestamp } } extension Item: Identifiable {} The photo property is used to store images. However, when querying Item objects using Swift Data in a SwiftUI ScrollView, the app crashes if there are more than 100 images in the database. Scrolling down through the LazyVStack loads all images into memory leading to the app crashing when memory usage exceeds the device’s limits. Here’s my view: A LazyVStack inside a ScrollView displays the images. struct LazyScrollView: View { @Environment(\.modelContext) private var modelContext @State private var isShowingPhotosPicker: Bool = false @State private var selectedItems: [PhotosPickerItem] = [] @Query private var items: [Item] var body: some View { NavigationStack { ScrollView { LazyVStack { ForEach(items) { item in NavigationLink { Image(uiImage: UIImage(data: item.photo)!) .resizable() .scaledToFit() } label: { Image(uiImage: UIImage(data: item.photo)!) .resizable() .scaledToFit() } } } } .navigationTitle("LazyScrollView") .photosPicker(isPresented: $isShowingPhotosPicker, selection: $selectedItems, maxSelectionCount: 100, matching: .images) .onChange(of: selectedItems) { Task { for item in selectedItems { if let data = try await item.loadTransferable(type: Data.self) { let newItem = Item(photo: data) modelContext.insert(newItem) } } try? modelContext.save() selectedItems = [] } } } } } Based on this: How can I prevent SwiftUI from loading all the binary data (photo) into memory when the whole view is scrolled until the last item? Why does SwiftUI not free memory from the images that are not being displayed? Any insights or suggestions would be greatly appreciated. Thank you! I will put the full view code in the comments so anyone can test if needed.
2
0
691
Jan ’25
How to initialize @Observable object in View via @State?
When I switched to observable, I noticed a strange behavior of the ViewModel. The ViewModel is created 3x times. And my question is: How to properly initialize the ViewModel via state? Below is a minimal example with log output: ViewModel INIT : EBBB2C41 ViewModel INIT : D8E490DA ViewModel INIT : 54407300 ViewModel DEINIT: D8E490DA @Observable final class ViewModel { @ObservationIgnored let idd: UUID init() { idd = UUID() print("ViewModel INIT : \(idd.uuidString.prefix(8))") } deinit { print("ViewModel DEINIT: \(idd.uuidString.prefix(8))") } } struct SimpleView: View { @Environment(ViewModel.self) private var viewModel var body: some View { @Bindable var viewModel = viewModel Text("SimpleView: \(viewModel.idd.uuidString.prefix(8))") } } struct ContentView: View { @State private var viewModel = ViewModel() var body: some View { SimpleView() .environment(mainViewModel) } }
1
0
412
Feb ’25
SwiftUI: toolbar jump weirdly in AppleWatch
Here is the reproducible codes: struct JumpView: View { var body: some View { NavigationStack { TabView { Text("Jump") .toolbar { ToolbarItem(placement: .topBarLeading) { Button("Done") {} } } } } } } Run directly in real apple watch device in watchOS 10.0+ (do not debug connecting with Xcode). When raise your wrist the ToolBar Button will jump weirdly.
1
0
372
Feb ’25
SwiftUI PKCanvasView bounds
I am creating a Bible app with SwiftUI using Text in the background and a PKCanvasView in the front to mark the text and take notes. The user can modify the font and its size and you can navigate to different books and chapters. Each chapter's text has a different size causing the PKCanvasView to have varying sizes. The width of the canvas is always the same but the height changes based on these parameters I just mentioned. If the chapter is long and the height of the canvas exceeds 4000 or some settings cause the text to make the views bound to go beyond 4000, the drawing will enlarge or appear to be occurring in a different location than my pencil. As soon as I lift my pencil, the drawing snaps to the place it belongs. var body: some View { HStack(spacing: 0) { // Main content container ScrollView { ZStack { // Text content VStack { if let chapter = viewModel.currentChapterText { HStack { Text(AttributedString(chapter.html(fontName: fontName, fontSize: fontSize, showVerses: showVerse, showFootnotes: showFootnotes))) .padding() .frame(width: textWidth, alignment: .leading) Color.clear } .frame(width: canvasWidth) } else { Text("Select a book to begin reading") .foregroundColor(.gray) } } // Drawing canvas overlay if showingDrawingTools { DrawingCanvasView( canvasView: $canvasView, toolPicker: toolPicker, frame: CGSize(width: deviceWidth, height: deviceHeight), onSave: saveDrawing ) } } } } .onChange(of: viewModel.currentChapter) { oldValue, newValue in print("BibleContentView - chapter text changed") } }
Topic: UI Frameworks SubTopic: SwiftUI
2
0
269
Jan ’25
Monintoring Picture in Picture is hide in Device Edge.
I am developing a custom Picture in Picture (PiP) app that plays videos. The video continues to play even when the app goes to the background, but I would like to be able to get the bool value when the PiP is hidden on the edge, as shown in the attached image. The reason why we need this is because we don't want the user to consume extra network bandwidth, so we want to pause the video when the PiP is hidden on the edge of the screen. Please let me know if this is possible. This can be done in the foreground or in the background.
1
0
339
Jan ’25
Bidirectional Text Rendering Issue in Swift UILabel for Arabic
I'm encountering an issue displaying a large HTML string (over 11470 characters) in a UILabel. Specifically, the Arabic text within the string is rendering left-to-right instead of the correct right-to-left direction. I've provided a truncated version of the HTML string and the relevant code snippet below. I've tried setting the UILabel's text alignment to right, but this didn't resolve the issue. Could you please advise on how to resolve this bidirectional text rendering problem? The results of the correct and incorrect approaches are shown in the image below. Here's the relevant Swift code: let labelView: UILabel = { let label = UILabel() label.textAlignment = .right label.translatesAutoresizingMaskIntoConstraints = false label.numberOfLines = 0 label.semanticContentAttribute = .forceRightToLeft label.backgroundColor = .white label.lineBreakMode = .byWordWrapping return label }() //Important!! //It must exceed 11470 characters. let htmlString = """ &lt;p style=\"text-align: center;\"&gt;&lt;strong&gt;İSTİÂZE&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Nahl sûresindeki:&lt;/p&gt; &lt;p dir="rtl" lang="ar"&gt; فَاِذَا قَرَاْتَ الْقُرْاٰنَ فَاسْتَعِذْ بِاللّٰهِ مِنَ الشَّيْطَانِ الرَّج۪يمِ &lt;/p&gt; &lt;p&gt;&lt;strong&gt;“&lt;/strong&gt;&lt;strong&gt;Kur’an okuyacağın zaman kovulmuş şeytandan hemen Allah’a sığın!&lt;/strong&gt;&lt;strong&gt;”&lt;/strong&gt; (Nahl 16/98) emri gereğince Kur’ân-ı Kerîm okumaya başlarken:&lt;/p&gt; &lt;p dir="rtl" lang="ar"&gt;اَعُوذُ بِاللّٰهِ مِنَ الشَّيْطَانِ الرَّج۪يمِ&lt;/p&gt; &lt;p&gt;&lt;em&gt;“Kovulmuş şeytandan Allah’a sığınırım” &lt;/em&gt;deriz. Bu sözü söylemeye “istiâze&lt;em&gt;” denilir. “Eûzü”&lt;/em&gt;, sığınırım, emân dilerim, yardım taleb ederim, gibi anlamlara gelir. It must exceed 11470 characters.&lt;/p&gt; “”” if let data = htmlString.data(using: .utf8) { let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [ .documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue ] do { let attributedString = try NSAttributedString(data: data, options: options, documentAttributes: nil) labelView.attributedText = attributedString } catch { print("HTML string işlenirken hata oluştu: \(error)") } } I'm using iOS 18.2 and Swift 6. Any suggestions on how to correct the bidirectional text rendering?
0
0
376
Jan ’25
Explanation of DynamicProperty's update func in SwiftUI
Could an Apple employee that works on SwiftUI please explain the update() func in the DynamicProperty protocol? The docs have ambiguous information, e.g. "Updates the underlying value of the stored value." and "SwiftUI calls this function before rendering a view’s body to ensure the view has the most recent value." From: https://developer.apple.com/documentation/swiftui/dynamicproperty/update() How can it both set the underlying value and get the most recent value? What does underlying value mean? What does stored value mean? E.g. Is the code below correct? struct MyProperty: DynamicProperty { var x = 0 mutating func update() { // get x from external storage x = storage.loadX() } } Or should it be: struct MyProperty: DynamicProperty { let x: Int init(x: Int) { self.x = x } func update() { // set x on external storage storage.save(x: x) } } This has always been a mystery to me because of the ambigious docs so thought it was time to post a question.
Topic: UI Frameworks SubTopic: SwiftUI
0
0
218
Jan ’25
NSTextField Delegates Not Triggering After Refactoring NSView to NSViewController in macOS App
I'm developing a macOS application and facing an issue with NSTextField delegates after refactoring my code. Here's the situation: I have an NSWindowController. Inside the NSWindowController, there's a container NSView named containerView. On top of containerView, I added a custom NSView subclass named MyDetailsView. MyDetailsView has two NSTextField instances, and their delegates are properly set. The delegate methods like controlTextDidChange(_:) were getting called as expected. Due to some additional requirements, I refactored MyDetailsView into MyDetailsViewController, a subclass of NSViewController. I created a corresponding .xib file for MyDetailsViewController. Updated the code to load and add MyDetailsViewController's view (view property) to containerView. Verified that the NSTextField delegates are still being set, and the fields are displayed correctly in the UI. However, after this refactor, the NSTextField delegate methods (e.g., controlTextDidChange(_:)) are no longer being triggered. **What I've Tried: ** Verified that the delegates for the NSTextField instances are correctly set after the refactor. Ensured that the MyDetailsViewController's view is added to containerView. Question: What could be causing the NSTextField delegate methods to stop working after refactoring from NSView to NSViewController? @IBOutlet weak var customeView: NSView! var myDetailsViewController: MyDetailsViewController! var myDetailsView: MyDetailsView! var isViewController: Bool = true override func windowDidLoad() { super.windowDidLoad() if isViewController { myDetailsViewController = MyDetailsViewController(nibName: "MyDetailsViewController", bundle: nil) self.customeView.addSubview(myDetailsViewController.view) } else { myDetailsView = MyDetailsView.createFromNib() self.customeView.addSubview(myDetailsView!) } } override func showWindow(_ sender: Any?) { super.showWindow(nil) window?.makeKeyAndOrderFront(nil) } override var windowNibName: NSNib.Name? { return NSNib.Name("MyWindowController") }} class MyDetailsViewController: NSViewController { @IBOutlet weak var textField: NSTextField! override func viewDidLoad() { super.viewDidLoad() // Do view setup here. } } extension MyDetailsViewController: NSTextDelegate { func controlTextDidChange(_ obj: Notification) { guard let textField = obj.object as? NSTextField else { return } print("The value is ----> (MyDetailsViewController) \(textField.stringValue)") } } TextField delegate is set in XIB.
Topic: UI Frameworks SubTopic: AppKit Tags:
0
0
394
Dec ’24
Is it possible to make GeometryReader less vertically greedy?
I must be missing something here. I want to put a landscape image in a geometry reader that contains a ZStack that contains an image and an overlay centred on top of the Image. I would like the ZStack and GeoReader's sizes to be the size of Image. (ie I want geometry.size to be the size of the image, which can be used to control the offset of the overlay's position.) Unfortunately the ZStack also includes the space above the image (ie the top safeArea) and the GeometryReader also includes all the space below the Image. (so geometry.size.height is greater than the height of Image) I've gone down rabbit holes of adding other items above/below, but I don't seem to be able to prevent the GeometryReader from being vertically greedy. eg the Text(" ") above the ZStack in the VStack solves the ZStack claiming the top safe area. But adding Text(" ") below the ZStack does not prevent the GeometryReader from claiming more vertical space below the image. Any/all guidance greatly appreciated. struct ContentView: View { var body: some View { VStack { // Text(" ") GeometryReader { geometry in ZStack { Image( uiImage: .init(imageLiteralResourceName: "LandscapeSample") ) .resizable() .aspectRatio(contentMode: .fit) Text("Hello, world!") .background(.white) } .background(.red) } .background(.blue) // Text(" ") } } }
2
0
450
Jan ’25