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

Retrieve input field text as a keyboard extension in Swift
I am able to retrieve the text in the input field by doing: let contextBeforeInput = textDocumentProxy.documentContextBeforeInput ?? "" let contextAfterInput = textDocumentProxy.documentContextAfterInput ?? "" let fullText = contextBeforeInput + contextAfterInput However, when I'm pasting text into the input field, textDocumentProxy.documentContextBeforeInput refuses to return the entire text from the input field but instead only returns the last two sentences. I have tried this with the input fields in WhatsApp, Signal, and Telegram and it's all the same, so it doesn't seem to be caused by the specific app. At first I thought it was a limitation imposed by Apple but other third party keyboard extensions such as Grammarly are able to pick up the whole pasted text from the input field, so how are they doing it?
Topic: UI Frameworks SubTopic: UIKit
0
0
225
Jan ’25
SwiftUI infinite rendering loop when using a custom Binding to a dictionary-based store
I’m building a SwiftUI app where the struct AppGroup is identified by a UUID and stored in a dictionary. My Task model has appGroupId: UUID?. In TaskDetailView, I create a custom Binding<AppGroup> from the store, then navigate to AppGroupDetailView. However, when I tap the NavigationLink, the console spams logs, CPU hits 100%, and it never stabilizes. Relevant Code AppGroupStore (simplified) class AppGroupStore: ObservableObject { @Published var appGroupsDict: [UUID: AppGroup] = [:] func updateAppGroup(_ id: UUID, appGroup: AppGroup) { appGroupsDict[id] = appGroup } // Returns a binding so views can directly read/write the AppGroup by id func getBinding(withId id: UUID?) -> Binding<AppGroup> { Binding( get: { if let id = id { return self.appGroupsDict[id] ?? .empty } return .empty }, set: { newValue in print("New value set for \(newValue.name)") self.updateAppGroup(newValue.id, appGroup: newValue) } ) } // ... } AppGroup is a simple struct: struct AppGroup: Identifiable, Codable { let id: UUID var name: String var apps: [String] static let empty = AppGroup(id: UUID(), name: "Empty", apps: []) } TaskDetailView (main part) struct TaskDetailView: View { @Binding var task: ToDoTask // has task.appGroupId: UUID? @EnvironmentObject var appGroupStore: AppGroupStore var body: some View { let appGroup = appGroupStore.getBinding(withId: task.appGroupId) print("Task load") // prints infinitely, CPU 100% return List { // ... NavigationLink(destination: AppGroupDetailView(appGroup: appGroup)) { Text(appGroup.wrappedValue.name) } } .navigationTitle(task.name) } } AppGroupDetailView (simplified) struct AppGroupDetailView: View { @Binding var appGroup: AppGroup // ... var body: some View { List { ForEach(appGroup.apps, id: \.self) { app in Text(app) } } .navigationTitle(appGroup.name) } } Symptoms: Tapping the NavigationLink leads to infinite “Task load” logs and 100% CPU usage. The set closure (“New value set for...”) is never called, so it’s not repeatedly writing. If I replace the Binding<AppGroup> with a read-only approach (just accessing the dictionary), it does not get stuck. Question: What might cause SwiftUI to keep re-rendering the body indefinitely, even if my custom get closure doesn’t explicitly mutate the state? Are there known pitfalls when using a dictionary-based store and returning a Binding like this? Any help is much appreciated! Thanks in advance for your insights!
0
0
227
Jan ’25
Widget with dynamic property and clearing the option.
I have a widget with a dynamic property. I'm able to provide the options to the widget edit ui and the user can make their selection .. which filters what data gets shown in the widget. My use case is when the user goes back to the main app and deletes the option that is currently selected. Currently, the widget keeps that selection. How can I get the widget to clear that selection and show the defaultResult() from the EntityQuery?
0
0
254
Dec ’24
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
510
Jan ’25
iOS 18 crash issue for unnecessary dequeuing
My code extension MyViewController: UICollectionViewDelegate, UICollectionViewDataSource { func collectionView( _ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath ) -> UICollectionViewCell { if let cell = collectionView.dequeueReusableCell( withReuseIdentifier: "CollectionViewCellID", for: indexPath ) as? CollectionViewCell { cell.setup() return cell } return UICollectionViewCell() } func collectionView( _ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath ) { // Unnecessary dequeue guard collectionView.dequeueReusableCell( withReuseIdentifier: "CollectionViewCellID", for: indexPath ) is CollectionViewCell else { return } // My action for selecting cell print("Cell Selected") } } Error: *** Assertion failure in -[UICollectionView _updateVisibleCellsNow:], UICollectionView.m:5673 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Expected dequeued view to be returned to the collection view in preparation for display. When the collection view's data source is asked to provide a view for a given index path, ensure that a single view is dequeued and returned to the collection view. Avoid dequeuing views without a request from the collection view. For retrieving an existing view in the collection view, use -[UICollectionView cellForItemAtIndexPath:] or -[UICollectionView supplementaryViewForElementKind:atIndexPath:]. Solution: The problem was doing unnecessary dequeuing in didSelectItemAt when selecting the cell. In previous iOS like 17 or 16 or lower, it was allowed to dequeue where it is not really needed but from iOS 18, it may restricted to unnecessary dequeuing. So better to remove dequeue and use cellForItem(at) if we need to get cell from collection view. Example extension MyViewController: UICollectionViewDelegate, UICollectionViewDataSource { func collectionView( _ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath ) -> UICollectionViewCell { if let cell = collectionView.dequeueReusableCell( withReuseIdentifier: "CollectionViewCellID", for: indexPath ) as? CollectionViewCell { cell.setup() return cell } return UICollectionViewCell() } func collectionView( _ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath ) { guard collectionView.cellForItem(at: indexPath) is CollectionViewCell else { return } // My action for selecting cell print("Cell Selected") } }
0
0
3.6k
Dec ’24
iOS18 UIPinchGestureRecognizer finger change
Before ios18, when two fingers are switched to single fingers, the printing scale value will not change. When switching to two fingers again, the pinch and zoom printing scale will change. The same operation is performed after ios18, and two fingers are switched to single fingers. Switch back to two fingers, and the scale printing will not change. code here: - (void)pinchGesture:(UIPinchGestureRecognizer *)recognizer { NSSet <UIEvent*> *events = [recognizer valueForKey:@"_activeEvents"]; UIEvent *event = [events anyObject]; if (recognizer.state == UIGestureRecognizerStateBegan) { NSLog(@"---- begin finger count: %d scale: %f",event.allTouches.count,recognizer.scale); recognizer.scale = 1.0; } else if (recognizer.state == UIGestureRecognizerStateChanged) { NSLog(@"---- change finger count: %d scale: %f",event.allTouches.count,recognizer.scale); // recognizer.scale = 1.0; } log image for iOS 17.7 log image for ios18.0.2
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
279
Jan ’25
*** -colorSpaceName not valid
Here is a relatively simple code fragment: let attributedQuote: [NSAttributedString.Key: Any] = [ .font: FieldFont!, .foregroundColor: NSColor.red] let strQuote = NSAttributedString.init(string:"Hello World", attributes:attributedQuote) strQuote.draw(in: Rect1) It compiles without an issue, bur when I execute it, I get: "*** -colorSpaceName not valid for the NSColor <NSColor: 0x6000005adfd0>; need to first convert colorspace." I have tried everything I can think of. What's going on?
0
1
373
Jan ’25
UIDocumentPickerViewController directoryURL no longer opening correct folder
Since iOS 18, I have gotten user reports that the UIDocumentPickerViewController directoryURL is no longer opening the correct folder. Instead it is just loading the root directory of the Files app/iCloud files. Did something change in iOS 18 that I need to account for? Not all users are having this issue, but some are and they are frustrated because a major feature of my app was to allow users to save files at the ubiquityURL. I use the following to get the path: NSURL *rootDirectory = [[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil] URLByAppendingPathComponent:[NSString stringWithFormat:@"Documents/Photos/%@", folderName]]; Is there something that I need to do differently now in iOS 18 to prevent this from happening?
0
1
471
Dec ’24
view controller life cycle bug in xcode 16 ios 18
hi does any one know if there changes in lifecycle in xcode 16 ios 18 cause i notice that my view will appear does what view didappear use to do in older version and it kind of a problem cause all the rest of ios work diffrently does anyone else found a problem with it? or does anyone know if there was a known change to life cycles
0
0
413
Jan ’25
WatchOS SwiftUI List edit mode / Control Center
The WatchOS Control Center has an Edit/Done button at the bottom, and in its edit mode, elements can be moved around and added/removed. Yet, the SwiftUI List doesn't have an edit mode on WatchOS. My question is: is the edit functionality in Control Center a custom thing, or is that present in some SwiftUI component that I've missed?
0
0
467
Dec ’24
looking for sample code 3d wireframe (with lines ) & polygons
Looking for sample code 3d wireframe (with lines ) & polygons and should be able to rotate (set camera angles) I tried sample code seems to be complicated & getting a BLANK screen import SwiftUI import SceneKit struct SceneKitTest2: View { var body: some View { VStack{ Text("SceneKitTest2") SceneView(scene: SCNScene(named:"Earth_1_12756.scn"), options: [.autoenablesDefaultLighting,.allowsCameraControl]) .frame(width:UIScreen.main.bounds.width, height: UIScreen.main.bounds.height/2) Spacer(minLength: 0) } } }
0
0
386
Jan ’25
SwiftUI crashed on iOS16 when use List with .animation
When I use the following code List { ForEach(data.items, id: \.knowledgeInfo.mediaID) { item in SelectableKnowledgeListItem(knowledgeData: item, baseID: data.knowledgeBaseID, isSelectionMode: $isSelectionMode, selectedItems: $selectedItems) .KnowledgeListItemStyle() } // 添加底部加载更多 if !data.isEnd && !isRefreshing { ProgressView() .frame(maxWidth: .infinity, alignment: .center) .onAppear { self.isRefreshing = true manager.getKnowledgeList(knowledgeBaseID: data.knowledgeBaseID, completion: { self.isRefreshing = false }) } } } .animation(.interactiveSpring) .scrollContentBackground(.hidden) .environment(\.defaultMinListHeaderHeight, 7) The number of Views rendered in the List remains unchanged after he adds an item to data.items (data is an ObservedObject, items is Published) at runtime.When I removed .animation(.interactiveSpring), it would be processed normally.And if I perform a delete operation after adding, it will cause a crash. *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections. The number of sections contained in the collection view after the update (11) must be equal to the number of sections contained in the collection view before the update (10), plus or minus the number of sections inserted or deleted (1 inserted, 1 deleted).
Topic: UI Frameworks SubTopic: SwiftUI
0
0
182
Dec ’24
TabView with ScrollView: scroll position ID not updating when tapping Tab item
When working with SwiftUI TabView and ScrollView at root level with scrollPosition(id:anchor:), after tapping on Tab item the ScrollView scrolls to the top, but the scroll position ID does not get updated. struct ContentView: View { @State var positionID: Int? var body: some View { TabView { Tab("Test", systemImage: "house") { ScrollView(.vertical) { LazyVStack(pinnedViews: [.sectionHeaders]) { ForEach(0 ... 100, id: \.self) { index in Text("\(index)") } } .scrollTargetLayout() } .scrollPosition(id: $positionID, anchor: .top) .onChange(of: positionID) { _, newValue in print(newValue) } } } } } FB15964820
0
0
566
Dec ’24
Application threw exception NSInternalInconsistencyException: Multi layer delegate table missing.
I recently detected a special crash on 18.0, 18.1, 18.1.1, 18.2,18.3 which cannot be repeated, and the page logs are related to the keyboard, is there any idea to deal with this problem? Exception Category: nsexception Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x00000000 at 0x0000000000000000 Crashed Thread: 0 CrashDoctor Diagnosis: Application threw exception NSInternalInconsistencyException: Multi layer delegate table missing. Thread 0 Crashed: 0 CoreFoundation 0x00000001869d87cc __exceptionPreprocess + [ : 164] 1 libobjc.A.dylib 0x0000000183cab2e4 objc_exception_throw + [ : 88] 2 Foundation 0x0000000185da88d8 _userInfoForFileAndLine 3 UIKitCore 0x0000000189e78074 -[UIView _multiLayerDelegatesTableCreateIfNecessary:] + [ : 208] 4 UIKitCore 0x0000000189e780c4 -[UIView _registerMultiLayerDelegate:] + [ : 36] 5 UIKitCore 0x00000001894874c0 -[_UIPortalView setSourceView:] + [ : 132] 6 UIKitCore 0x000000018a1eb6bc -[_UIPortalView initWithSourceView:] + [ : 68] 7 UIKitCore 0x000000018a213ea4 -[_UITextMagnifiedLoupeView initWithSourceView:] + [ : 444] 8 UIKitCore 0x000000018a6c461c +[UITextLoupeSession _makeLoupeViewForSourceView:selectionWidget:orientation:] + [ : 84] 9 UIKitCore 0x000000018a6c47bc +[UITextLoupeSession _beginLoupeSessionAtPoint:fromSelectionWidgetView:inView:orientation:] + [ : 304] 10 UIKitCore 0x0000000189d50ce0 -[UITextRefinementTouchBehavior textLoupeInteraction:gestureChangedWithState:location:translation:velocity:modifierFlags:shouldCancel:] + [ : 1756] 11 UIKit 0x0000000240e309e0 -[UITextRefinementTouchBehaviorAccessibility textLoupeInteraction:gestureChangedWithState:location:translation:velocity:modifierFlags:shouldCancel:] + [ : 216] 12 UIKitCore 0x000000018a4d45b4 -[UITextRefinementInteraction loupeGestureWithState:location:translation:velocity:modifierFlags:shouldCancel:] + [ : 124] 13 UIKitCore 0x000000018a4d3f74 -[UITextRefinementInteraction loupeGesture:] + [ : 548] 14 UIKitCore 0x000000018952eac4 -[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:] + [ : 128] 15 UIKitCore 0x000000018952e934 _UIGestureRecognizerSendTargetActions + [ : 92] 16 UIKitCore 0x000000018952e6f4 _UIGestureRecognizerSendActions + [ : 284] 17 UIKitCore 0x00000001891e1b28 -[UIGestureRecognizer _updateGestureForActiveEvents] + [ : 572] 18 UIKitCore 0x00000001891b3724 _UIGestureEnvironmentUpdate + [ : 2488] 19 CoreFoundation 0x000000018697a1f4 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + [ : 36] 20 CoreFoundation 0x0000000186979f98 __CFRunLoopDoObservers + [ : 552] 21 CoreFoundation 0x00000001869a9028 __CFRunLoopRun + [ : 948] 22 CoreFoundation 0x00000001869a8830 CFRunLoopRunSpecific + [ : 588] 23 GraphicsServices 0x00000001d29881c4 GSEventRunModal + [ : 164] 24 UIKitCore 0x000000018950eeb0 -[UIApplication _run] + [ : 816] 25 UIKitCore 0x00000001895bd5b4 UIApplicationMain + [ : 340] 26 顺丰小哥 0x0000000104423cc0 main + [main.m : 13] 27 (null) 0x00000001ac396ec8 0x0 + 7184412360
Topic: UI Frameworks SubTopic: UIKit
0
0
275
Dec ’24
the ID [":"] occurs multiple times within the collection, this will give undefined results!
Hi! After upgrading to Xcode 16.1 my watchOS app is getting below error using a DatePicker configured with: displayedComponents: .hourAndMinute. I cannot find a solution for this error/warning. It only appears when im using : .hourAndMinute or : .hourAndMinuteandSeconds, but not .date. Note! My code is unchanged only change I Xcode upgrade. Any suggestions? ForEach<Array, Array, _ConditionalContent<_ConditionalContent<_ConditionalContent<_ConditionalContent<YearPicker, MonthPicker>, _ConditionalContent<DayPicker, ComponentPicker>>, _ConditionalContent<_ConditionalContent<ComponentPicker, ComponentPicker>, _ConditionalContent<AMPMPicker, ModifiedContent<Text, _PaddingLayout>>>>, EmptyView>>: the ID [":"] occurs multiple times within the collection, this will give undefined results! import SwiftUI import WidgetKit struct TimeEditView: View { let title: String @Binding var storedValue: String var body: some View { Form { DatePicker( title, selection: Binding<Date>( get: { Date.from(storedValue) ?? Date() }, set: { newDate in storedValue = newDate.toString() } ), displayedComponents: .hourAndMinute ) .onChange(of: storedValue) { WidgetCenter.shared.reloadAllTimelines() print("Morning Start changed!") } } .navigationTitle(title) } }
0
0
284
Dec ’24
UIColor labelColor in macOS made-for-iPad app is not solid black
When my iOS app runs on macOS in "designed for iPad" mode, the system foreground colour RGBA values seem strange. Looking at [UIColor labelColor], [UIColor secondaryLabelColor] etc. on iOS, I see values like these: (Light Mode) // R G B A fg0 = 0 0 0 255 fg1 = 10 10 13 153 fg2 = 10 10 13 76 fg3 = 10 10 13 45 Note in particular that fg0, aka labelColor, is solid black. When I run it on my Mac, the values I see are: // R G B A fg0 = 0 0 0 216 fg1 = 0 0 0 127 fg2 = 0 0 0 66 fg3 = 0 0 0 25 Here, fg0 has alpha = 216. The result is that it looks like a dark grey, on a white background. Of course it's reasonable for macOS to have a different colour palette than iOS - but native macOS apps seem to have solid 100% black as their foreground colour. Do others see this? What should I be doing? Note that I'm getting colour values using UIColor's getRed: blue: green: alpha: method and then using these colour values for some custom GPU drawing. Previously I was using solid black and white, but at some point I updated it to use UIColor in order to respond to light/dark-mode changes.
0
0
414
Dec ’24
SwiftUI image has isAccessibilityElement == false
My SwiftUI app uses an Image with a tap gesture: Image(systemName: "xmark.circle.fill") .accessibilityIdentifier(kTextFieldClearButton) .foregroundColor(.secondary) .padding(.trailing, 6) .onTapGesture { dataSource.textFieldText = "" } In a UI test, I want to tap this image to execute its action: let clearButton = app.images[kTextFieldClearButton] clearButton.tap() However the action is not executed. I then set a breakpoint at clearButton.tap(), to execute lldb commands. Here are the results: (lldb) p clearButton.isHittable t = 439.54s Find the "TextFieldClearButton" Imag (Bool) true e It is a little strange that "Image" has been interrupted by (Bool) true, but the image is hittable. p clearButton.isAccessibilityElement gives (lldb) p clearButton.isAccessibilityElement (Bool) false I don't understand why this Image is no accessibility element. I thought, SwiftUI Views are by default accessible. What can I do to make it accessible so that clearButton.tap() works as expected?
0
0
477
Dec ’24