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

Allow custom tap gesture in List but maintain default selection gesture
I'm trying to create a List that allows multiple selection. Each row can be edited but the issue is that since there's a tap gesture on the Text element, the list is unable to select the item. Here's some code: import SwiftUI struct Person: Identifiable { let id: UUID let name: String init(_ name: String) { self.id = UUID() self.name = name } } struct ContentView: View { @State private var persons = [Person("Peter"), Person("Jack"), Person("Sophia"), Person("Helen")] @State private var selectedPersons = Set<Person.ID>() var body: some View { VStack { List(selection: $selectedPersons) { ForEach(persons) { person in PersonView(person: person, selection: $selectedPersons) { newValue in // ... } } } } .padding() } } struct PersonView: View { var person: Person @Binding var selection: Set<Person.ID> var onCommit: (String) -> Void = { newValue in } @State private var isEditing = false @State private var newValue = "" @FocusState private var isInputActive: Bool var body: some View { if isEditing { TextField("", text: $newValue, onCommit: { onCommit(newValue) isEditing = false }) .focused($isInputActive) .labelsHidden() } else { Text(person.name) .onTapGesture { if selection.contains(person.id), selection.count == 1 { newValue = person.name isEditing = true isInputActive = true } } } } } Right now, you need to tap on the row anywhere but on the text to select it. Then, if you tap on the text it'll go in edit mode. Is there a way to let the list do its selection? I tried wrapping the tap gesture in simultaneousGesture but that didn't work. Thanks!
3
2
1.8k
Feb ’23
UIDeferredMenuElement With Uncached Provider Not Working on Mac Catalyst. Uncached provider block never called and menu displays as "Loading"
I'm trying to create a dynamic menu on Mac Catalyst. Using a UIBarButtonitem like so to make a "pull down" button: UIDeferredMenuElement *deferredmenuElement; deferredmenuElement = [UIDeferredMenuElement elementWithUncachedProvider:^(void (^ _Nonnull completion)(NSArray<UIMenuElement *> * _Nonnull)) { UIAction *actionOne = [UIAction actionWithTitle:@"Action One" image:nil identifier:nil handler:^(__kindof UIAction * _Nonnull action) { NSLog(@"action one fired."); }]; UIAction *actionTwo = [UIAction actionWithTitle:@"Action Two" image:nil identifier:nil handler:^(__kindof UIAction * _Nonnull action) { NSLog(@"action two fired."); }]; UIAction *actionThree = [UIAction actionWithTitle:@"Action Three" image:nil identifier:nil handler:^(__kindof UIAction * _Nonnull action) { NSLog(@"action three fired."); }]; completion(@[actionOne,actionTwo,actionThree]); }]; UIMenu *wrappedMenu = [UIMenu menuWithChildren:@[deferredmenuElement]]; UIBarButtonItem *uiBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:nil menu:wrappedMenu]; uiBarButtonItem.image = [UIImage systemImageNamed:@"rectangle.and.pencil.and.ellipsis"]; self.navigationItem.rightBarButtonItems = @[uiBarButtonItem]; The button appears in the toolbar but when I click it to expose the menu I get a menu with on element in it that says "Loading...". The the uncached provider block is never called. Running Ventura 13.2.1 and Xcode 14.2.
8
2
2.0k
Mar ’23
NavigationSplitView hide sidebar toggle button
I'm trying to implement the same UI used by the Settings app on iPad: a split view with two columns that are visible at all times. This code produces the layout i want, but I would like to hide the "toggle sidebar visibility" button that the system introduces. Is there a SwiftUI API I can use to hide this button? Maybe an alternate way to setup views that tells the system that the button is not necessary? struct SomeView: View { var body: some View { NavigationSplitView( columnVisibility: .constant(.all), sidebar: { Text("sidebar") }, detail: { Text("detail") } ) .navigationSplitViewStyle(.balanced) } }
7
3
7.9k
Apr ’23
NO ANIMATIONS in NavigationStack or NavigationSplitView
I'm building a macOS app using SwiftUI and I recently updated to xcode 14.3. Since then I've been debugging why none of my animations were working, it turned out that the NavigationSplitView or NavigationStack are somehow interfering with all the animations from withAnimation to .transition() and everything in between. Is anyone else experiencing this, knows a work around or knows why this is happening?
11
9
9.7k
Apr ’23
CloudKit Stopped Syncing after adding new Entities
Can someone please shed some light? I have an app that uses Core Data and CloudKit, up until the last version, I was able to sync data between devices but now after I added two new Entities for some reason it stopped syncing between devices. Here is how I did the change: Created a new Core Data container. Added the new Entities and their Attributes Tested the new Entities locally to be able to send the new schema to CloudKit. Went to CloudKit and made sure that the new Entities and Attributes were reflected on the Developent database. Deploy Schema Cahnges. Went to the Production database to make sure the new schema was deployed; and it was, both databases look the same. Testing: Tested in the simulator and with a real device and everything syncs, even the new Entities. If I download the app from the App Store on two different devices they do NOT sync. Based on the procedure I'm describing above, is there any important step I may have missed when doing the migration? I'm not sure if this is related to the syncing issue but after testing a few times, I no longer can turn the iCloud on, I get the following message when I try to turn iCloud Sync On. CoreData: error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate resetAfterError:andKeepContainer:]: <NSCloudKitMirroringDelegate: 0x282c488c0> - resetting internal state after error: Error Domain=NSCocoaErrorDomain Code=134410 "CloudKit setup failed because there is another instance of this persistent store actively syncing with CloudKit in this process." UserInfo={NSURL=file:///var/mobile/Containers/Data/Application/73F19BC7-4538-4098-85C7-484B36192CF3/Library/Application%20Support/CoreDataContainer.sqlite, NSLocalizedFailureReason=CloudKit setup failed because there is another instance of this persistent store actively syncing with CloudKit in this process., NSUnderlyingException=Illegal attempt to register a second handler for activity identifier com.apple.coredata.cloudkit.activity.setup.8D4C04F6-8040-445A-9447-E5646484521} Any idea of what could be wrong and preventing the devices from syncing? Any idea or suggestion is welcome. Thanks
3
0
3.1k
May ’23
How can I integrate my own text changes into UITextView's undo manager?
I have an app that uses UITextView for some text editing. I have some custom operations I can do on the text that I want to be able to undo, and I'm representing those operations in a way that plugs into NSUndoManager nicely. For example, if I have a button that appends an emoji to the text, it looks something like this: func addEmoji() { let inserting = NSAttributedString(string: "😀") self.textStorage.append(inserting) let len = inserting.length let range = NSRange(location: self.textStorage.length - len, length: len) self.undoManager?.registerUndo(withTarget: self, handler: { view in view.textStorage.deleteCharacters(in: range) } } My goal is something like this: Type some text Press the emoji button to add the emoji Trigger undo (via gesture or keyboard shortcut) and the emoji is removed Trigger undo again and the typing from step 1 is reversed If I just type and then trigger undo, the typing is reversed as you'd expect. And if I just add the emoji and trigger undo, the emoji is removed. But if I do the sequence above, step 3 works but step 4 doesn't. The emoji is removed but the typing isn't reversed. Notably, if step 3 only changes attributes of the text, like applying a strikethrough to a selection, then the full undo chain works. I can type, apply strikethrough, undo strikethrough, and undo typing. It's almost as if changing the text invalidates the undo manager's previous operations? How do I insert my own changes into UITextView's NSUndoManager without invalidating its chain of other operations?
4
0
1.7k
May ’23
Gesture: System gesture gate timed out.
Hi everyone I am fighting with a weird problem in my app I use swiftui and ai do not use tabs, but a hierarchy of view created by me that switch one to the other with a slide animation when I tap one of the elements i don't use gesture, but only ontap. The same app launched on two different iPhone has two different behaviours on the iPhone 11 no problem, the animation is fluid and responsive, on the iPhone 10 I got some delay, and in the console I can read Gesture: System gesture gate timed out I have searched but I have not found anything useful and more than this it is extremely difficult to find some info about this warning/error How can I solve this? on the iPhone 10 it seems like the animation got stuck for 1 seconds prior to be executed in the correct way
16
17
12k
May ’23
dropDestination does not work inside List
I've discovered an issue with using iOS 16's Transferable drag-and-drop APIs for SwiftUI. The dropDestination modifier does not work when applied to a subview of a List. This code below will not work, unless you replace the List with a VStack or any other container (which, of course, removes all list-specific rendering). The draggable modifier will still work and the item will drag, but the dropDestination view won't react to it and neither closure will be called. struct MyView: View { var body: some View { List { Section { Text("drag this title") .font(.largeTitle) .draggable("a title") } Section { Color.pink .frame(width: 400, height: 400) .dropDestination(for: String.self) { receivedTitles, location in true } isTargeted: { print($0) } } } } } Has anyone encountered this bug and perhaps found a workaround?
8
0
3.3k
May ’23
Intermittent crashes when calling performSegue(withIdentifier:,sender:)
Our app crashes intermittently when calling performSegue(withIdentifier:,sender:). The segue does exist, as most of the time it works fine. The destination view controller only has its view as a connection. Crash report excerpt below. Uploading the crash report isn't working for some reason, so I'll try to do so as a reply. The stack trace shows searchForClientURL... as the last part of our code that gets executed. I'm curious if I should look at things in our code that happen while the segue is being performed such as prepare(for:, sender:), the init of the destination controller, etc. or not because they're not showing up in the stack trace. Thanks for any help! 0 CoreFoundation 0x19e310e38 __exceptionPreprocess + 164 (NSException.m:202) 1 libobjc.A.dylib 0x19749f8d8 objc_exception_throw + 60 (objc-exception.mm:356) 2 UIKitCore 0x1a1306630 __66-[UIStoryboardPushSegueTemplate newDefaultPerformHandlerForSegue:]_block_invoke + 880 (UIStoryboardPushSegueTemplate.m:58) 3 UIKitCore 0x1a08f3c84 -[UIStoryboardSegueTemplate _performWithDestinationViewController:sender:] + 172 (UIStoryboardSegueTemplate.m:134) 4 UIKitCore 0x1a08f3ba4 -[UIStoryboardSegueTemplate _perform:] + 68 (UIStoryboardSegueTemplate.m:121) 5 UIKitCore 0x1a0cc74c0 -[UIViewController performSegueWithIdentifier:sender:] + 300 (UIViewController.m:5017) 6 AWApp 0x10061ce38 closure #1 in ClientSelectorViewController.searchForClientURL(nameOrGUID:shouldTestSession:) + 3616 (ClientSelectorViewController.swift:231)
2
0
1.1k
May ’23
How to hide NSToolbar background when NSHostingController's ScrollView is at the top
In Monterey, when a user was at the top of a ScrollView implemented inside of a NSHostingController's view (that was itself embedded in a window with a NSToolbar), the window's toolbar background would be hidden until the user scrolled from the top. In Ventura, this behavior is different, with the toolbar's background visible all of the time unless a traditional NSScrollView is used (which means no SwiftUI). Is there the ability to change this behavior within SwiftUI some how now?
1
1
824
May ’23
SwiftUI view printout on paper
Hello and thanks for reading my post. I have a SwiftUI view, the users should be able to click a button and take printout of that view. Clicking on the button should open the standard print sheet (select printer, pages, layout, etc.). How can I implement such a functionality? I have been trying hard without any success. Please help. It is an iPad app, using Xcode 14.3
5
1
2.5k
Jun ’23
@Observable and didSet?
I'm in the process of migrating to the Observation framework but it seems like it is not compatible with didSet. I cannot find information about if this is just not supported or a new approach needs to be implemented? import Observation @Observable class MySettings { var windowSize: CGSize = .zero var isInFullscreen = false var scalingMode: ScalingMode = .scaled { didSet { ... } } ... } This code triggers this error: Instance member 'scalingMode' cannot be used on type 'MySettings'; did you mean to use a value of this type instead? Anyone knows what needs to be done? Thanks!
11
3
4.4k
Jun ’23
Keep ScrollView position when adding items on the top
I am using a LayzVStack embedded into a ScrollView. The list items are fetched from a core data store by using a @FetchResult or I tested it also with the new @Query command coming with SwiftData. The list has one hundred items 1, 2, 3, ..., 100. The user scrolled the ScrollView so that items 50, 51, ... 60 are visible on screen. Now new data will be fetched from the server and updates the CoreData or SwiftData model. When I add new items to the end of the list (e.g 101, 102, 103, ...) then the ScrollView is keeping its position. Opposite to this when I add new items to the top (0, -1, -2, -3, ...) then the ScrollView scrolls down. Is there a way with the new SwiftData and SwiftUI ScrollView modifiers to update my list model without scrolling like with UIKit where you can query and set the scroll offset pixel wise?
8
1
9.1k
Jun ’23
@Transient update doesn't propagate to view
When I update a variable inside my model that is marked @Transient, my view does not update with this change. Is this normal? If I update a non-transient variable inside the model at the same time that I update the transient one, then both changes are propagated to my view. Here is an example of the model: @Model public class WaterData { public var target: Double = 3000 @Transient public var samples: [HKQuantitySample] = [] } Updating samples only does not propagate to my view.
7
8
2.6k
Jun ’23
iOS17 UITextView inputView becomFirstResponder does not work
Simplely, when we set UITextView.inputView and then call becomeFirstResponder, but the custom inputView could not show expectedly just like before. We test this code in iOS17 and below, while only iOS17 does not work. And xcode console print these logs: Failed to retrieve snapshot. -[RTIInputSystemClient remoteTextInputSessionWithID:performInputOperation:] perform input operation requires a valid sessionID -[RTIInputSystemClient remoteTextInputSessionWithID:performInputOperation:] perform input operation requires a valid sessionID -[RTIInputSystemClient remoteTextInputSessionWithID:performInputOperation:] perform input operation requires a valid sessionID -[RTIInputSystemClient remoteTextInputSessionWithID:performInputOperation:] perform input operation requires a valid sessionID Unsupported action selector setShiftStatesNeededInDestination:autoShifted:shiftLocked: Unsupported action selector setShiftStatesNeededInDestination:autoShifted:shiftLocked: Unsupported action selector setShiftStatesNeededInDestination:autoShifted:shiftLocked: Unsupported action selector setShiftStatesNeededInDestination:autoShifted:shiftLocked:
49
17
35k
Jun ’23
SwiftUI NavigationSplitView like Apple Music
In the Apple Music app on iPad (horizontal size class == .regular), when a selection is made from the Split View sidebar, the detail switches to a separate UINavigationController for that selection, where we can push/pop views. If we make a different selection from the sidebar, we get another UINavigationController to manipulate. If we return to the first selection, the detail view is still showing the stack contents for that controller. I am trying to get the same behavior from NavigationSplitView in SwiftUI, but the detail view will reset its presented controller to its root. I think this is because NavigationSplitView uses whatever NavigationStack it finds in the detail hierarchy to manage its contents, effectively erasing the per-view stack contents. I have tried various methods of saving and restoring the navigation path without any luck. Any ideas on how to approach this? I have included a very simple example to show what I'm talking about. import SwiftUI struct ExampleView: View { enum Selection: String, CaseIterable { case letters case numbers } @State private var selection: Selection? var body: some View { NavigationSplitView { List(selection: $selection) { ForEach(Selection.allCases, id: \.self) { selection in NavigationLink(value: selection) { Text(selection.rawValue.capitalized) } } } .navigationTitle("Sidebar") } detail: { switch selection { case .letters: self.lettersView case .numbers: self.numbersView default: Text("Make a selection") } } } var lettersView = LettersView() var numbersView = NumbersView() } struct ExampleView_Previews: PreviewProvider { static var previews: some View { ExampleView() } } // MARK: - struct LettersView: View { private let letters = ["a", "b", "c", "d", "e", "f"] @State private var path = NavigationPath() var body: some View { NavigationStack(path: $path) { List { ForEach(letters, id: \.self) { letter in NavigationLink(value: letter) { Text(letter.uppercased()) } } } .navigationTitle("Letters") .navigationDestination(for: String.self) { letter in Text(letter.uppercased()).font(.largeTitle) } } } } // MARK: - struct NumbersView: View { private let numbers = Array(0..<6) @State private var path = NavigationPath() var body: some View { NavigationStack(path: $path) { List { ForEach(numbers, id: \.self) { number in NavigationLink(value: number) { Text(String(number)) } } } .navigationTitle("Numbers") .navigationDestination(for: Int.self) { number in Text(String(number)).font(.largeTitle) } } } }
1
2
931
Jun ’23
No macro named 'Preview' - error
So I am trying to move an old project from ios16 to ios17... wanted to play around with the new previews, and animations and first error I get is the above. When I create a new project I can use the macro just fine. What is more: when I add a new swiftUI file I get the same error with the #Preview macro. I went through the project and target settings, making sure everything is set to ios17 and Swift5, but can't find any other settings. Cleared the build cache and rebuilt from scratch. Hoping someone else ran onto the same problem and found a solution? Without using #Preview
3
0
1.5k
Jun ’23
VisionOS Set Default Window Size
Is it possible to specify a default window size for a 2D window in visionOS? I know this is normally achieved by modifying the WindowGroup with .defaultSize(width:height:), but I get an error that this was not included in "xrOS". I am able to specify .defaultSize(width:height:depth:) for a volumetric window, but this doesn't have any effect when applied to a 2D one.
11
3
4.5k
Jun ’23
Pass @Query filter predicate from parent view in SwiftData
Hi all, I am starting using the new amazing SwiftData and I really like it! I have a question regarding how to pass the filter predicate from the parent view. In my app I have a simple case where I have a package that contains multiple items. When I package is selected a view is pushed with the list of items in that package. The Items view has a query as following: struct ScoreListView: View { [.....] @Query(filter: #Predicate<SWDItem> { item in item.package?.id == selectedPackage.id } ,sort: \.timestamp) var items: [SWDItem] [.....] var body: some View { [...] } The problem is that selectedPackage is not "yet" available when defining the @Query and I have the classic error "Cannot use instance member 'selectedPackage' within property initializer; property initializers run before 'self' is available". How can I structure the code to have the selected package available when the @Query is defined? Thank you a lot
6
0
3.1k
Jun ’23