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

A Summary of the WWDC25 Group Lab - UI Frameworks
At WWDC25 we launched a new type of Lab event for the developer community - Group Labs. A Group Lab is a panel Q&A designed for a large audience of developers. Group Labs are a unique opportunity for the community to submit questions directly to a panel of Apple engineers and designers. Here are the highlights from the WWDC25 Group Lab for UI Frameworks. How would you recommend developers start adopting the new design? Start by focusing on the foundational structural elements of your application, working from the "top down" or "bottom up" based on your application's hierarchy. These structural changes, like edge-to-edge content and updated navigation and controls, often require corresponding code modifications. As a first step, recompile your application with the new SDK to see what updates are automatically applied, especially if you've been using standard controls. Then, carefully analyze where the new design elements can be applied to your UI, paying particular attention to custom controls or UI that could benefit from a refresh. Address the large structural items first then focus on smaller details is recommended. Will we need to migrate our UI code to Swift and SwiftUI to adopt the new design? No, you will not need to migrate your UI code to Swift and SwiftUI to adopt the new design. The UI frameworks fully support the new design, allowing you to migrate your app with as little effort as possible, especially if you've been using standard controls. The goal is to make it easy to adopt the new design, regardless of your current UI framework, to achieve a cohesive look across the operating system. What was the reason for choosing Liquid Glass over frosted glass, as used in visionOS? The choice of Liquid Glass was driven by the desire to bring content to life. The see-through nature of Liquid Glass enhances this effect. The appearance of Liquid Glass adapts based on its size; larger glass elements look more frosted, which aligns with the design of visionOS, where everything feels larger and benefits from the frosted look. What are best practices for apps that use customized navigation bars? The new design emphasizes behavior and transitions as much as static appearance. Consider whether you truly need a custom navigation bar, or if the system-provided controls can meet your needs. Explore new APIs for subtitles and custom views in navigation bars, designed to support common use cases. If you still require a custom solution, ensure you're respecting safe areas using APIs like SwiftUI's safeAreaInset. When working with Liquid Glass, group related buttons in shared containers to maintain design consistency. Finally, mark glass containers as interactive. For branding, instead of coloring the navigation bar directly, consider incorporating branding colors into the content area behind the Liquid Glass controls. This creates a dynamic effect where the color is visible through the glass and moves with the content as the user scrolls. I want to know why new UI Framework APIs aren’t backward compatible, specifically in SwiftUI? It leads to code with lots of if-else statements. Existing APIs have been updated to work with the new design where possible, ensuring that apps using those APIs will adopt the new design and function on both older and newer operating systems. However, new APIs often depend on deep integration across the framework and graphics stack, making backward compatibility impractical. When using these new APIs, it's important to consider how they fit within the context of the latest OS. The use of if-else statements allows you to maintain compatibility with older systems while taking full advantage of the new APIs and design features on newer systems. If you are using new APIs, it likely means you are implementing something very specific to the new design language. Using conditional code allows you to intentionally create different code paths for the new design versus older operating systems. Prefer to use if #available where appropriate to intentionally adopt new design elements. Are there any Liquid Glass materials in iOS or macOS that are only available as part of dedicated components? Or are all those materials available through new UIKit and AppKit views? Yes, some variations of the Liquid Glass material are exclusively available through dedicated components like sliders, segmented controls, and tab bars. However, the "regular" and "clear" glass materials should satisfy most application requirements. If you encounter situations where these options are insufficient, please file feedback. If I were to create an app today, how should I design it to make it future proof using Liquid Glass? The best approach to future-proof your app is to utilize standard system controls and design your UI to align with the standard system look and feel. Using the framework-provided declarative API generally leads to easier adoption of future design changes, as you're expressing intent rather than specifying pixel-perfect visuals. Pay close attention to the design sessions offered this year, which cover the design motivation behind the Liquid Glass material and best practices for its use. Is it possible to implement your own sidebar on macOS without NSSplitViewController, but still provide the Liquid Glass appearance? While technically possible to create a custom sidebar that approximates the Liquid Glass appearance without using NSSplitViewController, it is not recommended. The system implementation of the sidebar involves significant unseen complexity, including interlayering with scroll edge effects and fullscreen behaviors. NSSplitViewController provides the necessary level of abstraction for the framework to handle these details correctly. Regarding the SceneDelagate and scene based life-cycle, I would like to confirm that AppDelegate is not going away. Also if the above is a correct understanding, is there any advice as to what should, and should not, be moved to the SceneDelegate? UIApplicationDelegate is not going away and still serves a purpose for application-level interactions with the system and managing scenes at a higher level. Move code related to your app's scene or UI into the UISceneDelegate. Remember that adopting scenes doesn't necessarily mean supporting multiple scenes; an app can be scene-based but still support only one scene. Refer to the tech note Migrating to the UIKit scene-based life cycle and the Make your UIKit app more flexible WWDC25 session for more information.
Topic: UI Frameworks SubTopic: General
0
0
551
Jun ’25
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
(iOS 17 & 18) Using QLPreviewController in specific app, added text colour reverts to black on text edit
In the company that I work we have a huge app and we have implemented an image annotation feature using the QLPreviewController but there is a bug where even with an OOTB implementation of the QLPreviewController, when I add a text, change the colour of that text and then double click on the text to edit it, it reverts back to black. I tried the same implementation in a sample app but I couldn't reproduce the bug hence it is not a bug with the library but something with the app interacting with the library. I was wondering if anyone can provide any suggestion with what the reason may be, as sadly I cannot provide any code examples as that would break company code. From my research what I found strange is that when I double click the coloured text and it goes to black, then undo it its as if that was not a recorded event as the undo goes back to the step before the text was coloured meaning it replaces the colour changing event rather than recording it as a new event that can be undone. If any has any suggestion please help me as I am quite stuck. 🙏
1
0
744
Sep ’24
trailingSwipeActionsConfigurationProvider causes shadow effect on UICollectionViewListCell gone
Currently, I have achieve shadow and corner effect for UICollectionViewListCell, using the following code. UICollectionViewListCell class NoteCell: UICollectionViewListCell { override func awakeFromNib() { super.awakeFromNib() initShadow() initCorner() } private func updateShadowColor() { // Determine the shadow color based on the current interface style let shadowUIColor = UIColor.label self.layer.shadowColor = shadowUIColor.cgColor } private func initShadow() { // https://www.hackingwithswift.com/example-code/uikit/how-to-add-a-shadow-to-a-uiview self.layer.shadowOpacity = 0.3 self.layer.shadowOffset = CGSize(width: 0.5, height: 0.5) self.layer.shadowRadius = 2 self.layer.masksToBounds = false self.updateShadowColor() // Remove the following two lines if you experience any issues with shadow rendering: self.layer.shouldRasterize = true self.layer.rasterizationScale = UIScreen.main.scale } private func initCorner() { var backgroundConfig = UIBackgroundConfiguration.listPlainCell() backgroundConfig.backgroundColor = .systemBackground backgroundConfig.cornerRadius = 16 self.backgroundConfiguration = backgroundConfig } layout private func layoutConfig() -> UICollectionViewCompositionalLayout { let layout = UICollectionViewCompositionalLayout { section, layoutEnvironment in var config = UICollectionLayoutListConfiguration(appearance: .plain) config.headerMode = .none config.footerMode = .none config.showsSeparators = false config.headerTopPadding = 0 config.backgroundColor = nil config.trailingSwipeActionsConfigurationProvider = { [weak self] indexPath in guard let self = self else { return nil } // Knowing what we are tapping at. var snapshot = dataSource.snapshot() let sectionIdentifier = snapshot.sectionIdentifiers[indexPath.section] let itemIdentifiers = snapshot.itemIdentifiers(inSection: sectionIdentifier) let itemIdentifier: NoteWrapper = itemIdentifiers[indexPath.item] let deleteHandler: UIContextualAction.Handler = { action, view, completion in completion(true) // TODO: //snapshot.reloadItems([itemIdentifier]) } let deleteAction = UIContextualAction(style: .normal, title: "Trash", handler: deleteHandler) var swipeActionsConfiguration = UISwipeActionsConfiguration(actions: [ deleteAction, ]) deleteAction.image = UIImage(systemName: "trash") deleteAction.backgroundColor = UIColor.systemRed swipeActionsConfiguration.performsFirstActionWithFullSwipe = false return swipeActionsConfiguration } // https://developer.apple.com/forums/thread/759987 let layoutSection = NSCollectionLayoutSection.list(using: config, layoutEnvironment: layoutEnvironment) layoutSection.interGroupSpacing = 16 // Distance between item. layoutSection.contentInsets = NSDirectionalEdgeInsets( top: 16, // Distance between 1st item and its own header. leading: 16, bottom: 16, // Distance of last item and other header/ bottom edge. trailing: 16 ) return layoutSection } return layout } This is the outcome. However, when I perform swipe action, the shadow effect is gone. Do you have any idea how I can resolve such? Thanks.
0
0
363
Oct ’24
[UITextView becomeFirstResponder] crash with [__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]
I am trying to set my UITextView as the first responder with [self.textView becomeFirstResponder] when my view controller called viewDidAppear. But sometimes it will cause crash with the error: [__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0] all I did is just: - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self.textView becomeFirstResponder]; } So if anyone can tell me what happened and how to do? when I call the [self.textView becomeFirstResponder], what will be insert into the responders list? self.textView itself? Thanks very much!
0
0
375
Sep ’24
Wait for some completion in main thread using Catalyst environment
I need to bring an iOS application to macOS using Catalyst. This application contain parts where it waits for a button to be pressed in the main thread, using [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; in a while loop to allow some dispatching while waiting. I know that this is not good style, but I need to convert this old source code and mentioned that when using this part of code under Catalyst, the main thread will not dispatch. So the button cannot be clicked, and a beach ball appears after two seconds. I saw a similar construct for native macOS applications: NSEvent *event= [[NSApplication sharedApplication] nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate dateWithTimeIntervalSinceNow:0.1] inMode:NSDefaultRunLoopMode dequeue:YES]; if (event) { [[NSApplication sharedApplication] sendEvent:event]; } but I do not have access to NSEvent and NSApplication in a Catalyst environment. Question: I there any code snippet which I can use to achieve the above? I do not want to completely rewrite old code if there is a solution for this. Any ideas or hints are highly appreciated. Thank you! Markus
4
0
575
Oct ’24
User Defined Runtime Attributes
You used to be able to use the "User Defined Runtime Attributes" section in Interface Builder to add attributes such as layer.borderColor, layer.borderWidth, layer.cornerRadius, etc. I can still enter these values, but they don't do anything. What happened? I can still set them via code and then they work, but it's much more convenient to be able to do it in interface builder.
Topic: UI Frameworks SubTopic: UIKit
0
0
451
Oct ’24
MapCameraPosition camera region rect item all of them are nil
@State var position : MapCameraPosition = .userLocation(fallback: .region(.defaultRegion)) Map(position: $position) {} .onAppear { Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in print("check.position",position.camera,position.region,position.rect,position.item) } } All of the value are nil, so how do I get the current camera position?? check.position nil nil nil nil check.position nil nil nil nil check.position nil nil nil nil check.position nil nil nil nil check.position nil nil nil nil check.position nil nil nil nil check.position nil nil nil nil check.position nil nil nil nil It is always nil (even if I manually move around the Map with a finger)
1
0
409
Oct ’24
iOS 18 update causes toolbar display regression
Hi there, I'm having an app developed in the last weeks, and recently I'm testing it on iOS 18. This following piece of UI code has diff between iOS 18 and iOS version lower than 18. I have a NavigationStack in my homeView, and the display difference is for its toolbar in one destination. I've tried both approaches in code, with header variable or ToolbarItemGroup used directly in the toolbar modifier, both would result in there being a spacer between the body VStack and toolbar, which is unexpected. Here's the code and a demo screenshot. var body: some View { // header VStack(alignment: .leading) { notificationView( iconKey: "ErrorCircle", contentKey: "receivedFile.notification.noNetwork.content" ) fileListView } .toolbar { // header ToolbarItemGroup(placement: .principal) { Button { dismiss() } label: { Image(systemName: "chevron.backward") } .background(Color.yellow) Spacer() Text(LocalizedStringKey("title")) .font( .system(size: 17) .weight(.semibold) ) .background(Color.yellow) Spacer() Button { print("click") } label: { Text("Click") } .background(Color.yellow) } } .navigationBarBackButtonHidden() .onAppear { refreshAllFiles() } } @ToolbarContentBuilder private var header: some ToolbarContent { ToolbarItem(placement: .topBarLeading) { Button { dismiss() } label: { Image(systemName: "chevron.backward") } .background(Color.yellow) } ToolbarItem(placement: .principal) { Text(LocalizedStringKey("receivedFileList.title")) .font( .system(size: 17) .weight(.semibold) ) .background(Color.yellow) } ToolbarItem(placement: .topBarTrailing) { Button { print("click for jumping") } label: { Text("Click for jumping") } .background(Color.yellow) } } Hope I can get some help from the forum on the usage. If not fixable, may I know if this is a known issue that would be fixed in the next upgrades.
3
0
1.1k
Oct ’24
Unable to update NSProgressIndicator for the dock Icon
I have created a progress indicator to simulate some progressing download task in the dock icon. However, I can see the progress bar appearing in the dock icon but it is not getting updated when I invoked the updateProgress() method. Ideally it should have updated it, and I m not able to figure out the reason? I have creating the same NSProgressIndicator on an NSWindow and it works to update the progress bar with the same code. Anything that I m missing to understand here? Below is the code I m using: class AppDelegate: NSObject, NSApplicationDelegate { var progressIndicator: NSProgressIndicator! let dockTile = NSApp.dockTile func applicationWillFinishLaunching(_ notification: Notification) { // Step 1: Create a progress bar (NSProgressIndicator) progressIndicator = NSProgressIndicator(frame: NSRect(x: 10, y: 10, width: 100, height: 20)) progressIndicator.isIndeterminate = false progressIndicator.minValue = 0.0 progressIndicator.maxValue = 100.0 progressIndicator.doubleValue = 0.0 progressIndicator.style = .bar dockTile.contentView = progressIndicator dockTile.display() //// Update the progress bar for demonstration DispatchQueue.main.asyncAfter(deadline: .now() + 1) { self.updateProgress(50) } } func updateProgress(_ value: Double) { progressIndicator.doubleValue = value NSApp.dockTile.display() } }
Topic: UI Frameworks SubTopic: AppKit Tags:
0
0
475
Oct ’24
Split View DoubleColumn Mode
Hi, When SplitView is in detailsOnly and I swipe from left side the sidebar appears as popover above the details content, but when I try to open it manually by settings the columnVisibility to doubleColumn it pushes the details view and shows, so haw to make it appear as poorer ? Kind Regards
Topic: UI Frameworks SubTopic: SwiftUI
0
0
182
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
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
Application being hang when use UIActivityViewController
Our application uses UIActivityViewController to share files, and we have received numerous complaints from users stating that triggering the share functionality causes the app to hang, making it unresponsive. Users are instructed to restart their devices, after which the sharing function works normally. 0 libsystem_kernel.dylib 0x00000001daae2708 mach_msg2_trap + 8 1 libsystem_kernel.dylib 0x00000001daae5e18 mach_msg2_internal + 80 2 libsystem_kernel.dylib 0x00000001daae5d30 mach_msg_overwrite + 424 3 libsystem_kernel.dylib 0x00000001daae5b7c mach_msg + 24 4 libdispatch.dylib 0x00000001926d1f14 _dispatch_mach_send_and_wait_for_reply + 544 5 libdispatch.dylib 0x00000001926d22b4 dispatch_mach_send_with_result_and_wait_for_reply + 60 6 libxpc.dylib 0x0000000211c1b84c xpc_connection_send_message_with_reply_sync + 256 7 Foundation 0x00000001891e98d8 __NSXPCCONNECTION_IS_WAITING_FOR_A_SYNCHRONOUS_REPLY__ + 16 8 Foundation 0x00000001891e6034 -[NSXPCConnection _sendInvocation:orArguments:count:methodSignature:selector:withProxy:] + 2160 9 Foundation 0x000000018924fda4 -[NSXPCConnection _sendSelector:withProxy:arg1:] + 116 10 Foundation 0x000000018924fa18 _NSXPCDistantObjectSimpleMessageSend1 + 60 11 ShareSheet 0x00000001a89e7b2c -[SFShareSheetSlotManager ensureConnectionEstablished] + 220 12 ShareSheet 0x00000001a89e7960 -[SFShareSheetSlotManager ensureXPCStarted] + 440 13 ShareSheet 0x00000001a89e7f90 -[SFShareSheetSlotManager activate] + 188 14 ShareSheet 0x00000001a8a0020c -[SHSheetServiceManager init] + 100 15 ShareSheet 0x00000001a89f347c -[SHSheetInteractor _setupServiceManagerIfNeeded] + 52 16 ShareSheet 0x00000001a89f1998 -[SHSheetInteractor initWithContext:] + 76 17 ShareSheet 0x00000001a89dd450 +[SHSheetFactory createMainPresenterWithContext:] + 204 18 ShareSheet 0x00000001a89d3e90 -[UIActivityViewController _createMainPresenterIfNeeded] + 84 19 ShareSheet 0x00000001a89d53c4 -[UIActivityViewController _viewControllerPresentationDidInitiate] + 104 20 UIKitCore 0x000000018d247fd0 -[UIViewController _presentViewController:withAnimationController:completion:] + 220 21 UIKitCore 0x000000018d24a71c __63-[UIViewController _presentViewController:animated:completion:]_block_invoke + 88 22 UIKitCore 0x000000018d244ad0 -[UIViewController _performCoordinatedPresentOrDismiss:animated:] + 532 23 UIKitCore 0x000000018d2447c0 -[UIViewController _presentViewController:animated:completion:] + 324 24 UIKitCore 0x000000018d2445cc -[UIViewController presentViewController:animated:completion:] + 164 Above is the stack trace when the hang occurs. We found that UIActivityViewController ultimately calls xpc_connection_send_message_with_reply_sync, which synchronously waits for messages on the main thread, leading to the hang. Are there any suggestions that can avoid this waiting forever hang?
Topic: UI Frameworks SubTopic: UIKit Tags:
2
0
420
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
UIViewRepresentable animations
I've tried to animate custom UIViewRepresentable with SwitfUI animations, but it doesn't work. It just sets value without interpolation. What should i do to use interpolation values in UIKit views? My example shows two "progress bars" red one is UIKit view, blue one is SwiftUI version. Sliders controls value directly, randomize button changes value to random with 5s animation. When I press button SwiftUI progress bar animates exactly as it should, but UIKit's one just jumps to final position. Set block of animatableData inside Animatable extension not called. How can I use SwiftUI animation value interpolations for UIKit? import SwiftUI import UIKit class UIAnimationView: UIView { var progress: CGFloat = 0.5 { didSet { if self.progressConstraint != nil, self.innerView != nil { self.removeConstraint(self.progressConstraint!) } let progressConstraint = NSLayoutConstraint( item: innerView!, attribute: .trailing, relatedBy: .equal, toItem: self, attribute: .trailing, multiplier: min(1.0, max(0.0001, progress)), constant: 0 ) self.addConstraint(progressConstraint) self.progressConstraint = progressConstraint self.layoutIfNeeded() } } var innerView: UIView? private var progressConstraint: NSLayoutConstraint? public override init(frame: CGRect) { super.init(frame: frame) self.performInit() } public required init?(coder: NSCoder) { super.init(coder: coder) self.performInit() } private func performInit() { let innerView = UIView() innerView.translatesAutoresizingMaskIntoConstraints = false self.addSubview(innerView) self.leadingAnchor.constraint(equalTo: innerView.leadingAnchor).isActive = true self.topAnchor.constraint(equalTo: innerView.topAnchor).isActive = true self.bottomAnchor.constraint(equalTo: innerView.bottomAnchor).isActive = true let progressConstraint = NSLayoutConstraint( item: innerView, attribute: .trailing, relatedBy: .equal, toItem: self, attribute: .trailing, multiplier: progress, constant: 0 ) self.progressConstraint = progressConstraint self.addConstraint(progressConstraint) self.innerView = innerView self.innerView!.backgroundColor = UIColor.red self.backgroundColor = UIColor.black } } struct AnimationTest: UIViewRepresentable { var progress: CGFloat typealias UIViewType = UIAnimationView func updateUIView(_ uiView: UIAnimationView, context: Context) { print("progress: \(progress) \(context.transaction.isContinuous)") uiView.progress = progress } func makeUIView(context: Context) -> UIAnimationView { let view = UIAnimationView() view.progress = progress return view } } extension AnimationTest: Animatable { var animatableData: CGFloat { get { return progress } set { print("Animation \(newValue)") progress = newValue } } } struct AnimationDebug: View { @State var progress: CGFloat = 0.75 var body: some View { VStack { AnimationTest(progress: progress) Spacer() VStack { Slider(value: $progress, in: 0...1) { Text("Progress") } } GeometryReader { gr in Color.blue .frame( width: gr.size.width * progress, height: 48) } .frame(height: 48) Button("Randomize") { withAnimation(Animation.easeInOut(duration: 5)) { progress = CGFloat.random(in: 0...1) } } } } } struct AnimationTest_Previews: PreviewProvider { static var previews: some View { AnimationDebug() } }
2
0
1.5k
Oct ’24
Disable Swipe in SwiftUI NavigationView
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. In tried this way , but it doesn't work for me: struct DisableSwipeBackGesture: ViewModifier { func body(content: Content) -> some View { content .background(DisableBackSwipeGestureView()) } } struct DisableBackSwipeGestureView: UIViewControllerRepresentable { typealias UIViewControllerType = DisableSwipeBackViewController func makeUIViewController(context: Context) -> DisableSwipeBackViewController { DisableSwipeBackViewController() } 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?
0
0
344
Sep ’24
Text right-to-left direction with mathematical text
Hi, I am writing a calculator app in Swift 5 and decided to support eastern asian numerals to make it a bit interesting. The numeric display itself works well in Arabic langauge setting, but I have a protocol view that reports the entered data and results. I do it in a Grid with two Text items, one for the input and one for the result. The result contains a numeric string in U0660... arabic numerals, and that looks fine. The input is a construct looking like Text(number1) + Text(" ") + Text(operation), so it goes into a single Grid cell. The standard version looks like this: but the arabic version shows the numbers and operation symbols in the wrong sequence: I guess that has something to do with the mathematical symbols such as + and = simply register as ltr Text and confuse the text layout. If I localize π, the result looks different: So my question would be: How do I force a fragment such as Text(" +") to go in rtl direction? Is this a SwiftUI topic or doesit go deeper? I am looking at the Text element now, but may be that is the wrong approach.
Topic: UI Frameworks SubTopic: SwiftUI
6
0
440
Oct ’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