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

Animation Issue: SwiftUI View Not Animating Height Changes in UIHostingController
Hello, I’m developing an app where I display a SwiftUI view inside a UIHostingController embedded within a UIKit ViewController. I’m trying to animate the height of the UIHostingController’s view based on a switch’s value, but the SwiftUI view doesn’t animate at all. Below is a simplified version of my code: class ViewController: UIViewController { private lazy var parentView: UIView = { let view = UIView() view.backgroundColor = .red view.translatesAutoresizingMaskIntoConstraints = false return view }() private lazy var hostingView: UIView = { let testView = TestView() let hostingController = UIHostingController(rootView: testView) let view = hostingController.view! view.translatesAutoresizingMaskIntoConstraints = false return view }() private lazy var button: UISwitch = { let button = UISwitch() button.addTarget(self, action: #selector(onClickSwitch(sender:)), for: .valueChanged) button.translatesAutoresizingMaskIntoConstraints = false return button }() private var hostingViewHeightConstraint: NSLayoutConstraint? override func viewDidLoad() { super.viewDidLoad() view.addSubview(parentView) parentView.addSubview(hostingView) parentView.addSubview(button) NSLayoutConstraint.activate([ parentView.topAnchor.constraint(equalTo: view.topAnchor), parentView.bottomAnchor.constraint(equalTo: view.bottomAnchor), parentView.leadingAnchor.constraint(equalTo: view.leadingAnchor), parentView.trailingAnchor.constraint(equalTo: view.trailingAnchor) ]) NSLayoutConstraint.activate([ hostingView.bottomAnchor.constraint(equalTo: parentView.bottomAnchor), hostingView.leadingAnchor.constraint(equalTo: parentView.leadingAnchor), hostingView.trailingAnchor.constraint(equalTo: parentView.trailingAnchor) ]) hostingViewHeightConstraint = hostingView.heightAnchor.constraint(equalTo: parentView.heightAnchor, multiplier: 0.5) hostingViewHeightConstraint?.isActive = true NSLayoutConstraint.activate([ button.centerXAnchor.constraint(equalTo: parentView.centerXAnchor), NSLayoutConstraint(item: button, attribute: .centerY, relatedBy: .equal, toItem: parentView, attribute: .centerY, multiplier: 0.25, constant: 0) ]) } @objc func onClickSwitch(sender: UISwitch) { hostingViewHeightConstraint?.isActive = false let multiplier: CGFloat = sender.isOn ? 0.25 : 0.5 hostingViewHeightConstraint = hostingView.heightAnchor.constraint(equalTo: parentView.heightAnchor, multiplier: multiplier) hostingViewHeightConstraint?.isActive = true UIView.animate(withDuration: 0.3) { self.view.layoutIfNeeded() } } } I’m looking for the behavior demonstrated in the video below: Does anyone have suggestions on how to achieve this?
0
1
200
Mar ’25
Putting buttons over SwiftUI map view
Has anyone gotten custom buttons to work on top of tvOS Map()? I've tried many variations of FocusState focusSection .defaultFocus() and as soon as the map appears at startup the buttons never get focus again. They are on a ZStack over the map. I could post code but truthfully nothing works for me. I'm wondering if anyone has successfully put focusable buttons on top of the map view.
0
0
242
Mar ’25
How to correctly and simply remove the edges of listStyle sidebar?
Hello, I've managed to get rid of these spaces in different ways. Using scrollview, giving negative insets, rewriting modifiers from scratch with plain style etc. But I couldn't solve this with a simple solution. I've read comments from many people experiencing similar problems online. It seems like there isn't a simple modifier to remove these spaces when we use sidebar as the list style in SwiftUI, or I couldn't find the simple solution. I wonder what's the simplest and correct way to reset these spaces? let numbers = Array(1...5) @State private var selected: Int? var body: some View { List(numbers, id: \.self, selection: $selected) { number in HStack { Text("Test") Spacer() } .frame(maxWidth: .infinity, alignment: .leading) } .listStyle(.sidebar) } }
0
0
193
Mar ’25
`UIGraphicsImageRenderer` + `drawHierarchy` gives very flat colors
My setup: a UILabel with text in it and then let aBugRenderer = UIGraphicsImageRenderer(size: aBugLabel.bounds.size) let aBugImage = aBugRenderer.image { context in aBugLabel.drawHierarchy(in: aBugLabel.bounds, afterScreenUpdates: true) } The layout and everything is correct, the image is correct, but I used my colors in the displayP3 color space to configure the source UILabel.textColor And unfortunately, the resulted image ends up being sRGB IEC61966-2.1 color space and the color appears way bleaker than when it's drawn natively. Question: how can I set up the renderer so that it draws the same color.
0
0
172
Jun ’25
Lack of API to access scrubber preview time in AVPlayerViewController (scrubbingTime)
Hi everyone, I'm working with AVPlayerViewController in a tvOS/iOS app and ran into a limitation that I believe some developers face. When using player.currentItem?.currentTime(), we only get the playback time—which is fine while the video is playing. But when the player is paused and the user drags the scrubber, there's no public API to get the time that is currently being previewed under the scrubber thumb (stick), but there's no way to read it programmatically. This becomes a problem when trying to show thumbnail previews or display metadata tied to the scrubbed position.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
0
1
94
Jun ’25
Detect when app window is being moved
Is there a way to detect when your apps (or any app I guess) is being moved by the user clicking and dragging the main window around the desktop at all? I'm trying to find out if there's a way I can find out if a window is being clicked and dragged and whether there's certain triggers to the movement a little bit like shaking an iPhone with Shake to Undo. Thanks
0
0
76
Jun ’25
How to move from Share Extension to the main screen
My app is designed to share and import images with apps such as the File app. I created a program after looking at various information, but the app from which the images are shared does not work, and the screen cannot be moved to the main screen of my app. The program is as follows. How should I modify it? import UIKit import MobileCoreServices import UniformTypeIdentifiers class ShareViewController: UIViewController { let suiteName: String = "group.com.valida.pettyGeneral" let keyString: String = "share-general" override func viewDidLoad() { var nameArray: [String] = [String]() let sharedDefaults: UserDefaults = UserDefaults(suiteName: self.suiteName)! guard let inputItem = self.extensionContext?.inputItems.first as? NSExtensionItem, let attachments = inputItem.attachments else { return } let identifier = UTType.image.identifier let imgAttachments = attachments.filter { $0.hasItemConformingToTypeIdentifier(identifier) } let dispatchGroup = DispatchGroup() for (no, itemProvider) in imgAttachments.enumerated() { dispatchGroup.enter() itemProvider.loadItem(forTypeIdentifier: identifier, options: nil) { [self] item, error in do { if let error = error { throw error } else if let url = item as? URL { let data = try Data(contentsOf: url) let fileManager = FileManager.default let url = fileManager.containerURL(forSecurityApplicationGroupIdentifier: suiteName) if let url = url?.appendingPathComponent(String(no)) { try! data.write(to: url) } nameArray.append(String(no)) } do { dispatchGroup.leave() } } catch { print("Error") do { dispatchGroup.leave() } } } } dispatchGroup.notify(queue: .main) { [self] in // 全ての画像を保存 sharedDefaults.set(nameArray, forKey: self.keyString) sharedDefaults.synchronize() // メニュー画面に移動する openUrl(url: URL(string: "container-general://")) self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil) } } //#selector(openURL(_:))はこの関数がないと作れない @objc func open(_ url: URL) {} func openUrl(url: URL?) { let selector = #selector(open(_ : )) var responder = (self as UIResponder).next while let r = responder, !r.responds(to: selector) { responder = r.next } _ = responder?.perform(selector, with: url) } func openContainerApp() { let url = URL(string: "container-general://") // カスタムスキームを作って指定する var responder: UIResponder? = self while responder != nil { if let application = responder as? UIApplication { let selector = sel_registerName("openURL:") application.perform(selector, with: url) break } responder = responder?.next } } }
0
0
120
Jun ’25
SwiftUI app crashes (EXC_BAD_ACCESS) when view hierarchy becomes too large.
Hey! Our team is experiencing some issue in a large SwiftUI application. When loading large views, the app crashes with a EXC_BAD_ACCESS signal. This signal can be reported by Xcode either on the @main attribute, inside a view hierarchy, or any order property that is accessed in the view hierarchy. After some investigation we found several possible workarounds: Splitting up the view into smaller subviews Wrapping parts of the view into an AnyView, which isn't ideal. However, this only temporarily solved the issue. As the app becomes bigger, we run into this problem more frequently. When trying to reproduce this issue in a clean Xcode project, I came up with the following: struct ContentView: View { var body: some View { Text("Hello") .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} .task {} } } When running this, the app immediately crashes on an iPhone 14 (YMMV on different (newer) devices). Of course such a view is not very likely to occur, but in total a view hierarchy could have this many view modifiers. Is there some limit we should we aware of? How can we circumvent this? Thanks!
0
0
86
Jun ’25
The issue of unable to use document type for Mac catalyst project
Hello, I have encountered a question that I hope to receive an answer to. Currently, I am working on a music project for Mac Catalyst and need to enable music files such as FLAC to be opened by right clicking to view my Mac Catalyst app. But currently, I have encountered a problem where I can see my app option in the right-click open mode after debugging the newly created macOS project using the following configuration. But when I created an iOS project and converted it to a Mac Catalyst app, and then modified the info.plist with the same configuration, I couldn't see my app in the open mode after debugging. May I ask how to solve this problem? Do I need to configure any permissions or features in the Mac Catalyst project? I have been searching for a long time but have not found a solution regarding it. Please resolve it, thank you. Here is the configuration of my macOS project: CFBundleDocumentTypes CFBundleTypeExtensions flac CFBundleTypeIconSystemGenerated 1 CFBundleTypeName FLAC Audio File CFBundleTypeRole Viewer LSHandlerRank Default Note: Sandbox permissions have been enabled for both the macOS project and the iOS to Mac Catalyst project. The Mac Catalyst project also has additional permissions for com. apple. security. files. user taught. read write
0
0
129
Mar ’25
SwiftUI TextEditor undo button
I'm using SwiftUI's TextEditor. I'd like to include an undo button in my UI that operates on the TextEditor. I don't see a way to hook this up. You can get the UndoManager from the environment, but this is not the undo manager the TextEditor is using. I know that UITextView uses an undocumented UndoManager (_UITextUndoManager) and I've accessed that before when using a UIViewRepresentable wrapper around UITextView. I'd like to achieve the same with TextEditor.
Topic: UI Frameworks SubTopic: SwiftUI
0
0
94
Jun ’25
How to truncate text from head with multi line?
I want to truncate text from head with max 2 lines. I try the following code import SwiftUI struct ContentView: View { @State var content: String = "Hello world! wef wefwwfe wfewe weweffwefwwfwe wfwe" var body: some View { VStack { Text(content) .lineLimit(nil) .truncationMode(.head) .frame(height: 50) Button { content += content } label: { Text("Double") } .buttonStyle(.borderedProminent) } .frame(width: 200, height: 1000) .padding() } } #Preview { ContentView() } It show result like this, this is not what I want.
0
0
246
Mar ’25
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
820
Jun ’25
UISplitViewController changes behavior of `viewControllers` property on iOS 26
I am attempting to start my application on iOS 26 with Xcode 26. It uses an UISplitViewController that is instantiated through a Storyboard. It uses the "Unspecified" style, which is a holdover from a previous version of iOS. I'm not sure if this is a bug in iOS, or if I am supposed to change it now. The viewControllers property only has the primary view controller on iOS, although it has the primary and detail view controllers on iPadOS. When I start the application on iOS 18.5, it has both primary and detail controllers on both platforms.
0
0
138
Jun ’25
In navigationLink closure, FocusState doesn't work in sheet
Hello, I have a question about FocusState, navigationLink and sheet, the code which in navigationLink closure doesn’t work, but work without navigationLink, just like the following code struct ContentView: View { var body: some View { NavigationStack { // this work interView() // this doesn't work NavigationLink { interView() } label: { Text("into interView") } } } } struct interView: View { @FocusState var focusStateA : Int? @State var show : Bool = false @State var text: String = "" var body: some View { ScrollView { VStack { coreView Button("Detail") { show.toggle() } } .sheet(isPresented: $show, content: { coreView }) } } } extension interView { var coreView : some View { VStack { VStack { putdown TextField("hi", text: $text) .focused($focusStateA , equals: 1) } } } var putdown : some View { Button(action: { if focusStateA != nil { focusStateA = nil print("OK") } else { print("It's nil") } }, label: { Text("Put down the keyboard") }) } } and there are some strange phenomena, I must put all view into a scrollview, otherwise, it even doesn’t work without navigationLink This problem has existed in IOS 18, and now in IOS26 still doesn’t be settled, is it a problem or some character?
Topic: UI Frameworks SubTopic: SwiftUI
0
0
61
Jun ’25
Access DocumentGroup container by external WindowGroup
Hi, I am currently developing a document-based application for macOS and have encountered a challenge related to document container management. Specifically, I need to open a windowGroup that shares the same container as the one used in the DocumentGroup. However, my current approach of using a global shared model container has led to unintended behavior: any new document created is linked to existing ones, and changes made in one document are reflected across all documents. To address this issue, I am looking for a solution that allows each newly created document to be individualized while still sharing the document container with all relevant WindowGroups that require access to the data it holds. I would greatly appreciate any insights or recommendations you might have on how to achieve this. Thank you for your time and assistance. Best regards, Something like: @main struct Todo: App { var body: some Scene { DocumentGroup(editing: Item.self, contentType: .item) { ContentView() } WindowGroup { UndockView() .modelContainer(of documentGroup above) } } }
0
0
86
Apr ’25
About CarPlay entitlement of EV
I'm developing a CarPlay version of my app, with the CarPlay EV Charging App entitlement (com.apple.developer.carplay-charging). However, I would like to use the Search template to searching for charging stations — but it seems this template is only available for Navigation Apps(maps). In this case, what is the recommended approach? Is it possible to apply both entitlements simultaneously and use the Search template only?
0
0
91
Jun ’25
Child Views and ViewThatFits
I'd like to support different template views within a ViewThatFits for items within a list, allowing the list to optimize its layout for different devices. Within the child views is a Text view that is bound to the name of an item. I'd rather the Text view simply truncate the text as necessary although it instead is influencing which view is chosen by ViewThatFits. I'd also rather not artificially set the maxWidth of the Text view as it artificially limits the width on devices where it's not necessary (e.g. iPad Pro vs. iPad mini or iPhone). Any guidance or suggestions on how this can be accomplished as it looks very odd for the layout of one row in the list to be quite different than the rest of the rows.
0
0
75
Jun ’25