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

Loading secondary Icon
I want to add the option to choose an alternative icon inside the app. Is there a way to load an icon asset from within the app? I downloaded Apple’s alternative icon sample, which is supposed to show a list of icons to choose from, but even in the sample, it did not work. So the current solution is to add every alternative icon along with another image asset of the same image to display to the user. This sounds like a waste of bytes. Thank you in advance for any help.
Topic: UI Frameworks SubTopic: General
0
0
67
Mar ’25
CATransaction commit() crashed on background thread [EXC_BREAKPOINT: com.apple.root.****-qos.cooperative]
Problem Description We are developing a app for iOS and iPadOS that involves extensive custom drawing of paths, shapes, texts, etc. To improve drawing and rendering speed, we use CARenderer to generate cached images (CGImage) on a background thread. We adopted this approach based on this StackOverflow post: https://stackoverflow.com/a/75497329/9202699. However, we are experiencing frequent crashes in our production environment that we can hardly reproduce in our development environment. Despite months of debugging and seeking support from DTS and the Apple Feedback platform, we have not been able to fully resolve this issue. Our recent crash reports indicate that the crashes occur when calling CATransaction.commit(). We suspect that CATransaction may not be functioning properly outside the main thread. However, based on feedback from the Apple Feedback platform, we were advised to use CATransaction.begin() and CATransaction.commit() on a background thread. If anyone has any insights, we would greatly appreciate it. Code Sample The line CATransaction.commit() is causing the crash: [EXC_BREAKPOINT: com.apple.root.****-qos.cooperative] private let transactionLock = NSLock() // to ensure one transaction at a time private let device = MTLCreateSystemDefaultDevice()! @inline(never) static func drawOnCGImageWithCARenderer( layerRect: CGRect, itemsToDraw: [ItemsToDraw] ) -> CGImage? { // We have encapsulated everything related to CALayer and its // associated creations and manipulations within CATransaction // as suggested by engineers from Apple Feedback Portal. transactionLock.lock() CATransaction.begin() // Create the root layer. let layer = CALayer() layer.bounds = layerRect layer.masksToBounds = true // Add one sublayer for each item to draw itemsToDraw.forEach { item in // We have thousands or hundred thousands of drawing items to add. // Each drawing item may produce a CALayer, CAShapeLayer or CATextLayer. // This is also why we want to utilise CARenderer to leverage GPU rendering. layer.addSublayer( item.createCALayerOrCATextLayerOrCAShapeLayer() ) } // Create MTLTexture and CARenderer. let textureDescriptor = MTLTextureDescriptor.texture2DDescriptor( pixelFormat: .rgba8Unorm, width: Int(layer.frame.size.width), height: Int(layer.frame.size.height), mipmapped: false ) textureDescriptor.usage = [MTLTextureUsage.shaderRead, .shaderWrite, .renderTarget] let texture = device.makeTexture(descriptor: textureDescriptor)! let renderer = CARenderer(mtlTexture: texture) renderer.bounds = layer.frame renderer.layer = layer.self /* ********************************************************* */ // From our crash report, this is where the crash happens. CATransaction.commit() /* ********************************************************* */ transactionLock.unlock() // Rendering layers onto MTLTexture using CARenderer. renderer.beginFrame(atTime: 0, timeStamp: nil) renderer.render() renderer.endFrame() // Draw MTLTexture onto image. guard let colorSpace = CGColorSpace(name: CGColorSpace.sRGB), let ciImage = CIImage(mtlTexture: texture, options: [.colorSpace: colorSpace]) else { return nil } // Convert CIImage to CGImage. let context = CIContext() return context.createCGImage(ciImage, from: ciImage.extent) }
0
1
469
Jan ’25
PasteButton in a confirmationDialog
Hey, Anyone knows of a possible way to present a PasteButton in a .confirmationDialog on iOS? when I try adding it, it's ignored and not displayed with the rest of the buttons struct MyView: View { @State var flag: Bool = false var body: some View { Text("Some Text") .confirmationDialog("Dialog", isPresented: $flag) { Group { Button("A") {} Button("B") {} PasteButton(payloadType: Data.self) { data in } } } } }
0
0
147
Mar ’25
SwiftUI: How to change `contentInset` of `List`
Hi, Is there any way of changing the contentInset (UIKit variant) of a List in SwiftUI? I do not see any APIs for doing so, the closest I gotten is to use safeAreaInset . While visually that works the UX is broken as you can no longer "scroll" from the gap made by the .safeAreaInset(edge:alignment:spacing:content:) I have subbmited a feedback suggestion: FB16866956
0
0
173
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
180
Mar ’25
LiveCommunicationKit events
how can i watch the LiveCommunicationKit event? i have codes likes this: import UIKit import LiveCommunicationKit @available(iOS 17.4, *) class LiveCallKit: NSObject, ConversationManagerDelegate { @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, conversationChanged conversation: Conversation) { } @available(iOS 17.4, *) func conversationManagerDidBegin(_ manager: ConversationManager) { } @available(iOS 17.4, *) func conversationManagerDidReset(_ manager: ConversationManager) { } @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, perform action: ConversationAction) { switch action.state { case .idle: self.completionHandler!(InterfaceKind.reject,self.payload!) case .running: self.completionHandler!(InterfaceKind.reject,self.payload!) case .complete: self.completionHandler!(InterfaceKind.reject,self.payload!) case .failed(let reason): self.completionHandler!(InterfaceKind.reject,self.payload!) default: self.completionHandler!(InterfaceKind.reject,self.payload!) } } @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, timedOutPerforming action: ConversationAction) { } @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, didActivate audioSession: AVAudioSession) { } @available(iOS 17.4, *) func conversationManager(_ manager: ConversationManager, didDeactivate audioSession: AVAudioSession) { } @objc public enum InterfaceKind : Int, Sendable, Codable, Hashable { /// 拒绝/挂断 case reject /// 接听. case answer } var sessoin: ConversationManager var callId: UUID var completionHandler: ((_ actionType: InterfaceKind,_ payload: [AnyHashable : Any]) -> Void)? var payload: [AnyHashable : Any]? @objc init(icon: UIImage!) { let data:Data = icon.pngData()!; let cfg: ConversationManager.Configuration = ConversationManager.Configuration(ringtoneName: "ring.mp3", iconTemplateImageData: data, maximumConversationGroups: 1, maximumConversationsPerConversationGroup: 1, includesConversationInRecents: false, supportsVideo: false, supportedHandleTypes: Set([Handle.Kind.generic])) self.sessoin = ConversationManager(configuration: cfg) self.callId = UUID() super.init() self.sessoin.delegate = self } @objc func toIncoming(_ payload: [AnyHashable : Any], displayName: String,actBlock: @escaping(_ actionType: InterfaceKind,_ payload: [AnyHashable : Any])->Void) async { self.completionHandler = actBlock do { self.payload = payload self.callId = UUID() var update = Conversation.Update(members: [Handle(type: .generic, value: displayName, displayName: displayName)]) let actNumber = Handle(type: .generic, value: displayName, displayName: displayName) update.activeRemoteMembers = Set([actNumber]) update.localMember = Handle(type: .generic, value: displayName, displayName: displayName); update.capabilities = [ .playingTones ]; try await self.sessoin.reportNewIncomingConversation(uuid: self.callId, update: update) try await Task.sleep(nanoseconds: 2000000000); } catch { } } } i want to watch the buttons action,how should i do?
Topic: UI Frameworks SubTopic: SwiftUI
0
0
224
Mar ’25
MVVM design and data dependency
According to the MVVM design pattern, one of my views depends on many properties in my model. Can I use logic like @published var model = MyModel()? Will there be a large performance loss? Will the UI be refreshed when other unrelated properties in the model are modified? What is the best practice in this case?
Topic: UI Frameworks SubTopic: General
0
0
241
Jan ’25
SwiftUI Canvas Text - scale to fill rectangle
How do I draw a single line of text in a SwiftUI Canvas, scaled to fill a given rectangle? Example: Canvas { context, size in let r = CGRect(origin: CGPointZero, size: size); // Whole canvas let t = Text("Hello World"); context.draw(t, in: r); } Outside of Canvas I'd add .minimumScaleFactor(0) .lineLimit(1), and I guess set a large default font size, and I'd get the result I want. But inside Canvas, .minimumScaleFactor and .lineLimit don't seem to be available; they return some View, not Text, which can't be used in context.draw. (Is there a trick to make that work?) I have written the following to do this, but I think there must be an easier way to achieve this! Suggestions? extension GraphicsContext { mutating func draw_text_in_rect(string: String, rect: CGRect) { let text = Text(string) .font(.system(size: 25)); // The font size used here does matter, because e.g. letter spacing // varies with the font size. let resolved = resolve(text); let text_size = resolved.measure(in: CGSize(width: CGFloat.infinity, height: CGFloat.infinity)); let text_aspect = text_size.width / text_size.height; let fit_size = CGSize(width: min(rect.size.width, rect.size.height*text_aspect), height: min(rect.size.height, rect.size.width/text_aspect)); let fit_rect = CGRect(x: rect.origin.x + (rect.size.width-fit_size.width)/2, y: rect.origin.y + (rect.size.height-fit_size.height)/2, width: fit_size.width, height: fit_size.height); let scale = fit_size.width / text_size.width; // For debug: // var p = Path(); // p.addRect(fit_rect); // stroke(p, with: GraphicsContext.Shading.color(.red), lineWidth: 1); translateBy(x: fit_rect.minX, y: fit_rect.minY); scaleBy(x:scale, y:scale); draw(resolved, at: CGPointZero, anchor: UnitPoint.topLeading); transform = CGAffineTransformIdentity; } };
0
0
368
Jan ’25
How to override NSWindow in a pure SwiftUI Application
So I am looking to use a custom NSWindow application (so I can implement some enhanced resizing/dragging behavior which is only possible overriding NSWindow). The problem is my whole application is currently SwiftUI-based (see the project here: https://github.com/msdrigg/Roam/blob/50a2a641aa5f2fccb4382e14dbb410c1679d8b0c/Roam/RoamApp.swift). I know there is a way to make this work by dropping my @main SwiftUI app and replacing it with a SwiftUI root view hosted in a standard AppKit root app, but that feels like I'm going backwards. Is there another way to get access (and override) the root NSWindow for a SwiftUI app?
0
0
280
Mar ’25
Siri Intent Dialog with custom SwiftUIView not responding to buttons with intent
I have created an AppIntent and added it to shortcuts to be able to read by Siri. When I say the phrase, the Siri intent dialog appears just fine. I have added a custom SwiftUI View inside Siri dialog box with 2 buttons with intents. The callback or handling of those buttons is not working when initiated via Siri. It works fine when I initiate it in shortcuts. I tried using the UIButton without the intent action as well but it did not work. Here is the code. static let title: LocalizedStringResource = "My Custom Intent" static var openAppWhenRun: Bool = false @MainActor func perform() async throws -> some ShowsSnippetView & ProvidesDialog { return .result(dialog: "Here are the details of your order"), content: { OrderDetailsView() } } struct OrderDetailsView { var body: some View { HStack { if #available(iOS 17.0, *) { Button(intent: ModifyOrderIntent(), label : { Text("Modify Order") }) Button(intent: CancelOrderIntent(), label : { Text("Cancel Order") }) } } } } struct ModifyOrderIntent: AppIntent { static let title: LocalizedStringResource = "Modify Order" static var openAppWhenRun: Bool = true @MainActor func perform() async throws -> some OpensIntent { // performs the deeplinking to app to a certain page to modify the order } } struct CancelOrderIntent: AppIntent { static let title: LocalizedStringResource = "Cancel Order" static var openAppWhenRun: Bool = true @MainActor func perform() async throws -> some OpensIntent { // performs the deeplinking to app to a certain page to cancel the order } } Button(action: { if let url = URL(string: "myap://open-order") { UIApplication.shared.open(url) } }
0
0
333
Mar ’25
NSHostingController menu not activated
I'm attempting to write a macOS version of https://stackoverflow.com/a/74935849/2178159. From my understanding, I should be able to set the menu property of an NSResponder and it will automatically show on right click. I've tried a couple things: A: set menu on an NSHostingController's view - when I do this and right or ctrl click, nothing happens. B: set menu on NSHostingController directly - when I do this I get a crash Abstract method -[NSResponder setMenu:] called from class _TtGC7SwiftUI19NSHostingControllerGVS_21_ViewModifier_...__. Subclasses must override C: manually call NSMenu.popup in a custom subclasses of NSHostingController or NSView's rightMouseDown method - nothing happens. extension View { func contextMenu(menu: NSMenu) -> some View { modifier(ContextMenuViewModifier(menu: menu)) } } struct ContextMenuViewModifier: ViewModifier { let menu: NSMenu func body(content: Content) -> some View { Interaction_UI( view: { content }, menu: menu ) .fixedSize() } } private struct Interaction_UI<Content: View>: NSViewRepresentable { typealias NSViewType = NSView @ViewBuilder var view: Content let menu: NSMenu func makeNSView(context: Context) -> NSView { let v = NSHostingController(rootView: view) // option A - no effect v.view.menu = menu // option B - crash v.menu = menu return v.view } func updateNSView(_ nsView: NSViewType, context: Context) { // part of option A nsView.menu = menu } }
0
0
237
Mar ’25
MacOS Scale to view
on iOS you can choose to scale to view to have the app resize the screen easily in the developer environment. Scale to view is however not easily done on MacOS using NS to solve on MacOS now. Is it possible for the Apple developer team to make this easier for the Developer, as I understand it is for iOS applications?
0
0
261
Feb ’25
QLPreviewingController can access previewed file, but cannot load files referenced by the previewed file
I have an app on the Mac App Store (so sandboxed) that includes a QuickLook Preview Extension that targets Markdown files. It established a QLPreviewingController instance for the macOS QuickLook system to access and it works. I'm in the process of updating it so that it displays inline images referenced in the file as well as styling the file's text. However, despite setting Downloads folder read-only access permission (and user-selected, though I know that shouldn't be required: no open/save dialogs here) in the extension's entitlements, Sandbox refuses too allow access to the test image: I always get a deny(1) file-read-data error in the log. FWIW, the test file is referenced in the source Markdown as an absolute unix file path. I've tried different signings and no joy. I’ve tried placing the referenced image in various other locations. Also no joy. All I can display is the error-case bundle image for 'missing image'. Question is, is this simply something that QuickLook extensions cannot do from within the sandbox, or am I missing something? Is there anything extra I can do to debug this?
0
0
405
Jan ’25
view controller life cycle bug in xcode 16 ios 18
hi does any one know if there changes in lifecycle in xcode 16 ios 18 cause i notice that my view will appear does what view didappear use to do in older version and it kind of a problem cause all the rest of ios work diffrently does anyone else found a problem with it? or does anyone know if there was a known change to life cycles
0
0
429
Jan ’25
Multipeer Connectivity with iOS devices
I used the Multipeer Connectivity Framework to allow players of my game app to see the highest score along with their own score as the game progresses. It works fine running in 3 or 4 simulators in Xcode. However, I was just told by two Apple support reps that bluetooth connectivity is not allowed between two Apple devices, other than for watches, AirPods, headphones, etc. My question is: can two iPhones or iPads connect for peer-to-peer play? Can they play offline? If the answer is yes to either or both of those questions, how do I get that to happen since I get an error message when trying to connect two iPhones via bluetooth even though they can see each other in the Other Devices list? If the answer is no, then why does Apple provide a Multipeer Connectivity Framework and simulate that type of device to device connection with the Xcode simulators?
Topic: UI Frameworks SubTopic: SwiftUI
0
0
170
Feb ’25
Is it possible to automatically flip device orientation?
Hello togehter, i do have the following question. If I have my App run in landscape mode and a sheet view get's called, will it be possible to switch automatically from landscape mode in portrait mode and fix this device orientation? Once the sheet view get's dismissed or closed, the original view will come back and the device orientation shall switch back to landscape mode. Thanks you so much for your help!
0
0
240
Feb ’25