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
615
Jun ’25
SwiftUI App crashes while switching orientation
Hi, I am a new SwiftUI app developer and developing my first application. In the process of designing not very GUI rich app, I noticed my app crashed whenever I switched orientation (testing on multiple iPhone devices). After going through all kind of logs and errors, performance enhancements nothing worked. Then I started rolling back all GUI related features 1 by 1 and tested (I am sure there are better approaches, but excuse me I am novice in app development :) ). Even though it's time consuming, I could pin point the cause of the fatal error and app crash, it's due to multiple .shadow modifiers I used on NavigationLink inside a ForEach look (to be precise I used it like following, .shadow(radius: 15) .shadow(radius: 20) .shadow(radius: 20) .shadow(radius: 20) .shadow(radius: 20) Note, there are only 7 items in List and it uses the Hero View (like app store's Today section) for child views. Once I got rid of shadow modifies or used only 1 app works fine and doesn't crash. Lesson learnt... P.S. It's so ironic that so performance tuned devices couldn't handle this basic GUI stuff.
4
0
579
Nov ’24
@FetchRequest predicate is ignored if the context changes
I have a simple SwiftUI application with CoreData and two views. One view displays all "Place" objects. You can create new places and you can show the details for the place. Inside the second view you can add "PlaceItem"s to a place. The problem is that, once a new "PlaceItem" is added to the viewContext, the @NSFetchRequest seems to forget about its additional predicates, which I set in onAppear. Then every place item is shown inside the details view. Once I update the predicate manually (the refresh button), only the items from the selected place are visible again. Any idea how this can be fixed? Here's the code for my two views: struct PlaceView: View { @FetchRequest(sortDescriptors: []) private var places: FetchedResults<Place> @Environment(\.managedObjectContext) private var viewContext var body: some View { NavigationView { List(places) { place in NavigationLink { PlaceItemsView(place: place) } label: { Text(place.name ?? "") } } } .toolbar { ToolbarItem(placement: .primaryAction) { Button { let place = Place(context: viewContext) place.name = NSUUID().uuidString try! viewContext.save() } label: { Label("Add", systemImage: "plus") } } } .navigationTitle("Places") } } struct PlaceItemsView: View { @ObservedObject var place: Place @FetchRequest(sortDescriptors: []) private var items: FetchedResults<PlaceItem> @Environment(\.managedObjectContext) private var viewContext func updatePredicate() { items.nsPredicate = NSPredicate(format: "place == %@", place) } var body: some View { NavigationView { List(items) { item in Text(item.name ?? ""); } } .onAppear(perform: updatePredicate) .toolbar { ToolbarItem(placement: .primaryAction) { Button { let item = PlaceItem(context: viewContext) item.place = place item.name = NSUUID().uuidString try! viewContext.save() } label: { Label("Add", systemImage: "plus") } } ToolbarItem(placement: .navigationBarLeading) { Button(action: updatePredicate) { Label("Refresh", systemImage: "arrow.clockwise") } } } .navigationTitle(place.name ?? "") } } struct ContentView: View { @Environment(\.managedObjectContext) private var viewContext var body: some View { NavigationView { PlaceView() } } } Thanks!
2
0
892
Nov ’24
Infinite view loop
If I add items at the root level, this code works, but if I attempt to add a child to any item, it runs an infinite loop where it goes from the AddItemView back to the SubItemView and starts all over. I suspect it has something to do with the Predicate in SubItemView, but the debugger is crap, so I'm just guessing. Minimal code: @Model final class Item { var id: String var name: String var children: [Item] = [] @Relationship(deleteRule: .cascade) var parent: Item? init(name: String, parent: Item?, id: String = UUID().uuidString) { self.name = name self.parent = parent self.id = id } } struct ContentView: View { @Environment(\.modelContext) private var modelContext @Query( filter: #Predicate<Item> { item in item.parent == nil }, sort: \Item.name ) public var rootItems: [Item] var body: some View { NavigationStack { List { ForEach(rootItems) { item in HStack { NavigationLink ( destination: SubItemView(parent: item)) { Text(item.name) } } } } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { EditButton() } ToolbarItem { NavigationLink(destination: AddItemView(itemParent: nil)) { Text("Add To Do") } } } } } } struct SubItemView: View { @Environment(\.dismiss) private var dismiss @Environment(\.modelContext) private var modelContext @State var parent: Item @State private var todo: String = "" @State var selectedDate = Date() @State var showPicker: Bool = false @Query var children: [Item] init(parent: Item) { self.parent = parent let parentID = parent.id _children = Query(filter: #Predicate<Item> { $0.parent.flatMap(\.id) == parentID && $0.parent.flatMap(\.id) != nil }, sort: \Item.name ) } var body: some View { Form { LabeledContent { TextField("Name", text: $parent.name) } label: { Text("Name:") } } Text("Parent: \(parent.name)\n") NavigationStack { Text("Child count: \(children.count)") List(children) { child in HStack { if(child.children.isEmpty) { Text(child.name) NavigationLink ( destination: SubItemView(parent: child)) { Text("").foregroundColor(.white).background(Color.blue) } .opacity(0) .background( Text("") ) } else { Text(child.name) NavigationLink(destination: SubItemView(parent: child)) { Text("") } } } } } .navigationTitle("Sub Items") .toolbar { ToolbarItem(placement: .navigationBarTrailing) { EditButton() } ToolbarItem { NavigationLink(destination: AddItemView(itemParent: parent)) { Text("Add To Do") } } ToolbarItem { Button("Save") { try? modelContext.save() dismiss() } } } } } struct AddItemView: View { @Environment(\.dismiss) private var dismiss @Environment(\.modelContext) private var context @State var itemParent: Item? @State private var name = "" @State private var showWarning: Bool = false @State var child = Item(name: "", parent: nil) var body: some View { NavigationStack { Form { LabeledContent { TextField("Item", text: $name) } label: { Text("Todo:") } } .navigationTitle("Add New Item") .toolbar { Button("Save") { let tmp = Item(name: name, parent: itemParent) if(itemParent != nil) { itemParent!.children.append(tmp) } context.insert(tmp) try? context.save() dismiss() } } } } }
4
0
484
Nov ’24
Not possible to remove variable: 221: <unknown var (bug!) with engine as delegate:0x301a75580>{id: 12318} colIndex:60 from engine <NSISEngine: 0x151bc3100>{ delegate:0x151bc2bc0
On the iOS 18 system, we have found that some pages will definitely experience this kind of crash phenomenon when displayed. It's puzzling that I can modify different codes and this kind of crash won't occur on the 18 system. This has had a great impact on my code development, and I don't know if I can still use this API in the future. Can you help me solve this dilemma. thank
1
0
362
Dec ’24
Binding of an array element property inside a struct not working anymore
Hi, I programmed an app to draw cards from a deck. After a card is drawn it is hidden from the deck. The drawn state is a property of a card struct in an array inside a deck struct. This worked well in the past since iOS 14. Since Xcode 16 this does not work as before anymore. This is the Card struct with a Boolfor the drawn state: struct Card: Codable, Identifiable, Equatable, Hashable { var isDrawn: Bool … } The cards are stored in an array that is inside a CardDeck struct among other properties: struct CardDeck: Codable { var cards: [Card] = [] var cardSpacing: CGFloat … mutating func hideCard(card: Card) { if let cardIndex = self.cards.firstIndex(of: card) { self.cards[cardIndex].isDrawn = true } } } The deck is a published property of an observable DeckStore class for permanent storage: class CardDeckStore: ObservableObject { @Published var deck: CardDeck = CardDeck() … } The DeckStore class is @StateObject in the App struct: @main struct CardApp: App { @StateObject var store = OpaliaCardDeckStore() var body: some Scene { WindowGroup { ContentView(deck: $store.deck) } } } Here is the simplified DrawCardsView where I present and draw the cards: struct DrawCardsView: View { @Binding var deck: CardDeck var body: some View { // Was a NavigationView before NavigationStack() { HStack(spacing: deck.cardSpacing) { ForEach($deck.cards) { $card in if card.isDrawn { CardBackView(card: card) .hidden() } else { NavigationLink(destination: DrawnCardView(card: card, deck: $deck)) { CardBackView(card: card) } } } } } } } To hide a drawn card, hideCard() is called in the DrawnCardView: struct DrawnCardView: View { var card: Card @Binding var deck: CardDeck @State var drawnCard: DrawnCard = .init() var body: some View { DrawnCardSimpleView(drawnCard: self.drawnCard) .onDisappear(perform: { deck.hideCard(card: self.card) }) } } I am not a pro in programming and there are better solutions to program this, but this worked until I upgraded to Xcode 16. Now it seems the isDrawn state of a card does not update the DrawCardsView right away anymore. A drawn card is not hidden and still present when returning to DrawCardsView from DrawnCardView. After tapping the same card again or another update of the UI, the card will then be hidden. I do not know the reason. It seems the binding of the isDrawn state inside an element of the card array in the observable object is not working anymore. Other properties of the observable object like cardSpacing do work as expected. I can empty the cards array and fill it with new cards without problems in the DrawCardsView. I eliminated the ForEach loop by addressing the array elements directly, but to no avail. I tried different solutions I found on the internet, but nothing worked. I was under the impression that every change in an observable object would update the UI. Any ideas for a explanation/solution? Thanks, Christian
Topic: UI Frameworks SubTopic: SwiftUI
2
0
224
Nov ’24
“Search Bar Overlapping Keyboard and Displaying Suggestions Incorrectly on iPhone 16 Pro”
I’m experiencing an issue with the search bar on my iPhone 16 Pro. When I start typing in the search bar (as shown in the screenshot), the keyboard overlaps with the search suggestions, making it hard to see the contacts and apps that are displayed. The interface seems cluttered, and it becomes difficult to accurately tap on the desired suggestion or contact. Steps to Reproduce: 1. Swipe down to access the search bar on the iPhone 16 Pro. 2. Type a few letters to bring up suggestions for apps, contacts, and messages. Expected Result: The search results should display clearly above the keyboard without overlapping or cluttered suggestions. Actual Result: The keyboard overlaps with the search results, making it difficult to view or select items accurately. Device and OS Details: • iPhone 16 Pro • iOS Version (please replace with your specific version) Has anyone else encountered this issue? Any insights on possible fixes or settings adjustments would be appreciated.
Topic: UI Frameworks SubTopic: SwiftUI
0
0
284
Nov ’24
OSLog Logger & SwiftUI
Hi, Are there any macros that can be used with Logger to automatically capture the SwiftUI function that the message originates from? Currently, I am using something similar to: Logger.misc.error("In \(#fileID), \(#function): \(error)") Currently, the #function only tells me that it originates in body... Ideally, I'd like to be able to tell if it was with an onAppear, onChange, Button, alert, etc... I realize I can manually enter this, but was wondering if there was a more automated way to capture this info. Thx,
Topic: UI Frameworks SubTopic: SwiftUI
0
0
241
Dec ’24
Detect when a tvOS top shelf tile/slide transition occurs?
Our tvOS app makes use of top shelf Carousel style slides to promote our content. We would like to detect when tvOS transitions between individual top shelf slides, regardless of whether the slide transition is made by a user (via the Siri remote), or by the system idle auto-transition. Has anyone achieved this, maybe there are undocumented system hooks or events we can listen to?
0
0
467
Nov ’24
Why can't I use Task in an iOS only package?
Getting this error: 'Task' is only available in macOS 10.15 or newerSourceKit LoggerForPreviews.swift(130, 9): Add 'if #available' version check LoggerForPreviews.swift(129, 24): Add @available attribute to enclosing static method LoggerForPreviews.swift(5, 20): Add @available attribute to enclosing actor Does it have something to do with developing in VSCode? import Foundation import SwiftUI // Logger: A concise, globally accessible logging utility for SwiftUI previews public final actor PreviewLogger: Sendable { // LogLevel: Defines severity levels for logging public enum LogLevel: Int, Sendable, CaseIterable { // Define cases based on LOG_LEVEL_MAP case trace, debug, verbose, info, notice, warning, error, critical, fatal // Computed property to get order based on case declaration private var order: Int { switch self { case .trace: return 0 case .debug: return 1 case .verbose: return 2 case .info: return 3 case .notice: return 4 case .warning: return 5 case .error: return 6 case .critical: return 7 case .fatal: return 8 } } public var description: String { // Use capitalized raw value for description return String(describing: self).uppercased() } // Static function to compare log levels static func >= (lhs: LogLevel, rhs: LogLevel) -> Bool { return lhs.order >= rhs.order } } // Shared instance for global access public static let shared = PreviewLogger() // Current log level public var logLevelThreshold: LogLevel = .info private init() {} // Configure the logger's log level public func configure(logLevelThreshold: LogLevel) { self.logLevelThreshold = logLevelThreshold } // Helper function to center text within a given width private func centered(_ text: String, in separator: String) -> String { let totalLength = separator.count let textLength = text.count if textLength >= totalLength { return text } let padding = (totalLength - textLength) / 2 let padString = String(repeating: " ", count: padding) return padString + text } // Main logging function public func log( _ message: String, level: LogLevel = .info, file: String = #file, function: String = #function, line: Int = #line, callerFile: String? = nil, callerFunction: String? = nil, callerLine: Int? = nil ) { #if DEBUG guard ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" else { return } guard level >= logLevelThreshold else { return } let fileName = (file as NSString).lastPathComponent let cleanFunction = function.replacingOccurrences(of: "(_:file:function:line:)", with: "") let levelIcon: String switch level { case .trace: levelIcon = "🔍" case .debug: levelIcon = "🛠️" case .verbose: levelIcon = "📝" case .info: levelIcon = "ℹ️" case .notice: levelIcon = "📢" case .warning: levelIcon = "⚠️" case .error: levelIcon = "❌" case .critical: levelIcon = "🚨" case .fatal: levelIcon = "💀" } let header = "[\(levelIcon) \(level.description)]" let separator = "· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·" let finalSeparator = "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" let centeredHeader = centered(header, in: separator) var output = """ \n\(separator) \(centeredHeader) """ let locationInfo = "📍 \(fileName):\(line) ➜ \(cleanFunction)" let centeredLocation = centered(locationInfo, in: separator) output += "\n\(centeredLocation)" if let callerFile = callerFile, let callerLine = callerLine { let callerFileName = (callerFile as NSString).lastPathComponent let callerInfo = "📱 Called from: \(callerFileName):\(callerLine)" let centeredCallerInfo = centered(callerInfo, in: separator) output += "\n\(centeredCallerInfo)" } output += """ \n\(separator)\n\(message)\n\(finalSeparator) """ print(output) #endif } // Static Methods public static func configure(logLevelThreshold: LogLevel) { Task { await shared.configure(logLevelThreshold: logLevelThreshold) } } public static func log( _ message: String, level: LogLevel = .info, file: String = #file, function: String = #function, line: Int = #line, callerFile: String? = nil, callerFunction: String? = nil, callerLine: Int? = nil ) { Task { await shared.log( message, level: level, file: file, function: function, line: line, callerFile: callerFile, callerFunction: callerFunction, callerLine: callerLine ) } } }
1
0
247
Dec ’24
Crash when setting up the content view loaded from a NIB
I am trying to understand why I am seeing crash reports for my code that creates a view from a NIB like the code below. The crash occurs when referencing contentView which should have been bound when the NIB was loaded. Am I missing something here other than checking the result of the loadNibNamed function call? class MyView: NSView { @IBOutlet var contentView: NSView! init() { super.init(frame: NSRect(x: 0, y: 0, width: 84.0, height: 49.0)) commonInit() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func commonInit() { Bundle.main.loadNibNamed("MyView", owner: self, topLevelObjects: nil) translatesAutoresizingMaskIntoConstraints = false contentView.translatesAutoresizingMaskIntoConstraints = false addSubview(contentView) contentView.frame = self.bounds }
6
0
695
Nov ’24
Diffable Data Source Warning: Non-Thread Confined Updates
Hello, I’ve encountered a warning while working with UITableViewDiffableDataSource. Here’s the exact message: Warning: applying updates in a non-thread confined manner is dangerous and can lead to deadlocks. Please always submit updates either always on the main queue or always off the main queue - view=&lt;UITableView: 0x7fd79192e200; frame = (0 0; 375 667); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = &lt;NSArray: 0x600003f3c9f0&gt;; backgroundColor = &lt;UIDynamicProviderColor: 0x60000319bf80; provider = &lt;NSMallocBlock: 0x600003f0ce70&gt;&gt;; layer = &lt;CALayer: 0x6000036e8fa0&gt;; contentOffset: {0, -116}; contentSize: {375, 20}; adjustedContentInset: {116, 0, 49, 0}; dataSource: &lt;TtGC5UIKit29UITableViewDiffableDataSourceOC17ArticleManagement21DiscardItemsViewModel17SectionIdentifierSS: 0x600003228270&gt;&gt; OS: iOS Version: iOS 17+, Xcode Version: 16.0, Frameworks: UIKit, Diffable Data Source, View: UITableView used with a UITableViewDiffableDataSource. Steps to Reproduce: Using a diffable data source with a table view. Applying snapshot updates in the data source from a main thread. Warning occurs intermittently during snapshot application. Expected Behavior: The snapshot should apply without warnings, provided the updates are on a main thread. Actual Behavior: The warning suggests thread safety issues when applying updates on non-thread-confined queues. Questions: Is there a recommended best practice to handle apply calls in diffable data sources with thread safety in mind? Could this lead to potential deadlocks if not addressed? Note :- I confirm I am always reloading / reconfiguring data source on main thread. Please find the attached screenshots for the reference. Any guidance or clarification would be greatly appreciated!
0
0
599
Dec ’24
UIPasteboard
To store the data, I used the following api: (nullable UIPasteboard *)pasteboardWithName:(UIPasteboardName)pasteboardName create:(BOOL)create The official document says that starting from iOS10, clipboard data does not support persistence, but from the test practice, I use this clipboard to save the data always exists, no matter uninstall and reinstall the APP, restart the phone, or even update the system, then what scenarios may lead to the clipboard data is deleted, using this scheme to store data is reliable?
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
204
Dec ’24
Nested TimelineView and List cause hang issue
Hello. I’ve encountered a strange issue with TimelineView and wanted to report it. The following code runs without any problems: // Example 1. struct ContentView: View { var body: some View { TimelineView(.everyMinute) { _ in List { TimelineView(.everyMinute) { _ in Text("Hello") } } } } } However, the code below causes the CPU usage to spike to 100%, and the screen displays a blank view: // Example 2. struct ContentView: View { var body: some View { TimelineView(.everyMinute) { _ in List { TimelineView(.everyMinute) { _ in text } } } } var text: some View { Text("Hello") } } The same issue occurs with the following code: // Example 3. struct MyTextView: View { var body: some View { Text("Hello") } } struct ContentView: View { var body: some View { TimelineView(.everyMinute) { _ in List { TimelineView(.everyMinute) { _ in MyTextView() } } } } } Replacing List with LazyVStack and ForEach resolves the hang issue, but I need to use List because I rely on the swipeActions(). Does anyone have insights or suggestions on how to address this issue?
1
0
262
Dec ’24
How to use the mouse to select List data items
I have a question about SwiftUI and would like to ask you guys The problem is described as follows I am learning to use SwiftUI. I have a file list display window. I encapsulate the files into a structure called FileInfo and use List to display the files obtained through filemanager. I want to select files by mouse selection. But I didn't find SwiftUI support for selection, so I used Zstack to select, but I found that it is difficult to respond to selection and click events at the same time. Below is my code ZStack { List(selection: $localWorkspaceViewModel.selectedFiles) { ForEach(localWorkspaceViewModel.files.indices, id: \.self) { index in ZStack { } .contextMenu{ // ... } .onTapGesture(count: 2) { // ... } .onTapGesture(count: 1) { // ... } .onDrag { // ... } } .listRowInsets(EdgeInsets()) .listRowSeparator(.hidden) } .contextMenu { // ... } .onDrop(of: ["public.data"], isTargeted: nil) { providers in // ... } Color.clear .contentShape(Rectangle()) .gesture( DragGesture(minimumDistance: 20) .onChanged { value in print() if !isDragging { dragStartPoint = value.startLocation isDragging = true } // ... } .onEnded { _ in isDragging = false } ) .allowsHitTesting(!isDragging) if isDragging { Rectangle() .fill(Color.blue.opacity(0.2)) .frame(width: selectionRect.width, height: selectionRect.height) .position(x: selectionRect.midX, y: selectionRect.midY) .overlay( Rectangle() .stroke(Color.blue, lineWidth: 1) ) .allowsHitTesting(false) } } The code problem is described as follows When the line of code .allowsHitTesting(!isDragging) sets the static value to true or false, the click and drag event of the List item behaves normally or the box selection of Color.clear behaves normally, but only one of them behaves normally. However, after setting it to !isDragging, only one of them behaves normally. I would like to ask how to solve this problem. I would be very grateful if you can give me a solution.
Topic: UI Frameworks SubTopic: SwiftUI
0
0
280
Nov ’24
Problem with audio files in Swift
Hi guys, I've been this app for quite a while and I wanted to add audio to it but I've encountered a strange bug. Whenever I try to play the audio from the testing device, it prints out that the audio file cannot be found. I've checked multiple times the names and the code and I get no errors there whatsoever. I have no idea what might be causing this. Here's a part of the code: `import SwiftUI import AVFoundation struct Card: Identifiable { let id = UUID() let heading: String let description: String let imageName: String let detailDescription: String let sonification: String } struct ExplorepageUI: View { @State private var selectedCard: Card? @State private var showMore = false @State private var currentIndex = 0 @State private var currentCards: [Card] = [] let galaxies = [ Card(heading: "The Mice Galaxies", description: "They’re located about 300 million light-years away in the constellation Coma Berenices.", imageName: "TheMiceGalaxiesHubble", detailDescription:""" Their name refers to the long tails produced by tidal action, the relative difference between gravitational pulls on the near and far parts of each galaxy, known here as a galactic tide. It is a possibility that both galaxies, which are members of the Coma Cluster, have experienced collision, and will continue colliding until they coalesce. The colors of the galaxies are peculiar. In NGC 4676A a core with some dark markings is surrounded by a bluish white remnant of spiral arms. The tail is unusual, starting out blue and terminating in a more yellowish color, despite the fact that the beginning of each arm in virtually every spiral galaxy starts yellow and terminates in a bluish color. NGC 4676B has a yellowish core and two arcs; arm remnants underneath are bluish as well. The galaxies were photographed in 2002 by the Hubble Space Telescope. In the background of the Mice Galaxies, there are over 3000 galaxies, at distances up to 13 billion light-years. """, sonification: "SonificationoftheMiceGalaxies"), `class MusicPlayer: ObservableObject { private var audioPlayer: AVPlayer? func playSound(named sonificationFileName: String){ if let url = Bundle.main.url(forResource: sonificationFileName, withExtension: "mp3"){ print("✅ Found audio file at: \(url)") audioPlayer = try? AVPlayer(url: url) audioPlayer?.play() print("🎵 Audio should now be playing!") } else { print("❌ Audio file not found: \(sonificationFileName).mp3") } } func pause(){ audioPlayer?.pause() } }
1
0
562
Nov ’24
UIimage init crash for old Xcode
We have found some recent crashes that only appear on iOS 18 iPad OS 18, these crashes only appear in apps packaged in August 2022 and earlier and affect about 200 users per day, the same method calls have not had the same crashes in any of the subsequent Xcode build, here's the code in question. public class FeedComponentResource: NSObject { static func bundle() -> Bundle? { let path = (Bundle(for: FeedComponentResource.self).resourcePath! as NSString).appendingPathComponent("ResourceBundle.bundle") let bundle = Bundle(path: path) return bundle } public static func image(_ id: String) -> UIImage { var image = UIImage() if let bundle = self.bundle() { // crashed in this line image = UIImage(named: id, in: bundle, compatibleWith: nil)! } return image } and here is the call stack EXC_BREAKPOINT 0x000000010302b328 Crashed: com.apple.main-thread 0 NewsBreak 0x60b328 closure #1 in FeedComponentHeader.authorIconView.getter + 3256176 (FeedComponentResource.swift:3256176) 1 NewsBreak 0x6081b0 FeedComponentHeader.authorIconView.getter + 3243512 2 NewsBreak 0x6086ac FeedComponentHeader.init(frame:) + 94 (FeedComponentHeader.swift:94) 3 NewsBreak 0x609550 @objc FeedComponentHeader.init(frame:) + 3248536 (<compiler-generated>:3248536) 4 NewsBreak 0x241c00 closure #1 in FeedNewsRedesignBaseCell.header.getter + 17 (FeedNewsRedesignBaseCell.swift:17) 5 NewsBreak 0x241134 FeedNewsRedesignBaseCell.header.getter + 4332327220 6 NewsBreak 0x2452a0 FeedNewsRedesignBaseCell.init(frame:) + 160 (FeedNewsRedesignBaseCell.swift:160) 7 NewsBreak 0x245618 @objc FeedNewsRedesignBaseCell.init(frame:) + 4332344856 (<compiler-generated>:4332344856) 8 NewsBreak 0x249350 FeedNewsRedesignBigCell.init(frame:) + 16 (FeedNewsRedesignBigCell.swift:16) 9 NewsBreak 0x24a5b0 @objc FeedNewsRedesignBigCell.init(frame:) + 4332365232 (<compiler-generated>:4332365232) 10 UIKitCore 0x82110 __88-[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:]_block_invoke + 40 11 UIKitCore 0x7ff30 +[UIView(Animation) performWithoutAnimation:] + 76 12 UIKitCore 0x27a180 -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:] + 956 13 UIKitCore 0x279d48 -[UICollectionView dequeueReusableCellWithReuseIdentifier:forIndexPath:] + 84 14 NewsBreak 0x6f1e8 -[FeedViewController collectionView:cellForItemAtIndexPath:] + 1951 (FeedViewController.m:1951) 15 UIKitCore 0x9f6340 __112-[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:isFocused:notify:]_block_invoke.394 + 52 16 UIKitCore 0x7ff30 +[UIView(Animation) performWithoutAnimation:] + 76 17 UIKitCore 0x2782d4 -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:isFocused:notify:] + 1208 18 UIKitCore 0x2779b0 -[UICollectionView _createVisibleViewsForSingleCategoryAttributes:limitCreation:fadeForBoundsChange:] + 524 19 UIKitCore 0x3a2aa8 -[UICollectionView _createVisibleViewsForAttributes:fadeForBoundsChange:notifyLayoutForVisibleCellsPass:] + 300 20 UIKitCore 0x1acf18 -[UICollectionView _updateVisibleCellsNow:] + 3092 21 UIKitCore 0x3057c4 -[UICollectionView layoutSubviews] + 288 22 UIKitCore 0xd688 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2424 23 QuartzCore 0x78c28 CA::Layer::layout_if_needed(CA::Transaction*) + 496 24 UIKitCore 0x50138 -[UIView(Hierarchy) layoutBelowIfNeeded] + 312 25 UIKitCore 0xde5a4 -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:animator:animationHandler:] + 288 26 NewsBreak 0x6db5c -[FeedViewController updateCollection:updates:completion:] + 1791 (FeedViewController.m:1791) 27 NewsBreak 0x112348 -[FeedProvider startUpdateCollection:] + 1067 (FeedProvider.m:1067) 28 libdispatch.dylib 0x2370 _dispatch_call_block_and_release + 32 29 libdispatch.dylib 0x40d0 _dispatch_client_callout + 20 30 libdispatch.dylib 0x129e0 _dispatch_main_queue_drain + 980 31 libdispatch.dylib 0x125fc _dispatch_main_queue_callback_4CF + 44 32 CoreFoundation 0x56204 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16 33 CoreFoundation 0x53440 __CFRunLoopRun + 1996 34 CoreFoundation 0x52830 CFRunLoopRunSpecific + 588 35 GraphicsServices 0x11c4 GSEventRunModal + 164 36 UIKitCore 0x3d2eb0 -[UIApplication _run] + 816 37 UIKitCore 0x4815b4 UIApplicationMain + 340 38 NewsBreak 0xa6dc main + 17 (main.m:17) Looking forward to the subsequent iOS version can fix this problem can reduce the impact on online users, thank you!
Topic: UI Frameworks SubTopic: UIKit
2
0
286
Dec ’24
Regarding the display of AppleArcade access points when playing iOS apps on visionOS.
[The problem that is occurring] The game apps in development are compatible with iOS, macOS, tvOS, and visionOS. In the Game app under development, the AppleArcade access point is placed in the main menu. In visionOS, when the main menu is opened, the GameCenter dashboard is automatically launched within 1~2 seconds after the main menu is displayed. This condition occurs every time the menu is re-opened. On iOS, macOS, and tvOS, the dashboard appears after pressing the GameCenter access point icon. [What you want to solve] We would like to make it so that the Game Center dashboard is launched after the access point icon is pressed on visionOS as it is on other operating systems. Or, if there is a standard implementation method for visionOS, please let us know.
1
0
517
Dec ’24