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

List does not move the view into focused element, when changing it with a keyboard
Here is a simple main.swift file of a macOS app: import SwiftUI struct ContentView: View { @State private var selectedItem = 0 @FocusState private var isListFocused: Bool var body: some View { List(0..<40, id: \.self, selection: $selectedItem) { index in Text("\(index)") .padding() .focusable() } .focused($isListFocused) .onAppear { isListFocused = true } } } func createAppWindow() { let window = NSWindow( contentRect: .zero, styleMask: [.titled], backing: .buffered, defer: false ) window.contentViewController = NSHostingController(rootView: ContentView()) window.setContentSize(NSSize(width: 759, height: 300)) window.center() window.makeKeyAndOrderFront(nil) } class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_ notification: Notification) { createAppWindow() } } let delegate = AppDelegate() NSApplication.shared.delegate = delegate NSApplication.shared.run() Try to move the focus with a keyboard slowly as shown on the GIF attached and you'll see that the focus items don't sit in a List's view.
2
0
320
Mar ’25
Remove bottom border in a row in AppKit's NSTableView
I just made a simple AppKit app, but don't know how to remove borders of rows when they're swiped. SwiftUI's list does not have this problem though. Attaching gif demo and code: import SwiftUI struct NSTableViewWrapper: NSViewRepresentable { @State var data: [String] class Coordinator: NSObject, NSTableViewDataSource, NSTableViewDelegate { var parent: NSTableViewWrapper weak var tableView: NSTableView? init(parent: NSTableViewWrapper) { self.parent = parent } func numberOfRows(in tableView: NSTableView) -> Int { self.tableView = tableView return parent.data.count } func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier("Cell"), owner: nil) as? NSTextField ?? NSTextField(labelWithString: "") cell.identifier = NSUserInterfaceItemIdentifier("Cell") cell.stringValue = parent.data[row] cell.isBordered = false return cell } func tableView(_ tableView: NSTableView, rowActionsForRow row: Int, edge: NSTableView.RowActionEdge) -> [NSTableViewRowAction] { guard edge == .trailing else { return [] } let deleteAction = NSTableViewRowAction(style: .destructive, title: "Delete") { action, index in self.deleteRow(at: index, in: tableView) } return [deleteAction] } private func deleteRow(at index: Int, in tableView: NSTableView) { guard index < parent.data.count else { return } NSAnimationContext.runAnimationGroup({ context in context.duration = 0.3 tableView.removeRows(at: IndexSet(integer: index), withAnimation: .slideUp) }, completionHandler: { DispatchQueue.main.async { self.parent.data.remove(at: index) tableView.reloadData() } }) } } func makeCoordinator() -> Coordinator { return Coordinator(parent: self) } func makeNSView(context: Context) -> NSScrollView { let scrollView = NSScrollView() let tableView = NSTableView() let column = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("Column")) column.width = 200 tableView.addTableColumn(column) tableView.delegate = context.coordinator tableView.dataSource = context.coordinator tableView.backgroundColor = .clear tableView.headerView = nil tableView.rowHeight = 50 tableView.style = .inset scrollView.documentView = tableView scrollView.hasVerticalScroller = true scrollView.additionalSafeAreaInsets = .init(top: 0, left: 0, bottom: 6, right: 0) return scrollView } func updateNSView(_ nsView: NSScrollView, context: Context) { (nsView.documentView as? NSTableView)?.reloadData() } } struct ContentView: View { @State private var itemsString = Array(0..<40).map(\.description) var body: some View { NSTableViewWrapper(data: itemsString) } } func createAppWindow() { let window = NSWindow( contentRect: .zero, styleMask: [.titled], backing: .buffered, defer: false ) window.title = "NSTableView from AppKit" window.contentViewController = NSHostingController(rootView: ContentView()) window.setContentSize(NSSize(width: 759, height: 300)) window.center() window.makeKeyAndOrderFront(nil) } class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_ notification: Notification) { createAppWindow() } } let delegate = AppDelegate() NSApplication.shared.delegate = delegate NSApplication.shared.run()
Topic: UI Frameworks SubTopic: AppKit Tags:
1
0
299
Mar ’25
Reliable APIs to check if a Hotkey/Shortcut is already in use?
In our application we have two usecases for a Hotkey/Shortcut identification API/method. We have some predefined shortcuts that will ship with our MacOS application. They may or may not change dynamically, based on what the user has already set as shortcuts/hotkeys, and also to avoid any important system wide shortcuts that the user may or may not have changed. We allow the user to customize the shortcuts/hotkeys in our application, so we want to show what shortcuts the user already has in use system-wide and across their OS experience. This gives rise to the need for an API that lets us know which shortcut/hotkeys are currently being used by the user and also the current system wide OS shortcuts in use. Please let me know if there are any APIs in AppKit or SwiftUI we can use for the above
0
0
289
Mar ’25
SwiftUI Tabview - how to "kill" the views we do not use
I have the MainView as the active view if the user is logged in(authenticated). the memory allocations when we run profile is pretty good. We have graphql fetching, we have token handling eg: This is All heap: 1 All Heap & Anonymous VM 13,90 MiB 65408 308557 99,10 MiB 373965 Ratio: %0.14, %0.86 After what i have checked this is pretty good for initialise and using multiple repositories eg. But when we change tabs: 1 All Heap & Anonymous VM 24,60 MiB 124651 543832 156,17 MiB 668483 Ratio: %0.07, %0.40 And that is not pretty good. So i guess we need to "kill" it or something. How? I have tried some techniques in a forum this was a recommended way: public struct LazyView<Content: View>: View { private let build: () -> Content @State private var isVisible = false public init(_ build: @escaping () -> Content) { self.build = build } public var body: some View { build() Group { if isVisible { build() } else { Color.clear } } .onAppear { isVisible = true } .onDisappear { isVisible = false } } } But this did not help at all. So under here is the one i use now. So pleace guide me for making this work. import DIKit import CoreKit import PresentationKit import DomainKit public struct MainView: View { @Injected((any MainViewModelProtocol).self) private var viewModel private var selectedTabBinding: Binding<MainTab> { Binding( get: { viewModel.selectedTab }, set: { viewModel.selectTab($0) } ) } public init() { // No additional setup needed } public var body: some View { NavigationStack(path: Binding( get: { viewModel.navigationPath }, set: { _ in } )) { TabView(selection: selectedTabBinding) { LazyView { FeedTabView() } .tabItem { Label("Feed", systemImage: "house") } .tag(MainTab.feed) LazyView { ChatTabView() } .tabItem { Label("Chat", systemImage: "message") } .tag(MainTab.chat) LazyView { JobsTabView() } .tabItem { Label("Jobs", systemImage: "briefcase") } .tag(MainTab.jobs) LazyView { ProfileTabView() } .tabItem { Label("Profile", systemImage: "person") } .tag(MainTab.profile) } .accentColor(.primary) .navigationDestination(for: MainNavigationDestination.self) { destination in switch destination { case .profile(let userId): Text("Profile for \(userId)") case .settings: Text("Settings") case .jobDetails(let id): Text("Job details for \(id)") case .chatThread(let id): Text("Chat thread \(id)") } } } } } import SwiftUI public struct LazyView<Content: View>: View { private let build: () -> Content public init(_ build: @escaping () -> Content) { self.build = build } public var body: some View { build() } }
0
0
215
Mar ’25
SwiftUI: How to change `contentInset` of `List`
Hi, Is there any way of changing the contentInset (UIKit variant) of a List in SwiftUI? I do not see any APIs for doing so, the closest I gotten is to use safeAreaInset . While visually that works the UX is broken as you can no longer "scroll" from the gap made by the .safeAreaInset(edge:alignment:spacing:content:) I have subbmited a feedback suggestion: FB16866956
0
0
184
Mar ’25
NavigationSplitView and NavigationPaths
A NavigationStack with a singular enum for .navigationDestination() works fine. Both NavigationLinks(value:) and directly manipulating the NavigationPath work fine for moving around views. Zero problems. The issue is when we instead use a NavigationSplitView, I've only dabbled with two-column splits (sidebar and detail) so far. Now, if the sidebar has its own NavigationStack, everything works nicely on an iPhone, but on an iPad, you can't push views onto the detail from the sidebar. (They're pushed on the sidebar) You can solve this by keeping a NavigationStack ONLY on the detail. Sidebar links now properly push onto the detail, and the detail can move around views by itself. However, if you mix NavigationLink(value:) with manually changing NavigationPath, it stops working with no error. If you only use links, you're good, if you only change the NavigationPath you're good. Mixing doesn't work. No error in the console either, the breakpoints hit .navigationDestination and the view is returned, but never piled up. (Further attempts do show the NavigationPath is being changed properly, but views aren't changing) This problem didn't happen when just staying on NavigationStack without a NavigationSplitView. Why mix? There's a few reasons to do so. NavigationLinks put the appropriate disclosure indicator (can't replicate its look 100% without it), while NavigationPaths let you trigger navigation without user input (.onChange, etc) Any insights here? I'd put some code samples but there's a metric ton of options I've tested here.
0
0
205
Mar ’25
Animation Issue: SwiftUI View Not Animating Height Changes in UIHostingController
Hello, I’m developing an app where I display a SwiftUI view inside a UIHostingController embedded within a UIKit ViewController. I’m trying to animate the height of the UIHostingController’s view based on a switch’s value, but the SwiftUI view doesn’t animate at all. Below is a simplified version of my code: class ViewController: UIViewController { private lazy var parentView: UIView = { let view = UIView() view.backgroundColor = .red view.translatesAutoresizingMaskIntoConstraints = false return view }() private lazy var hostingView: UIView = { let testView = TestView() let hostingController = UIHostingController(rootView: testView) let view = hostingController.view! view.translatesAutoresizingMaskIntoConstraints = false return view }() private lazy var button: UISwitch = { let button = UISwitch() button.addTarget(self, action: #selector(onClickSwitch(sender:)), for: .valueChanged) button.translatesAutoresizingMaskIntoConstraints = false return button }() private var hostingViewHeightConstraint: NSLayoutConstraint? override func viewDidLoad() { super.viewDidLoad() view.addSubview(parentView) parentView.addSubview(hostingView) parentView.addSubview(button) NSLayoutConstraint.activate([ parentView.topAnchor.constraint(equalTo: view.topAnchor), parentView.bottomAnchor.constraint(equalTo: view.bottomAnchor), parentView.leadingAnchor.constraint(equalTo: view.leadingAnchor), parentView.trailingAnchor.constraint(equalTo: view.trailingAnchor) ]) NSLayoutConstraint.activate([ hostingView.bottomAnchor.constraint(equalTo: parentView.bottomAnchor), hostingView.leadingAnchor.constraint(equalTo: parentView.leadingAnchor), hostingView.trailingAnchor.constraint(equalTo: parentView.trailingAnchor) ]) hostingViewHeightConstraint = hostingView.heightAnchor.constraint(equalTo: parentView.heightAnchor, multiplier: 0.5) hostingViewHeightConstraint?.isActive = true NSLayoutConstraint.activate([ button.centerXAnchor.constraint(equalTo: parentView.centerXAnchor), NSLayoutConstraint(item: button, attribute: .centerY, relatedBy: .equal, toItem: parentView, attribute: .centerY, multiplier: 0.25, constant: 0) ]) } @objc func onClickSwitch(sender: UISwitch) { hostingViewHeightConstraint?.isActive = false let multiplier: CGFloat = sender.isOn ? 0.25 : 0.5 hostingViewHeightConstraint = hostingView.heightAnchor.constraint(equalTo: parentView.heightAnchor, multiplier: multiplier) hostingViewHeightConstraint?.isActive = true UIView.animate(withDuration: 0.3) { self.view.layoutIfNeeded() } } } I’m looking for the behavior demonstrated in the video below: Does anyone have suggestions on how to achieve this?
0
1
200
Mar ’25
How to correctly and simply remove the edges of listStyle sidebar?
Hello, I've managed to get rid of these spaces in different ways. Using scrollview, giving negative insets, rewriting modifiers from scratch with plain style etc. But I couldn't solve this with a simple solution. I've read comments from many people experiencing similar problems online. It seems like there isn't a simple modifier to remove these spaces when we use sidebar as the list style in SwiftUI, or I couldn't find the simple solution. I wonder what's the simplest and correct way to reset these spaces? let numbers = Array(1...5) @State private var selected: Int? var body: some View { List(numbers, id: \.self, selection: $selected) { number in HStack { Text("Test") Spacer() } .frame(maxWidth: .infinity, alignment: .leading) } .listStyle(.sidebar) } }
0
0
193
Mar ’25
Syntax Highlighting with TextKit 2
Based on this TextKit 2 demo project I thought that I could implement syntax highlighting by parsing syntax block tokens (e.g. comments like <!-- --> or /* */) in processEditing and storing their locations, and then actually applying the rendering with NSTextContentStorageDelegate in textContentStorage(_:textParagraphWith:) by checking the location of each paragraph against the store of syntax tokens. This sort of works except that the rendering is only updated for paragraphs which are changed. Is there a way to trigger NSTextContentStorage to re-fetch paragraphs in a given range? Or is this a totally misguided approach to the problem?
Topic: UI Frameworks SubTopic: UIKit Tags:
2
0
785
Mar ’25
UINavigtionController as a child view leaves an unwanted gap
I have a situation where I need to add a UINavigationController as a child view controller within another view controller. When I do this, there is a gap between the bottom of the navigation controller's root view controller and the bottom of the navigation controller's own view. This happens even though I am constraining the navigation controller's view to the edges of its superview, not the safe areas. I'd really like to eliminate this gap, but nothing I have tried is working.
Topic: UI Frameworks SubTopic: UIKit Tags:
1
0
241
Mar ’25
How to truncate text from head with multi line?
I want to truncate text from head with max 2 lines. I try the following code import SwiftUI struct ContentView: View { @State var content: String = "Hello world! wef wefwwfe wfewe weweffwefwwfwe wfwe" var body: some View { VStack { Text(content) .lineLimit(nil) .truncationMode(.head) .frame(height: 50) Button { content += content } label: { Text("Double") } .buttonStyle(.borderedProminent) } .frame(width: 200, height: 1000) .padding() } } #Preview { ContentView() } It show result like this, this is not what I want.
0
0
246
Mar ’25
ForEach loop in a Map doesn't work
Hi all, here's a tiny litte demo app import SwiftUI import MapKit struct MarkerData: Identifiable { var id = UUID() var coordinate: CLLocationCoordinate2D } struct MapView2: View { @State private var markers: [MarkerData] = [] var body: some View { ForEach(markers) { marker in Text("\(marker.coordinate)") } Map { ForEach(markers) { marker in MapMarker(coordinate: marker.coordinate) } } } } The ForEach loop inside the Map gives the error: "Generic parameter 'V' could not be inferred" The one above seems to be fine. What is wrong with the loop inside the map? (I'm working with XCode Version 16.2) Best!
4
0
437
Mar ’25
How do we support new OS functions not available to many users?
In the past I've used #if available to isolate functionality gaps at the code level in my apps. But yesterday I was trying to integrate the new methods Apple has made available for granting access to contacts, as discussed here: https://developer.apple.com/documentation/contacts/accessing-a-person-s-contact-data-using-contacts-and-contactsui The problem is that their example is rife with code that won't compile for iOS 17, which is still (from the last stats I found) 20% of the user base. I also experimented with @available; but when I was nearly done integrating the new methods, a compiler bug halted my entire project. It now simply doesn't build (the ol' non-zero exit code) with no further details or errors flagged. I filed a report, as requested in the logs. In the meantime, I have to start over. What is the recommended method for isolating large blocks of functionality that are only available to a later OS version?
2
0
542
Mar ’25
SWIFTUI: chartLegend alignment 'Centering' option
SWIFTUI : Chart control / view is there way to align the Legends to align the center I see there only 2 options, .chartLegend(position: .bottom, alignment: .leading,spacing: 10) .leading or .trailing code : Chart{ ..... SectorMark.. } .chartLegend(position: .bottom, alignment: .leading,spacing: 10)
Topic: UI Frameworks SubTopic: SwiftUI
2
0
284
Mar ’25
Swift UI on iOS 14 not assigning new object to @State property
On iOS 13 I used to use optional @State properties to adapt views. In my case, the presented view would either create a new object (an assignment) if the state that is passed into it is nil, or edit the assignment if an assignment was passed in. This would be done in the action block of a Button and it worked beautifully. On iOS 14 / Xcode 12 this no longer seems to work. Given the following code which creates a new assignment and passes it into the editor view when the user taps a "New Assignment" button, the value of assignment remains nil. Is anyone else experiencing similar behaviour? struct ContentView: View { &#9;&#9;@Environment(\.managedObjectContext) var context &#9;&#9;@State var assignmentEditorIsPresented = false &#9;&#9;@State var assignment: Assignment? = nil &#9;&#9;var Body: some View { &#9;&#9;&#9;&#9;[...] &#9;&#9;&#9;&#9;Button("New Assignment", action: { &#9;&#9;&#9;&#9;&#9;&#9;self.assignment = Assignment(context: context) &#9;&#9;&#9;&#9;&#9;&#9;self.assignmentEditorIsPresented = true &#9;&#9;&#9;&#9;}) &#9;&#9;&#9;&#9;.sheet(isPresented: assignmentEditorIsPresented) { &#9;&#9;&#9;&#9;&#9;&#9;[...] &#9;&#9;&#9;&#9;} &#9;&#9;} } What's even weirder is that I tried adding a random piece of state, an Int, to this view and modifying it right before the assignment state (between lines 9 and 10) and it didn't change either.
21
4
13k
Mar ’25
Unexpected onAppear behavior in NavigationStack with ViewThatFits
Hello, My goal is to have a NavigationStack whose root view is determined based on its height and width. To do so, I'm using ViewThatFits, which should choose the right view to display. It is working fine, but unexpectedly both views trigger onAppear, whereas only the appropriate one should. This causes the logic in both closures to be executed, which is not intended. The code below demonstrates the problem: struct NavigationStackContentView: View { var body: some View { NavigationStack { ViewThatFits(in: .vertical) { Color.yellow .onAppear { print("|-> on appear: yellow") } .onDisappear { print("|-> on disappear: yellow") } Color.red .frame(width: 1500, height: 1500) .onAppear { print("|-> on appear: red") } .onDisappear { print("|-> on disappear: red") } } } } } this produces: |-> on appear: red |-> on disappear: red |-> on appear: yellow When ViewThatFits is not nested within NavigationStack, the problem does not occur — only the yellow view (in this sample) triggers onAppear, which is the expected behavior. I also checked the macOS version, and the problem does not occur at all, whether within NavigationStack or not. This example is simple and demonstrates that the larger view is the second one. When I switch their places, the problem does not occur because it recognizes that the first view would not fit at this point. However, in my case I will have these views without knowing which one will not fit, so switching their order is not a viable solution if this works without NavigationStack. Am I doing something wrong, or is this a bug? // iOS: 18.3.1 Xcode: 16.2
1
0
210
Mar ’25
PasteButton in a confirmationDialog
Hey, Anyone knows of a possible way to present a PasteButton in a .confirmationDialog on iOS? when I try adding it, it's ignored and not displayed with the rest of the buttons struct MyView: View { @State var flag: Bool = false var body: some View { Text("Some Text") .confirmationDialog("Dialog", isPresented: $flag) { Group { Button("A") {} Button("B") {} PasteButton(payloadType: Data.self) { data in } } } } }
0
0
157
Mar ’25
Crash: KEY_TYPE_OF_DICTIONARY_VIOLATES_HASHABLE_REQUIREMENTS
Hi everyone, frome time to time I see crash which Im not able to debug, because there is no line of my code where crash occured. This is a crash log what Im getting from time to time of some users. In my device I never get this kind of crash. 0 libswiftCore.dylib 0x1172c _assertionFailure(_:_:flags:) + 208 1 libswiftCore.dylib 0x198624 KEY_TYPE_OF_DICTIONARY_VIOLATES_HASHABLE_REQUIREMENTS(_:) + 2980 2 libswiftCore.dylib 0xdb6c8 specialized _NativeDictionary.uncheckedRemove(at:isUnique:) + 534 3 libswiftCore.dylib 0xb250c Dictionary._Variant.setValue(_:forKey:) + 204 4 libswiftCore.dylib 0x5a620 Dictionary.subscript.setter + 520 5 SwiftUICore 0xf62ec ForEachState.item(at:offset:) + 4340 6 SwiftUICore 0xf5054 ForEachState.forEachItem(from:style:do:) + 1796 7 SwiftUICore 0x2272f8 ForEachState.traitKeys.getter + 84 8 SwiftUICore 0x227298 ForEachList.traitKeys.getter + 24 9 SwiftUICore 0x227008 protocol witness for ViewList.traitKeys.getter in conformance SubgraphList + 76 10 SwiftUICore 0x227008 protocol witness for ViewList.traitKeys.getter in conformance SubgraphList + 76 11 SwiftUICore 0x227008 protocol witness for ViewList.traitKeys.getter in conformance SubgraphList + 76 12 SwiftUICore 0x227008 protocol witness for ViewList.traitKeys.getter in conformance SubgraphList + 76 13 SwiftUICore 0x2271fc DynamicViewList.WrappedList.traitKeys.getter + 88 27 SwiftUICore 0x226d18 specialized static SectionAccumulator.processUnsectionedContent(list:contentSubgraph:) + 84 28 SwiftUI 0x26afe0 ListSectionInfo.init(list:listAttribute:contentSubgraph:) + 132 29 SwiftUI 0x269bb0 UpdateCollectionViewListCoordinator.updateValue() + 1528 30 SwiftUI 0x785d4 partial apply for implicit closure #1 in closure #1 in closure #1 in Attribute.init<A>(_:) + 32 31 AttributeGraph 0xccac AG::Graph::UpdateStack::update() + 540 32 AttributeGraph 0xc870 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int) + 424 33 AttributeGraph 0xc444 AG::Subgraph::update(unsigned int) + 848 34 SwiftUICore 0x805a8 GraphHost.flushTransactions() + 860 35 SwiftUI 0x1ac84 closure #1 in _UIHostingView._renderForTest(interval:) + 24 36 SwiftUICore 0x7ffa8 partial apply for closure #1 in ViewGraphDelegate.updateGraph<A>(body:) + 28 37 SwiftUICore 0x7fd6c ViewRendererHost.updateViewGraph<A>(body:) + 120 38 SwiftUICore 0x7fce8 ViewGraphDelegate.updateGraph<A>(body:) + 84 39 SwiftUI 0x3e688 closure #1 in closure #1 in closure #1 in _UIHostingView.beginTransaction() + 172 40 SwiftUI 0x3e5d4 partial apply for closure #1 in closure #1 in closure #1 in _UIHostingView.beginTransaction() + 24 41 SwiftUICore 0x79720 closure #1 in static Update.ensure<A>(_:) + 56 42 SwiftUICore 0x796a4 static Update.ensure<A>(_:) + 100 43 SwiftUI 0x9c808 partial apply for closure #1 in closure #1 in _UIHostingView.beginTransaction() + 80 44 SwiftUICore 0x7f5e0 thunk for @callee_guaranteed () -> () + 28 45 SwiftUICore 0x6161c specialized closure #1 in static NSRunLoop.addObserver(_:) + 144 46 CoreFoundation 0x218a4 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 36 47 CoreFoundation 0x213f8 __CFRunLoopDoObservers + 552 48 CoreFoundation 0x75da8 __CFRunLoopRun + 948 49 CoreFoundation 0xc8284 CFRunLoopRunSpecific + 588 50 GraphicsServices 0x14c0 GSEventRunModal + 164 51 UIKitCore 0x3ee674 -[UIApplication _run] + 816 52 UIKitCore 0x14e88 UIApplicationMain + 340 53 SwiftUI 0x291ef8 closure #1 in KitRendererCommon(_:) + 168 54 SwiftUI 0x291e28 runApp<A>(_:) + 100 55 SwiftUI 0x291d0c static App.main() + 180 56 DholRainbow 0x3019e8 main + 4339145192 (DholRainbowApp.swift:4339145192) 57 ??? 0x1b0bf5de8 (Missing) From Crashlytics I know at least human readable format of this error Fatal error: Duplicate keys of type 'Contact' were found in a Dictionary. This usually means either that the type violates Hashable's requirements, or that members of such a dictionary were mutated after insertion. I 've checked all my parts of code where Im using dictionary. This is a function which creating that particulary dictionary. private func logsByDate() { let groupedByDate = Dictionary(grouping: logs.filter { ($0.remoteParty as? Contact != nil) } ) { $0.date.removeTimeStamp ?? .distantPast }.mapValues { $0.compactMap { $0 } } var dayLogs = [DayLog]() for date in groupedByDate { var contacts = [CallLogContact]() for log in logs.filter({ $0.date.removeTimeStamp ?? .distantPast == date.key }) { if let contact = log.remoteParty as? Contact { if contacts.firstIndex(where: {$0.contact == contact }) == nil { let contactDayLogs = logs.filter({ $0.remoteParty as? Contact == contact && $0.date.removeTimeStamp == date.key}) contacts.append( CallLogContact( contact: contact, logs: contactDayLogs, lastCallLogDate: contactDayLogs.sorted(by: {$0.date > $1.date}).first?.date ?? .distantPast ) ) } } } dayLogs.append(DayLog(date: date.key, contact: contacts)) } DispatchQueue.main.async { self.groupedCallLogs = dayLogs } } This function is called from 3 others functions based on notification from the server in case of new call log, fetched call logs and removed call logs.
0
0
294
Mar ’25
detecting modifier keys using UITextFieldDelegate protocol
I have a UITextField in my application, and I want to detect all the keys uniquely to perform all relevant task. However, there is some problem in cleanly identifying some of the keys. I m not able to identify the backspace key press in the textField(_:shouldChangeCharactersIn:replacementString:) method. Also I don't know how to detect the Caps Lock key. I am intending to so this because I want to perform some custom handling for some keys. Can someone help me with what is the way of detecting it under the recommendation from apple. Thanks in advance. Note: checking for replacementString parameter in shouldChangeCharactersIn method for empty does not help for backspace detection as it overlaps with other cases.
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
152
Mar ’25