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

UICollectionView unwanted content offset change on invalidating layout
I have issue with unwanted changing offset in collection view to top or to near top. It is happening in collection view with vertical scroll when estimatedItemSize is not set to zero (main factor). If estimatedItemSize is zero it is always fine. It is SDK that provides items that should be loaded in few cells, items have dynamic height which is received from server and can be updated several times. Scenario when it happens (when was noticed) is 2 sections, in section 0 item is at index 4 of 14, section 1 is with only one cell with dynamic height item. If specific item is at index 0 in section 0 or have 1 cell per section (tried 15 sections and set items in sections 5 and 15) all is good regardless of estimatedItemSize. When new height is received if I call invalidateLayout or reloadItemAtIndexPaths it will “jump”. That same height is set in sizeForItemAtIndexPath. In some combinations it happens and in some not and that is the most annoying part. I tried setting estimated height to received height and it didn’t help (other cell may be smaller or larger). Also if I put items in one section at indexes 4 and 14 it “jumps”. I managed to make it work by setting at specific moment estimatedItemSize to zero then put back to one that SDK user set and didn’t see any issues but I was wondering if there is any other solution for this and did anyone had issue like this. It would be nice to have solution to keep one estimatedItemSize if it is not the default one (zero).
Topic: UI Frameworks SubTopic: UIKit
0
0
248
Sep ’24
UIButtonLegacyVisualProvider Crash
0 CoreFoundation 0x0000000183f687cc ___exceptionPreprocess + 164 1 libobjc.A.dylib 0x000000018123b2e4 _objc_exception_throw + 88 2 CoreFoundation 0x000000018406e5f0 +[NSObject(NSObject) doesNotRecognizeSelector:] + 0 3 UIKitCore 0x0000000186849a48 -[UIButtonLegacyVisualProvider _newLabelWithFrame:] + 60 4 UIKitCore 0x00000001867652b0 -[UIButtonLegacyVisualProvider _setupTitleViewRequestingLayout:] + 84 5 UIKitCore 0x0000000186763ba4 -[UIButtonLegacyVisualProvider titleViewCreateIfNeeded:] + 44 6 UIKitCore 0x00000001867d3f74 -[UIButton titleLabel] + 36 Hello bro, in IOS 18 our team find issue ,We created a button like this: UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.titleLabel.font = [UIFont fontWithName:paramFontName size: fontSize]; Please tell me whether we need to set button frame before we call button.titleLabe?
Topic: UI Frameworks SubTopic: UIKit
2
0
365
Nov ’24
Is there a way to know what size of icons is enabled in the home page?
Hey, i have an app that uses some calculations to replicate a transparent background in widgets, however given that in ios 18 we can now change the icons size to large, I wonder if there is a way to know what the user has currently selected and react to it? The workaround I have is that user needs to select a new config to switch the widget to large so re-calculations are done, but it would be nice if we there was a way for us to catch the new size.
0
0
299
Sep ’24
MapkitJS - not able to click on PointOfInterest and use it for actions
Hi, Have been trying to work with MapkitJS for a website, but I'm stumped on once basic capability: I want to be able to click on a point of interest, and perform some actions such as: Get its coordinates Attach an annotation to it (e.g. a callout) In my code, PointOfInterest's are selectable: map.selectableMapFeatures = [ mapkit.MapFeatureType.PointOfInterest, ]; But when I click on one, I do see the marker pop up but nothing else (which is not much help since there is no additional information in the marker itself). I see no event getting triggered that I can do something with. I am using an event listener as follows: map.addEventListener('single-tap', (event) => { const coordinate = map.convertPointOnPageToCoordinate(event.pointOnPage); console.log('Map tapped at:', coordinate); console.log('Map tapped event:', event); ... I guess I have to grab the Place ID somehow but I don't know how to. Thanks for any help.
0
0
541
Nov ’24
Cocoa Binding for custom class
So I was trying to use an NSArrayController to bind the contents of a property , first I tried using NSDictionary and it worked great, here's what I did: @interface ViewController : NSViewController @property IBOutlet ArrayController * tableCities; @end ... @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; NSString* filePath = @"/tmp/city_test.jpeg"; NSDictionary *obj = @{@"image": [[NSImage alloc] initByReferencingFile:filePath], @"name": @"NYC", @"filePath": filePath}; NSDictionary *obj2 = @{@"image": [[NSImage alloc] initByReferencingFile:filePath], @"name": @"Chicago", @"filePath": filePath}; NSDictionary *obj3 = @{@"image": [[NSImage alloc] initByReferencingFile:filePath], @"name": @"Little Rock", @"filePath": filePath}; [_tableCities addObjects:@[obj, obj2, obj3]]; } @end Now for an NSPopUpButton, binding the Controller Key to the ArrayController and the ModelKeyPath to "name" works perfectly and the popupbutton will show the cities as I expected. But now, instead of using an NSDictionary I wanted to use a custom class for these cities along with an NSMutableArray which holds the objects of this custom class. I'm having some trouble going about this.
0
0
419
Oct ’24
Identify what is being dragged globally
I would like to implement the same kind of behavior as the Dropoverapp application, specifically being able to perform a specific action when files are dragged (such as opening a window, for example). I have written the code below to capture the mouse coordinates, drag, drop, and click globally. However, I don't know how to determine the nature of what is being dropped. Do you have any ideas on how to detect the nature of what is being dragged outside the application's scope? Here is my current code: import SwiftUI import CoreGraphics struct ContentView: View { @State private var mouseX: CGFloat = 0.0 @State private var mouseY: CGFloat = 0.0 @State private var isClicked: Bool = false @State private var isDragging: Bool = false private var mouseTracker = MouseTracker.shared var body: some View { VStack { Text("Mouse coordinates: \(mouseX, specifier: "%.2f"), \(mouseY, specifier: "%.2f")") .padding() Text(isClicked ? "Mouse is clicked" : "Mouse is not clicked") .padding() Text(isDragging ? "Mouse is dragging" : "Mouse is not dragging") .padding() } .frame(width: 400, height: 200) .onAppear { mouseTracker.startTracking { newMouseX, newMouseY, newIsClicked, newIsDragging in self.mouseX = newMouseX self.mouseY = newMouseY self.isClicked = newIsClicked self.isDragging = newIsDragging } } } } class MouseTracker { static let shared = MouseTracker() private var eventTap: CFMachPort? private var runLoopSource: CFRunLoopSource? private var isClicked: Bool = false private var isDragging: Bool = false private var callback: ((CGFloat, CGFloat, Bool, Bool) -> Void)? func startTracking(callback: @escaping (CGFloat, CGFloat, Bool, Bool) -> Void) { self.callback = callback let mask: CGEventMask = (1 << CGEventType.mouseMoved.rawValue) | (1 << CGEventType.leftMouseDown.rawValue) | (1 << CGEventType.leftMouseUp.rawValue) | (1 << CGEventType.leftMouseDragged.rawValue) // Pass 'self' via 'userInfo' let selfPointer = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()) guard let eventTap = CGEvent.tapCreate( tap: .cghidEventTap, place: .headInsertEventTap, options: .defaultTap, eventsOfInterest: mask, callback: MouseTracker.mouseEventCallback, userInfo: selfPointer ) else { print("Failed to create event tap") return } self.eventTap = eventTap runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0) CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, .commonModes) CGEvent.tapEnable(tap: eventTap, enable: true) } // Static callback function private static let mouseEventCallback: CGEventTapCallBack = { _, eventType, event, userInfo in guard let userInfo = userInfo else { return Unmanaged.passUnretained(event) } // Retrieve the instance of MouseTracker from userInfo let tracker = Unmanaged<MouseTracker>.fromOpaque(userInfo).takeUnretainedValue() let location = NSEvent.mouseLocation // Update the click and drag state switch eventType { case .leftMouseDown: tracker.isClicked = true tracker.isDragging = false case .leftMouseUp: tracker.isClicked = false tracker.isDragging = false case .leftMouseDragged: tracker.isDragging = true default: break } // Call the callback on the main thread DispatchQueue.main.async { tracker.callback?(location.x, location.y, tracker.isClicked, tracker.isDragging) } return Unmanaged.passUnretained(event) } }
0
0
487
Oct ’24
SwiftUI DatePicker UI doesn't match the actual data
I have a view for editing time information。The view has two properties startTime and endTime wrapped using @binding, of type Date? @Binding var startTime: Date? @Binding var endTime: Date? Different components are displayed depending on whether they have a value or not, the logic is the same for both. if startTime == nil { // something } else { DatePicker("Start Time", selection: Binding( get: { startTime! }, set: { startTime = $0 } )) } if endTime == nil { // something } else { DatePicker("End Time", selection: Binding( get: { endTime! }, set: { endTime = $0 } )) } Execute the initData method when the view appears. private func initData() { print("Start Time: \(String(describing: startTime))") print("End Time: \(String(describing: endTime))") } The output of the open view is as follows: Start Time: Optional(2024-10-11 08:07:35 +0000) End Time: Optional(2024-10-11 08:08:35 +0000) Screenshot of the interface display: The end time is displayed correctly in the view that opens, and the start time shows the current time. The data seen via DEBUG is consistent with the console output, there is just a problem with the display. I don't make any changes and just click the save button and the data is still ‘2024-10-11 08:07:35 +0000’. I hope to get some answers, thanks!
Topic: UI Frameworks SubTopic: SwiftUI
0
0
192
Oct ’24
Is there a way to opt a Catalyst app into supporting preferred text size?
As of macOS Sequoia 15.1 (and probably earlier), in System Settings under Accessibility -> Display, there's a Text Size option that looks an awful lot like Dynamic Type on iOS: I have an iOS app with robust support for Dynamic Type that I've brought to the Mac via Catalyst. Is there any way for me to opt this app into supporting this setting, maybe with some Info.plist key? Calendar's Info.plist has a CTIgnoreUserFonts value set to true, but the Info.plist for Notes has no such value.
0
0
544
Oct ’24
iOS 18 NavigationSplitView in NavigationStack not loading properly
With iOS 18.0, this snippet of code that has a NavigationSplitView inside a NavigationStack will not display the sidebar until the navigation transition is completed. NavigationStack { NavigationLink("Link") { NavigationSplitView { Text("Example") } detail: { Text("Does not appear") } } } Directly after pressing the link, a toolbar briefly appears. Once the transition is completed, the split view's sidebar appears and the toolbar disappears. The detail view does not visually appear at all. The same problem occurs when using .navigationDestination(…), which I am in our production code. I've tested this in Xcode 16.0 Previews for iOS 18.0, iPhone SE Simulator iOS 18.0, iPadOS 18.0 when horizontal size class is compact, and on my personal iPhone 13 mini iOS 18.0 I experienced this problem on our production app. Is there any workaround to not have this delay? Our app is heavily built around this nested approach, and has been working perfectly in previous iOS versions.
3
0
997
Sep ’24
SwiftUI Table on macOS hanging with large number of rows
I am using SwiftUI Table View in my macOS application The app uses a server-client paradigm where the client queries the server database and presents the fetch in a table. I had used List earlier on, but I found it was not performant on macOS so I switched to using Table view. the Table view on macOS was better than List but it suffers from a 'forever hang' where a beachball can last for minutes. this occurs each time in this way: launch the app and the Table with 5000 rows load fine on update of the data, it hangs forever interestingly, this does not occur on iOS. I have a very simple test app that shows this issue but I cannot figure why the data update causes a hang and how to remedy this. I have tried applying an .id() to the Table but this did not help. Clearly, since the initial loading of the data is easily handled by the framework means that there is no inherent limit to the number of rows. There is something going on when applying an update to the table data.
6
0
380
Oct ’24
Screen on Apple watch turn off even when "Always On" is active
Our company has developed a product available, which measures body composition. During the measurement process, lasting 40 seconds, we require the device screen to remain illuminated. We are actively using the "Always On" feature and have set the timer on the watch to 70 minutes to prevent the screen from dimming. However, we are encountering issues where the screen may still turn off during the measurement. Could you please provide guidance on how to keep the screen active with backlighting across all Apple Watch models during measurements?
2
0
1.1k
Nov ’24
Binding NSPopUpButton to an NSMutableArray
My view controller has this property: @property NSMutableArray *tableCities; Whenever I press a button a new city object is added to this array, it consists of a dictionary of NSStrings containing the name and state of the city being added. Now, I have an NSPopUpButton that I'd like to bind to the city name of all cities in this NSMutableArray, how exactly can I achieve this with the Bindings Inspector?
2
0
542
Oct ’24
Disable SwiftUI NavigationView Swipe
I am using SwiftUI NavigationView to navigate. I cant find how can i disable swipe from the leftmost part of the screen for navigation bar. Im tried this way , but it doesn't work for me: struct DisableBackSwipeGestureView: UIViewControllerRepresentable { typealias UIViewControllerType = UINavigationController func makeUIViewController(context: Context) -> UINavigationController { DisableSwipeBackViewController().navigationController ?? UINavigationController() } func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {} func makeCoordinator() -> Coordinator { return Coordinator() } class Coordinator: NSObject, UIGestureRecognizerDelegate { func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { return false } } } final class DisableSwipeBackViewController: UIViewController { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) if let navigationController = self.navigationController { if let interactivePopGestureRecognizer = navigationController.interactivePopGestureRecognizer { interactivePopGestureRecognizer.delegate = self interactivePopGestureRecognizer.isEnabled = false } } } } extension DisableSwipeBackViewController: UIGestureRecognizerDelegate { func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { return false } } extension View { func disableSwipeBackGesture() -> some View { self.modifier(DisableSwipeBackGesture()) } } Is there a way to disable this feature in swiftui?
0
0
151
Sep ’24
SizeClasses, really?
I have an app with looks at the @Environment(\.horizontalSizeClass) variable and it's mate vertical. On the iPhone 16 sim, if I'm in portrait orientation, It says my vertical class is .regular and horizontal is .compact. If I rotate to landscape, it says vertical is now compact, and horizontal is still compact. That seems inconsistent. I'm trying to wrap my head around designing for size class, how am I supposed to think about this? What I want is two areas of the screen: The main area, which shows a graphic, and a much smaller control and data area, which has a button or two and a very narrow text display, which in my current app counts from 1 to 4. The button area These areas ought never move from where they are, but their contents ought to rotate in place to reflect the orientation. If portrait, the button area is on the bottom, if landscapeLeft, the button are is to the right, if landscapeRight, the button area is to the left. This currently sort of works if I test for the max of height or width from a Geometry Reader, but it doesn't handle landscapeRight or portraitUpsideDown correctly.
Topic: UI Frameworks SubTopic: SwiftUI
1
0
432
Oct ’24
Scale contextMenu preview size to containing content
Hi! I have a multi-line string I'd like to display as text in a long-press preview (using .contextMenu). However, text after 3rd or 4th linebreak (\n) gets clipped. The intended effect is to have the minimum preview size that can fit all of the text. Tried .frame(maxWidth: .infinity, maxHeight: .infinity) on Text() but it didn't have any effect. The only modifier that somewhat works is .containerRelativeFrame([.horizontal, .vertical]) but this gives the maximum preview size, instead of minimum. Any suggestions? TIA. struct RedditView: View { @State private var text = "AAAAAAAAAAAAAAAAAAAAAA?\n\nBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\nCCCCCCCCCCCCCCCCCCCCCCCCCC" var body: some View { Text("Long press this") .frame(width: 300, height: 100) .contentShape(.rect) .border(Color.blue) .contextMenu(menuItems: { Button { // do something } label: { Label { Text("Edit") } icon: { Image(systemName: "pencil") } } }, preview: { Text(text) // .frame(maxWidth: .infinity, maxHeight: .infinity) .multilineTextAlignment(.center) .padding() //.containerRelativeFrame([.horizontal, .vertical]) } ) } }
0
0
633
Sep ’24
Programmatically switch between "mirror" and "additional content" with windowExternalDisplayNonInteractive
I'd like to share an app's screen in two modes. First in a standard mirroring mode and second in an "additional content" mode (very likely with a session role windowExternalDisplayNonInteractive). I found that the Keynote app on iOS does a very nice example of what I want to achieve when sharing an iPhone using AirPlay to an AppleTV. sharing a screen results in mirroring the screen on the TV tapping the play button in Keynote switches to "additional content" where iPhone and TV show different content leaving the additional content mode returns to "mirroring" where TV and iPhone show the same content Is there an example for implementing such a feature? I am able to successfully use the external display (windowExternalDisplayNonInteractive) and show additional content there. How can I programmatically "detach" the additional content from the external display and activate mirroring mode? Searching the Developer Forums for windowExternalDisplayNonInteractive reveals some discussions, which include valuable information, however, returning to mirror mode does not seem to be covered.
Topic: UI Frameworks SubTopic: General Tags:
1
0
411
Oct ’24
iOS 18: "Invalid number of items in section 0"
Hi, I recently started experiencing the following bug in the code listed below. The app is a dieting/calorie logging app with a function that presents a List() of calories in different days, separated into sections for each Meal as derived from an array of Meals. Part of this functionality is that the user can swipe an entry in the List to delete one. If the user has one entry and they delete it, behaviour is as expected. If they have more than one entry and they delete one, behaviour is as expected. If they have more than one entry and they delete two items, one after another, the app crashes with the message "Invalid number of items in section 0". If they have more than one entry and they delete one, then go back to the main screen of the app, then delete another one, behaviour is as expected. Searches online suggest that this is because the array underpinning the list has not updated. However the app crashes before it has even reached the delete() function called by onDelete, so there is no opportunity to update the model before something refreshes and the app crashes. Does anyone have any idea how to resolve this? This code worked fine up until iOS 18. List { if list.budgieData.count != 0 { ForEach(list.mealList.indices, id: \.self) { idx in Section(header: Text(list.mealList[idx].name)) { ForEach(list.budgieData.indices, id: \.self) { entryIdx in if list.budgieData[entryIdx].meal == list.mealList[idx].mealUUID { CalorieEntryView(calories: list.budgieData[entryIdx].calories, narrative: list.budgieData[entryIdx].narrative ?? "Quick calories", realEntry: list.budgieData[entryIdx].realEntry, date: list.budgieData[entryIdx].date) } }.onDelete(perform: delete) } } } else { Text("You have no calories logged in Budgie Diet on this day.") } if list.hkCalories != 0 { Section(header: Text("Calories from other apps"), footer: Text("These are calories logged in Health by other apps. You'll need to go to the app that logged them to change or delete them.")) { CalorieEntryView(calories: list.hkCalories, narrative: "Calories from other apps", realEntry: false, date: list.curDate) .deleteDisabled(true) } } }.listStyle(.grouped)
Topic: UI Frameworks SubTopic: SwiftUI Tags:
0
0
200
Oct ’24
How can I make my multi-window Catalyst app restore window size and position after closing with stoplight button?
I have a Catalyst app that supports multiple scenes / windows. It has one "main" window type and lots of other secondary windows that can be opened. I'm using the system window restoration functionality via NSQuitAlwaysKeepsWindows to restore windows with their user activity data after the app is quit and restarted. Normally, this works great. If I open my app, change the size and position of my window, quit, and reopen it, the window size and position comes back as expected. But if I close the window using the red stoplight button and then click the app icon to bring it back, it comes back at the default position and size. This isn't how other system apps work - if I close the system Calendar app with the stoplight button, it comes back at the same size and position. How do I get this behavior with my Catalyst app? Is there some identifier property I need to set somewhere? I don't see such a property on UISceneConfiguration. If it matters, I'm using the configurationForConnectingSceneSession method to configure my windows when they open, instead of setting it up in the Info.plist.
1
0
521
Oct ’24