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

Swift pressesBegan no longer works iOS 18?
Previously this code would trigger fine on pressesBegan in iOS 17 and earlier versions, but no longer works in iOS 18. How can I start capturing pressesBegan in iOS 18? It seems like UIResponder is just not capturing the keyboard anymore? struct ContentView: View { var body: some View { KeyBoardView() } } //To Use in SwiftUI struct KeyBoardView: UIViewRepresentable{ func makeUIView(context: Context) -> KeyEventView { KeyEventView() } func updateUIView(_ uiView: KeyEventView, context: Context) { } class KeyEventView: UIView { init() { super.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) { print("test") } } }
0
0
275
Oct ’24
Re-Visiting NSViewController.loadView's behaviour in 2024 and under macOS 15...
This is a post down memory lane for you AppKit developers and Apple engineers... TL;DR: When did the default implementation of NSViewController.loadView start making an NSView when there's no matching nib file? (I'm sure that used to return nil at some point way back when...) If you override NSViewController.loadView and call [super loadView] to have that default NSView created, is it safe to then call self.view within loadView? I'm refactoring some old Objective-C code that makes extensive use of NSViewController without any use of nibs. It overrides loadView, instantiates all properties that are views, then assigns a view to the view controller's view property. This seems inline with the documentation and related commentary in the header. I also (vaguely) recall this being a necessary pattern when not using nibs: @interface MyViewController: NSViewController // No nibs // No nibName @end @implementation MyViewController - (void)loadView { NSView *hostView = [[NSView alloc] initWithFrame:NSZeroRect]; self.button = [NSButton alloc...]; self.slider = [NSSlider alloc...]; [hostView addSubview:self.button]; [hostView addSubview:self.slider]; self.view = hostView; } @end While refactoring, I was surprised to find that if you don't override loadView and do all of the setup in viewDidLoad instead, then self.view on a view controller is non-nil, even though there was no nib file that could have provided the view. Clearly NSViewController has realized that: There's no nib file that matches nibName. loadView is not overridden. Created an empty NSView and assigned it to self.view anyways. Has this always been the behaviour or did it change at some point? I could have sworn that if there as no matching nib file and you didn't override loadView, then self.view would be nil. I realize some of this behaviour changed in 10.10, as noted in the header, but there's no mention of a default NSView being created. Because there are some warnings in the header and documentation around being careful when overriding methods related to view loading, I'm curious if the following pattern is considered "safe" in macOS 15: - (void)loadView { // Have NSViewController create a default view. [super loadView]; self.button = [NSButton...]; self.slider = [NSSlider...]; // Is it safe to call self.view within this method? [self.view addSubview:self.button]; [self.view addSubview:self.slider]; } Finally, if I can rely on NSViewController always creating an NSView for me, even when a nib is not present, then is there any recommendation on whether one should continue using loadView or instead move code the above into viewDidLoad? - (void)viewDidLoad { self.button = [NSButton...]; self.slider = [NSSlider...]; // Since self.view always seems to be non-nil, then what // does loadView offer over just using viewDidLoad? [self.view addSubview:self.button]; [self.view addSubview:self.slider]; } This application will have macOS 15 as a minimum requirement.
0
1
451
Nov ’24
Setting value of NSSlider resets mouse cursor
Hi, in my macOS app I am modifying the mouse cursor image for some user interactions. I also have an NSSlider in the app which can be changed programmatically by setting its doubleValue. I've noticed that whenever the slider is set programmatically the custom mouse cursor is lost and changes back to an arrow. This doesn't happen if other controls are changed programmatically, e.g. the progress bar. Any ideas on how I can prevent this happening?
Topic: UI Frameworks SubTopic: AppKit
0
0
329
Sep ’24
Main Thread blocked by synchronous property query (AVPlayer)
I want to play remote videos using an AVPlayer in my SwiftUI App. However, I can't fix the error: "Main thread blocked by synchronous property query on not-yet-loaded property (PreferredTransform) for HTTP(S) asset. This could have been a problem if this asset were being read from a slow network." My code looks like this atm: struct CustomVideoPlayer: UIViewControllerRepresentable { let myUrl: URL func makeCoordinator() -> Coordinator { return Coordinator(self) } func makeUIViewController(context: Context) -> AVPlayerViewController { let playerItem = AVPlayerItem(url: myUrl) let player = AVQueuePlayer(playerItem: playerItem) let playerViewController = AVPlayerViewController() playerViewController.player = player context.coordinator.setPlayerLooper(player: player, templateItem: playerItem) playerViewController.delegate = context.coordinator playerViewController.beginAppearanceTransition(true, animated: false) return playerViewController } func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) { } static func dismantleUIViewController(_ uiViewController: AVPlayerViewController, coordinator: ()) { uiViewController.beginAppearanceTransition(false, animated: false) } class Coordinator: NSObject, AVPlayerViewControllerDelegate { var parent: CustomVideoPlayer var player: AVPlayer? = nil var playerLooper: AVPlayerLooper? = nil init(_ parent: CustomVideoPlayer) { self.parent = parent super.init() } func setPlayerLooper(player: AVQueuePlayer, templateItem: AVPlayerItem) { self.player = player playerLooper = AVPlayerLooper(player: player, templateItem: templateItem) } } } I already tried creating the AVPlayerItem/AVAsset on a background thread and I also tried loading the properties asynchronously before setting the player in makeUIViewController: let player = AVQueuePlayer(playerItem: nil) ... Task { let asset = AVAsset(url: myUrl) let _ = try await asset.load(.preferredTransform) let item = AVPlayerItem(asset: asset) player.replaceCurrentItem(with: item) } Nothing seems to fix the issue (btw: the main thread is actually blocked, there is a noticable animation hitch). Any help is much appreciated.
Topic: UI Frameworks SubTopic: General
0
5
787
Nov ’24
How to set followsUserLocation and define a custom camera distance dynamically using MapKit for SwiftUI ?
Hello, I've created an app that follows the user as they navigate through public transport. I want the camera to follow the user and at the same time I want the camera distance (elevation) to change dynamically depending on speed and other factors. I've tried a first approach using camera keyframes, but I've noticed a lot of crashes when the app comes back to the foreground. .mapCameraKeyframeAnimator(trigger: cameraFrame) { camera in KeyframeTrack(\MapCamera.centerCoordinate) { LinearKeyframe(cameraFrame.center, duration: cameraFrame.duration, timingCurve: cameraFrame.curve) } KeyframeTrack(\MapCamera.distance) { LinearKeyframe(cameraFrame.distance, duration: cameraFrame.duration, timingCurve: cameraFrame.curve) } } Some logs mention wrong center coordinates (nan, nan) but when I print them, it's show me valid coordinates. I've also tried manually setting the camera for each position update, but the result is not smooth. position = .camera( .init(.init( lookingAtCenter: newPosition, fromDistance: cameraElevation, pitch: .zero, heading: .zero) ) ) What's the best way to achieve this?
0
0
303
Nov ’24
ARVR RealityView Showing left Camera view Entity near more than the right view
I have this code to make ARVR Stereo View To Be Used in VR Box Or Google Cardboard, it uses iOS 18 New RealityView but for some reason the left side showing the Entity (Box) more near to the camera than the right side which make it not identical, I wonder is this a bug and need to be fixed or what ? thanx Here is the code import SwiftUI import RealityKit struct ContentView : View { let anchor1 = AnchorEntity(.camera) let anchor2 = AnchorEntity(.camera) var body: some View { HStack (spacing: 0){ MainView(anchor: anchor1) MainView(anchor: anchor2) } .background(.black) } } struct MainView : View { @State var anchor = AnchorEntity() var body: some View { RealityView { content in content.camera = .spatialTracking let item = ModelEntity(mesh: .generateBox(size: 0.25), materials: [SimpleMaterial()]) anchor.addChild(item) content.add(anchor) anchor.position.z = -1.0 anchor.orientation = .init(angle: .pi/4, axis:[0,1,1]) } } } And Here is the View
0
0
428
Nov ’24
Suddenly getting "Trailing closure passed to parameter of type 'Visibility' that does not accept a closure" for toolbars
Not sure exactly what’s going on here. I’ve been building out this little app for the past couple of weeks using Xcode 16 betas, and in a couple of places I have code like this: EditItemView(item: inItem) .toolbar { ToolbarItem { Button(action: { self.printLabel(item: inItem) }) { Label("Print Label", systemImage: "printer.filled.and.paper") } } } Now all of a sudden I'm getting an error on .toolbar: “Trailing closure passed to parameter of type 'Visibility' that does not accept a closure.” Looking at the comment for toolbar, it says this method "specifies the visibility," which is a weird thing for it to do with a name like that. But it also has a deprecation tag that I don't quite understand: @available(macOS, introduced: 13.0, deprecated: 100000.0, renamed: "toolbarVisibility(_:for:)"). The name change makes sense, given the description. But what is the huge deprecation version number? Just a hack? And why is this code no longer compiling? As I'm commenting out instances of this, all my toolbars are failing in this way. ETA: yeah, I finally found the right declaration of .toolbar: func toolbar<Content>(@ViewBuilder content: () -> Content) -> some View where Content : View. It's no longer choosing that one. I hate Swift sometimes. ETA2: I finally whittled it down to it not liking Label for some reason. Replacing that with Image works. But of course, the compiler won't tell me why. ETA3: It's worse than I thought: I tried to make a small test case for a bug, and Label works just fine. Why does my code not?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
0
1
700
Oct ’24
Hide TabItems?
Is there really no way to hide a TabItem using the built-in TabView? I have 6 pages, but the 6th one I want hidden from the bottom tab bar, because I have a button that programmatically navigates to it on the navigation bar. I did not want to have to code a custom tab bar due to losing some useful features like pop to root in Navigation Stack.
0
0
244
Nov ’24
SwiftUI .fileImporter does not react to isPresented change.
I made a ImagePicker which worked pretty well. But when app get bigger it stops. Does not react to change isPresented value. As far I know I changed nothing around this part of an App. Also same thing happened in different place, another kind of picker. print ("HELL'o") never prints. Silence. struct ImagePicker: View { @Binding var imageSource: ImageSource @State var showFileImporter: Bool = false @EnvironmentObject var manager: Manager var body: some View { VStack { .... Button(action: { print("before", showFileImporter) showFileImporter = true print("after", showFileImporter) }, label: { Text("open Image") }) .buttonStyle(.borderless) .controlSize(.mini) }.fileImporter(isPresented: $showFileImporter, allowedContentTypes: [.png, .jpeg, .tiff], onCompletion: { result in print ("HELL'o") // Never prints switch result { case let .success(url): guard let _ = try? Data(contentsOf: url) else { return } .... case let .failure(error): print(error) } }) } } Does anybody have an idea what happened? I suspect some settings in completely different palce or bug or computer does not like me.
0
0
298
Dec ’24
SwiftUI Animation very Laggy on iOS 18 Release only
Dear Experts, I created a SwiftUI View (in a UIKit based project) whose objective is to display a short animation in the front of the user screen. I developed it 8 month ago in XCode 15 for iOS 17, no problems. But since iOS 18, I can observe huge lags on my animation only in Release app. The problem is not present in Debug app. I don't understand why this problem occurs, the animation is quite simple, it's just an offset deplacement. I tried many thing like: Show the animation with a UINavigationController Show the animation with a UIWindow Move the view with .position Remove the GeometryReader All other animation withAnimation and .animation Task and DispatchQueue Etc... I found that the laggy animation occurs when I set the Optimization Level for the Swift Compiler - Code Generation to Optimize for Speed [-O]. That's very strange because we had this option on Release for iOS 17 and we had no lags... I can share to you a Sample Repository with the configuration we have. https://github.com/Thibma/sample-animation-swiftui Today the only option I used is to develop this feature in UIKit but it's too bad to skip the SwiftUI opportunity. :/ If you have any ideas to resolve this, I take ! Thank you !
0
0
536
Dec ’24
custom EnvironmentKey lookup causes compiler error
I receive the following compiler error: Cannot infer key path from context; consider explicitly specifying a root type when I attempt an @Environment(\.foodRepository) lookup in a descendant View. Here's the setup in my App class: import SwiftUI import SwiftData @main struct BulkCutApp: App { private var foodRepository: FoodRepository = /* some code*/ var body: some Scene { WindowGroup { ContentView() .foodRepository(foodRepository) } } } extension View { func foodRepository(_ customValue: FoodRepository) -> some View { environment(\.foodRepository, customValue) } } extension EnvironmentValues { var foodRepository: FoodRepository { get { self[FoodRepositoryKey.self] } set { self[FoodRepositoryKey.self] = newValue } } } struct FoodRepositoryKey: EnvironmentKey { static var defaultValue: FoodRepository = FoodRepository(food:[]) } Nothing special in FoodRepository: @Observable class FoodRepository { var food: [Food] // more code }
0
0
257
Nov ’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
Lose my variables when my watch turn off
Hello guys, I have such a big coding problem since a half year now about data saving. I have a fitness app where we can add our exercices depend of the muscle, so you can choose it and then select your weight and number of repetitions and valid your exercise. But when I do my exercises and my watch screen is also turn off, my muscle and muscleExercise variables are going back to their default value. Here some code for you : @EnvironmentObject var dataManager: DataManager @Environment(\.modelContext) private var context @AppStorage("savedGroupName") private var savedGroupName: String = "" @AppStorage("savedExerciceName") private var savedExerciceName: String = "" @State var groupName: String = "À choisir" @State var ExerciceChoose: String = "À choisir" I use my variables here : HStack { Text("Muscle:") Spacer() NavigationLink(destination: MusclesView()) { Text(savedGroupName.isEmpty ? "À choisir" : savedGroupName) } .buttonStyle(PlainButtonStyle()) } .onAppear { savedGroupName = groupName } HStack { Text("Exercise:") Spacer() NavigationLink(destination: MuscleExercicesView(groupName: groupName, ExerciceChoose: ExerciceChoose)) { Text(savedExerciceName.isEmpty ? "À choisir" : savedExerciceName) } .onAppear { savedExerciceName = ExerciceChoose } .buttonStyle(PlainButtonStyle()) } The value of my muscle variable is taking in an other view : struct MusclesView: View { let muscleGroup = ExerciceData.muscleGroups var body: some View { NavigationStack { List(muscleGroup, id: \.name) { group in NavigationLink(destination: MuscleExercicesView(groupName: group.name, ExerciceChoose: "À choisir")) { Text(group.name) } } } } } #Preview { MusclesView() } and the value of the exerciseMuscle variable is also taking in an other view : ```import SwiftUI struct MuscleExercicesView: View { let exerciceGroup = ExerciceData.muscleGroups @State var groupName: String @State var ExerciceChoose: String var body: some View { if let group = ExerciceData.muscleGroups.first(where: { $0.name == groupName }) { List(group.exercices, id: \.id) { exercice in NavigationLink(exercice.name, destination: CurrentInformationsView(groupName: groupName, ExerciceChoose: exercice.name)) } /*.onTapGesture { print("Selected exercise: \(ExerciceChoose) for muscle group: \(groupName)") }*/ .navigationTitle(Text("Exercices pour \(groupName)")) } else { Text("Aucun exercice trouvé pour \(groupName)") .navigationTitle(Text("Erreur")) } } } #Preview { MuscleExercicesView(groupName: "Pectoraux", ExerciceChoose: "À choisir") } I tried many things (like userDefault, put my values in an array to save it etc..) to keep my variables with the same value during the session but nothing works. I wish I could have some help from you guys. Have a good day ! Cyrille
0
0
317
Oct ’24
crash while open UIActivityViewController only in iOS 15
let activityViewController = UIActivityViewController(activityItems: items, applicationActivities: []) activityViewController.popoverPresentationController?.barButtonItem = navigationController.topViewController?.navigationItem.rightBarButtonItem navigationController.present(activityViewController, animated: true, completion: nil) Crash logs ===================================================== *** Assertion failure in -[_UIActivityContentCollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:], UICollectionView.m:7588 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempted to dequeue a cell for a different registration or reuse identifier than the existing cell when reconfiguring an item, which is not allowed. You must dequeue a cell using the same registration or reuse identifier that was used to dequeue the cell originally to obtain the existing cell. Dequeued reuse identifier: UIActivityContentActionCellIdentifier; Original reuse identifier: UIActivityActionGroupCell; Existing cell: <UIActivityActionGroupCell: 0x10f19f220; baseClass = _UICollectionViewListCell; frame = (16 354; 358 30); clipsToBounds = YES; layer = <CALayer: 0x600000781740>>'
0
0
441
Oct ’24
NavigationStack in TabView not working as expected
Hi all! I encountered some strange behaviour that I cannot explain. When I have a NavigationStack that is embedded in a TabView, and that NavigationStack uses a NavigationPath that is stored within an ObservableObject, and the view within the NavigationStack gets its NavigationDestinations via an extension on the View object (either via a direct function or via a ViewExtension), the navigation doesn't work as expected, namely that back button seems to not pop views from the path. Consider the following example: struct ContentView: View { var body: some View { TabView { NavViewContainer1() .tabItem { Text("One") } NavViewContainer2() .tabItem { Text("Two") } } } } @MainActor class Model: ObservableObject { @Published var path = NavigationPath() } struct NavViewContainer1: View { @StateObject private var model = Model() var body: some View { NavigationStack(path: $model.path) { VStack { Text("1").font(.title).padding() NavigationLink(value: "One") { Text("Dest 1") } NavigationLink(value: "Two") { Text("Dest 2") } } .navigationDestination(for: String.self) { Text($0) } } } } struct NavViewContainer2: View { @StateObject private var model = Model() var body: some View { NavigationStack(path: $model.path) { VStack { Text("2").font(.title).padding() NavigationLink(value: "One") { Text("Dest 1") } NavigationLink(value: "Two") { Text("Dest 2") } } .setUpDestinations() } } } extension View { func setUpDestinations() -> some View { navigationDestination(for: String.self) { Text($0) } } } When clicking the destination buttons on the first tab (so in NavViewContainer1, I can go to a child view, back to the root, then click the other link to go to a child view and back to the root, all good. The route taken looks like this: Root > Dest 1 > Root > Dest 2 > Root. However, when I do the same in the second tab (NavViewContainer2), as soon as I click on the second destination, it seems like the first destination was not removed from the path, since clicking the back button in the second destination brings me to the first destination. The route taken looks like this: Root > Dest 1 > Root > Dest 2 > Dest 1 > Root. If I either move the view out of the TabView, move the path inside of the view with a @State variable or as in view 1 add the navigationDestinations directly, the path works as expected. Only the combination of TabView + NavigationPath in ObservableObject + view extension yields this behaviour. Am I missing something here, or is this a bug in the SwiftUI framework?
Topic: UI Frameworks SubTopic: SwiftUI
0
0
284
Oct ’24