Provide views, controls, and layout structures for declaring your app's user interface using SwiftUI.

Posts under SwiftUI tag

200 Posts

Post

Replies

Boosts

Views

Activity

MapProxy conversion from screen to coords is wrong on macOS
Try the following code on macOS, and you'll see the marker is added in the wrong place, as the conversion from screen coordinates to map coordinates doesn't work correctly. The screenCoord value is correct, but reader.convert(screenCoord, from: .local) offsets the resulting coordinate by the height of the content above the map, despite the .local parameter. struct TestMapView: View { @State var placeAPin = false @State var pinLocation :CLLocationCoordinate2D? = nil @State private var cameraProsition: MapCameraPosition = .camera( MapCamera( centerCoordinate: .denver, distance: 3729, heading: 92, pitch: 70 ) ) var body: some View { VStack { Text("This is a bug demo.") Text("If there are other views above the map, the MapProxy doesn't convert the coordinates correctly.") MapReader { reader in Map( position: $cameraProsition, interactionModes: .all ) { if let pl = pinLocation { Marker("(\(pl.latitude), \(pl.longitude))", coordinate: pl) } } .onTapGesture(perform: { screenCoord in pinLocation = reader.convert(screenCoord, from: .local) placeAPin = false if let pinLocation { print("tap: screen \(screenCoord), location \(pinLocation)") } }) .mapControls{ MapCompass() MapScaleView() MapPitchToggle() } .mapStyle(.standard(elevation: .automatic)) } } } } extension CLLocationCoordinate2D { static var denver = CLLocationCoordinate2D(latitude: 39.742043, longitude: -104.991531) } (FB13135770)
5
1
1.3k
Dec ’24
Why am I unable to render .dae file in Playground?
This is my code in ContentView: import SwiftUI import SceneKit import PlaygroundSupport struct ContentView: View { var body: some View { VStack { Text("SceneKit with SwiftUI") .font(.headline) .padding() SceneView( scene: loadScene(), options: [.autoenablesDefaultLighting, .allowsCameraControl] ) .frame(width: 400, height: 400) .border(Color.gray, width: 1) } } } func loadScene() -> SCNScene? { if let fileURL = Bundle.main.url(forResource: "a", withExtension: "dae") { do { let scene = try SCNScene(url: fileURL, options: [ SCNSceneSource.LoadingOption.checkConsistency: true ]) print("Scene loaded successfully.") return scene } catch { print("Error loading scene: \(error.localizedDescription)") } } else { print("Error: Unable to locate a.dae in Resources.") } return nil } a.dae file exists in the Resources section of macOS Playground app. And a.dae can be viewed in Xcode. Console shows: Error loading scene: The operation couldn’t be completed. (Foundation._GenericObjCError error 0.) Any input is appreciated.
1
0
512
Dec ’24
Using TextField:text:selection crashes on macOS
I am trying out the new TextField selection ability on macOS but it crashes in various different ways with extremely large stack traces. Looks like it is getting into re-entrant function calls. A similar problem is described on the SwiftUI forums with no responses yet. Here is my simple example struct ContentView: View { @State private var text: String = "" @State private var selection: TextSelection? var body: some View { TextField("Message", text: $text, selection: $selection) .padding() } } Setting text to a value like "Hallo World" causes an instant crash as soon as you start typing in the TextField. Setting text empty (as in example above) lets you edit the text but as it crashes as soon as you commit it (press enter). Any workarounds or fixes?
4
1
506
Dec ’24
Navigation Bar Jumping Issue in SwiftUI with TabView and NavigationStack (Observed in Apple's Example Code)
I recently started exploring the latest version of SwiftUI and encountered an issue while working with TabView and NavigationStack. I downloaded the example code provided by Apple and began making changes to explore new SwiftUI features. However, I noticed that the navigation bar "jumps" or resets when switching between tabs, even in their example implementation. Here are some changes which I made below in the files: LibraryView: .navigationTitle("Library") .navigationBarTitleDisplayMode(.inline) .toolbarBackground(Color("AccentColor"),for: .navigationBar) WatchNowView: .navigationTitle("Watch Now") .navigationBarTitleDisplayMode(.inline) .toolbarBackground(Color("AccentColor"),for: .navigationBar) example code url :- destinationVideo I suspect the issue arises because each tab bar item has its own NavigationStack. When we set a navigation title for each view, the NavigationStack resets the navigation bar on view appearance, which causes this visual bug. Thank you!
0
0
283
Dec ’24
Navigation Bar Jumping Issue in SwiftUI with TabView and NavigationStack (Observed in Apple's Example Code)
I recently started exploring the latest version of SwiftUI and came across a issue while working with TabView and NavigationStack. I downloaded Apple’s provided example code and began making changes to explore new SwiftUI changes. i added navigationtitle and toolbarBackground to first two tab. However, I noticed that the navigation bar "jumps" or resets when switching between tabs, even in their own example implementation. Here’s a simplified version of the example code I was testing: file name - WatchNowView .navigationTitle("Watch Now") .navigationBarTitleDisplayMode(.inline) .toolbarBackground(Color("AccentColor"),for: .navigationBar) file name - LibraryView .navigationTitle("Library") .navigationBarTitleDisplayMode(.inline) .toolbarBackground(Color("AccentColor"),for: .navigationBar) Here is a sample code link (provided by Apple developer document) : destination-video I have attached a gif below demonstrating this issue: Questions: Is this behavior expected in the latest version of SwiftUI, or is it a bug in the framework's handling of TabView and NavigationStack? Is this behavior expected as all tabbar item have their own nativationStack? Are there any official recommendations for maintaining seamless navigation experiences when using navigationStack and TabView? This behavior detracts from the otherwise smooth experience SwiftUI aims to provide. If anyone has encountered this issue and found a workaround, I’d greatly appreciate your insights. I hope Apple can review this problem to enhance the usability of SwiftUI. Thank you!
3
3
307
Dec ’24
Why is ScrollView / LazyVStack retaining Views which causes memory leaks in the end?
Recently I noticed how my ViewModels aren't deallocating and they end up as a memory leaks. I found something similar in this thread but this is also happening without using @Observation. Check the source code below: class CellViewModel: Identifiable { let id = UUID() var color: Color = Color.red init() { print("init") } deinit { print("deinit") } } struct CellView: View { let viewModel: CellViewModel var body: some View { ZStack { Color(viewModel.color) Text(viewModel.id.uuidString) } } } @main struct LeakApp: App { @State var list = [CellViewModel]() var body: some Scene { WindowGroup { Button("Add") { list.append(CellViewModel()) } Button("Remove") { list = list.dropLast() } ScrollView { LazyVStack { ForEach(list) { model in CellView(viewModel: model) } } } } } } When I tap the Add button twice in the console I will see "init" message twice. So far so good. But then I click the Remove button twice and I don't see any "deinit" messages. I used the Debug Memory Graph in Xcode and it showed me that two CellViewModel objects are in the memory and they are owned by the CellView and some other objects that I don't know where are they coming from (I assume from SwiftUI internally). I tried using VStack instead of LazyVStack and that did worked a bit better but still not 100% "deinits" were in the Console. I tried using weak var struct CellView: View { weak var viewModel: CellViewModel? .... } but this also helped only partially. The only way to fully fix this is to have a separate class that holds the list of items and to use weak var viewModel: CellViewModel?. Something like this: class CellViewModel: Identifiable { let id = UUID() var color: Color = Color.red init() { print("init") } deinit { print("deinit") } } struct CellView: View { var viewModel: CellViewModel? var body: some View { ZStack { if let viewModel = viewModel { Color(viewModel.color) Text(viewModel.id.uuidString) } } } } @Observable class ListViewModel { var list = [CellViewModel]() func insert() { list.append(CellViewModel()) } func drop() { list = list.dropLast() } } @main struct LeakApp: App { @State var viewModel = ListViewModel() var body: some Scene { WindowGroup { Button("Add") { viewModel.insert() } Button("Remove") { viewModel.drop() } ScrollView { LazyVStack { ForEach(viewModel.list) { model in CellView(viewModel: model) } } } } } } But this won't work if I want to use @Bindable such as @Bindable var viewModel: CellViewModel? I don't understand why SwiftUI doesn't want to release the objects?
0
1
483
Dec ’24
SwiftUI bug, when removing a TabView all other tabs have `onAppear` and `onDisappear` triggered
Xcode 14.1 Running on iPhone 14 Pro max simulator 16.1 Code... import SwiftUI struct ContentView: View { @State var loggedIn: Bool = false var body: some View { switch loggedIn { case false: Button("Login") { loggedIn = true } .onAppear { print("🍏 Login on appear") } .onDisappear { print("🍎 Login on disappear") } case true: TabView { NavigationView { Text("Home") .navigationBarTitle("Home") .onAppear { print("🍏 Home on appear") } .onDisappear { print("🍎 Home on disappear") } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button("Logout") { loggedIn = false } } } } .tabItem { Image(systemName: "house") Text("Home") } NavigationView { Text("Savings") .navigationBarTitle("Savings") .onAppear { print("🍏 Savings on appear") } .onDisappear { print("🍎 Savings on disappear") } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button("Logout") { loggedIn = false } } } } .tabItem { Image(systemName: "dollarsign.circle") Text("Savings") } NavigationView { Text("Profile") .navigationBarTitle("Profile") .onAppear { print("🍏 Profile on appear") } .onDisappear { print("🍎 Profile on disappear") } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button("Logout") { loggedIn = false } } } } .tabItem { Image(systemName: "person") Text("Profile") } } .onAppear { print("🍏 Tabview on appear") } .onDisappear { print("🍎 Tabview on disappear") } } } } Video of bug... https://youtu.be/oLKjRGL2lX0 Example steps... Launch app Tap Login Tap Savings tab Tap Home tab Tap Logout Expected Logs... 🍏 Login on appear 🍏 Tabview on appear 🍏 Home on appear 🍎 Login on disappear 🍏 Savings on appear 🍎 Home on disappear 🍏 Home on appear 🍎 Savings on disappear 🍏 Login on appear 🍎 Home on disappear 🍎 Tabview on disappear Actual logs... 🍏 Login on appear 🍏 Tabview on appear 🍏 Home on appear 🍎 Login on disappear 🍏 Savings on appear 🍎 Home on disappear 🍏 Home on appear 🍎 Savings on disappear 🍏 Login on appear 🍏 Savings on appear 🍎 Home on disappear 🍎 Savings on disappear 🍎 Tabview on disappear Error... 10 and 12 in the actual logs should not be there at all. For each tab that you have visited (that is not the current tab) it will call onAppear and onDisappear for it when the tab view is removed.
1
4
1.1k
Dec ’24
Why first View on my NavigationStack appears again when I switch branch?
Hello, In my app, I have an onboarding made of multiple steps in a NavigationStack. I also have a state variable that controls an if else root branch to show either the onboarding NavigationStack or the app content if the onboarding is finished. I noticed that when I end the onboarding (i.e. I switch to the other part of the if else root branch), the onAppear of the first View in the NavigationStack of the onboarding is called again. I don’t understand why. Is this a bug? Thanks, Axel enum Step { case one case two case three case four } struct ContentView: View { @State private var isFinished: Bool = false @State private var steps: [Step] = [] var body: some View { if isFinished { Button("Restart") { steps = [] isFinished = false } } else { NavigationStack(path: $steps) { VStack { Text("Start") .onAppear { print("onAppear: start") } Button("Go to step 1") { steps.append(.one) } } .navigationDestination(for: Step.self) { step in switch step { case .one: Button("Go to step 2") { steps.append(.two) } .onAppear { print("onAppear: step 1") } case .two: Button("Go to step 3") { steps.append(.three) } .onAppear { print("onAppear: step 2") } case .three: Button("Go to step 4") { steps.append(.four) } .onAppear { print("onAppear: step 3") } case .four: Button("End") { isFinished = true } .onAppear { print("onAppear: end") } } } } .onAppear { print("onAppear: NavigationStack") } } } }
6
0
751
Dec ’24
DocumentGroup Fails to Display Document Content in Mac Catalyst App
When running a Mac Catalyst app that uses DocumentGroup, the app fails to display the document content. The document picker works as expected, but creating a new document or opening an existing one results in an empty window. This issue occurs regardless of whether “Optimize for Mac” or “Scale iPad” is selected. Steps to Reproduce: 1. Download the sample project provided by Apple for building a document-based app in SwiftUI. 2. Delete the macOS version of the project. 3. Add a Mac Catalyst version of the app. 4. In the Mac Catalyst settings, select “Optimize for Mac” (the bug also appears if it is “Scale iPad”). 5. Run the project on macOS. Expected Result: The app should correctly display the content of the document when creating or opening it. Actual Result: The app opens an empty window when a new document is created or an existing one is opened. Impact: We have received multiple 1-star reviews, and our retention has dropped by two-thirds due to this issue. Environment: Xcode 16.1; macOS 15.1 & 15.2 (on 15.0 it works fine) Has anyone experienced the same issue? I filed multiple reports so far.
3
1
933
Dec ’24
How to draw emojis like the Lock Screen customisation?
On iOS you can create a new Lock Screen that contains a bunch of emoji, and they'll get put on the screen in a repeating pattern, like this: When you have two or more emoji they're placed in alternating patterns, like this: How do I write something like that? I need to handle up to three emoji, and I need the canvas as large as the device's screen, and it needs to be saved as an image. Thanks! (I've already written an emojiToImage() extension on String, but it just plonks one massive emoji in the middle of an image, so I'm doing something wrong there.)
1
0
581
Dec ’24
SwiftUI.Stepper bug from `onIncrement` and `onDecrement`?
Ok… I'm baffled here… this is very strange. Here is a SwiftUI app: import SwiftUI @main struct StepperDemoApp: App { func onIncrement() { print(#function) } func onDecrement() { print(#function) } var body: some Scene { WindowGroup { Stepper { Text("Stepper") } onIncrement: { self.onIncrement() } onDecrement: { self.onDecrement() } } } } When I run in the app in macOS (Xcode 16.0 (16A242) and macOS 14.6.1 (23G93)), I see some weird behavior from these buttons. My experiment is tapping + + + - - -. Here is what I see printed: onIncrement() onIncrement() onIncrement() onIncrement() onDecrement() What I expected was: onIncrement() onIncrement() onIncrement() onDecrement() onDecrement() onDecrement() Why is an extra onIncrement being called? And why is one onDecrement dropping on the floor? Deploying the app to iPhone Simulator does not repro this behavior (I see the six "correct" logs from iPhone Simulator).
9
0
693
Dec ’24
Only Apple based music devices show view
The following is my playground code. Any of the apple audio units show the plugin view, however anything else (i.e. kontakt, spitfire, etc.) does not. It does not error, just where the visual is expected is blank. import AppKit import PlaygroundSupport import AudioToolbox import AVFoundation import CoreAudioKit let manager = AVAudioUnitComponentManager.shared() let description = AudioComponentDescription(componentType: kAudioUnitType_MusicDevice, componentSubType: 0, componentManufacturer: 0, componentFlags: 0, componentFlagsMask: 0) var deviceComponents = manager.components(matching: description) var names = deviceComponents.map{$0.name} let pluginName: String = "AUSampler" // This works //let pluginName: String = "Kontakt" // This does not var plugin = deviceComponents.filter{$0.name.contains(pluginName)}.first! print("Plugin name: \(plugin.name)") var customViewController:NSViewController? AVAudioUnit.instantiate(with: plugin.audioComponentDescription, options: []){avAudioUnit, error in var ilip = avAudioUnit!.auAudioUnit.isLoadedInProcess print("Loaded in process: \(ilip)") guard error == nil else { print("Error: \(error!.localizedDescription)") return } print("AudioUnit successfully created.") let audioUnit = avAudioUnit!.auAudioUnit audioUnit.requestViewController{ vc in if let viewCtrl = vc { customViewController = vc var b = vc?.view.bounds PlaygroundPage.current.liveView = vc print("Successfully added view controller.") }else{ print("Failed to load controller.") } } }
0
0
337
Dec ’24
swift ui in tableview cell gesture sometimes not call back
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let message = self.parent.viewModel.messages[indexPath.row] // var cell: RCBaseMessageCell? = tableView.dequeueReusableCell(withIdentifier: String( message.type.rawValue)) as? RCBaseMessageCell var cell = tableView.dequeueReusableCell(withIdentifier: "cell") if #available(iOS 16.0, *) { cell?.contentConfiguration = UIHostingConfiguration { Text("123").onTapGesture { print("123") } } return cell } on ios 18.1 onTapGesture sometimes will not callback ,but ios 17 16 is ok,how can i fix it
1
0
240
Dec ’24
Keep ScrollView position when adding items on the top using onAppear / onScrollTargeVisibilityChange
Related Post: Keep ScrollView position when adding items on the top I was trying to implement a message view using ScrollView + LazyVStack. This view requires pagination so I used onScrollTargeVisibilityChange modifier to detect if the first item appears on screen and a new page needs to be loaded. I learnt from the above post that scrollPositon modifier can help keep the scroll position. I tested the method mentioned in that post -- use a button to add new items to the top -- and it worked. However, when use onScrollTargeVisibilityChange modifier to add items, the view automatically scrolls to the top and cause the following loop: first item in the list appears on screen --> load and insert more items to the top --> scroll view scrolls to top --> first item appears --> load more data --> scroll to top --> first item ... --> more data... --> top ... Until it generates the error ScrollTargetVisibilityChange tried to update multiple times per frame. Here is the simplified code. struct Item: Identifiable { var id: UUID = .init() var content: String } struct ScrollViewTest: View { @State private var items: [Item] = (0...30).map {Item(content:"\($0)")}.reversed() @State private var itemID: Item.ID? @State private var page: Int = 0 var body: some View { ScrollView { LazyVStack { ForEach(items) {item in Text(item.content) .frame(height: 30) } } .scrollTargetLayout() } .scrollPosition(id: $itemID) .defaultScrollAnchor(.bottom) .onScrollTargetVisibilityChange(idType: Item.ID.self) { onScreenItemIDs in if onScreenItemIDs.first == items.first?.id { page += 1 let newItems = (page*30+1 ... (page+1)*30).map {Item(content:"\($0)")} items.insert(contentsOf: newItems.reversed(), at: 0) } } .toolbar { Button("Add") { page += 1 let newItems = (page*30+1 ... (page+1)*30).map {Item(content:"\($0)")} items.insert(contentsOf: newItems.reversed(), at: 0) } } } } I want to load data while scrolling without the need of pressing any buttons. How can I solve this problem?
0
1
276
Dec ’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
244
Dec ’24
SwiftUI Audio File Export via draggable
Hey everyone, TL;DR How do I enable a draggable TableView to drop Audio Files into Apple Music / Rekordbox / Finder? Intro / skip me I've been dabbling into Swift / SwiftUI for a few weeks now, after roughly a decade of web development. So far I've been able to piece together many things, but this time I'm stuck for hours with no success using Forums / ChatGPT / Perplexity / Trial and Error. The struggle Sometimes the target doesn't accept the dropping at all sometimes the file data is failed to be read when the drop succeeds, then only as a stream in apple music My lack of understanding / where exactly I'm stuck I think the right way is to use UTType.fileUrl but this is not accepted by other applications. I don't understand low-level aspects well enough to do things right. The code I'm just going to dump everything here, it includes failed / commented out attempts and might give you an Idea of what I'm trying to achieve. // // Tracks.swift // Tuna Family // // Created by Jan Wirth on 12/12/24. // import SwiftySandboxFileAccess import Files import SwiftUI import TunaApi struct LegacyTracks: View { @State var tracks: TunaApi.LoadTracksQuery.Data? func fetchData() { print("fetching data") Network.shared.apollo.fetch(query: TunaApi.LoadTracksQuery()) { result in switch result { case .success(let graphQLResult): self.tracks = graphQLResult.data case .failure(let error): print("Failure! Error: \(error)") } } } @State private var selection = Set<String>() var body: some View { Text("Tracks").onAppear{ fetchData() } if let tracks = tracks?.track { Table(of: LoadTracksQuery.Data.Track.self, selection: $selection) { TableColumn("Title", value: \.title) } rows : { ForEach(tracks) { track in TableRow(track) .draggable(track) // .draggable((try? File(path: track.dropped_source?.path ?? "").url) ?? test_audio.url) // This causes a compile-time error // .draggable(test_audio.url) // .draggable(DraggableTrack(url: test_audio.url)) // .itemProvider { // let provider = NSItemProvider() // if let path = self.dropped_source?.path { // if let f = try? File(path: path) { // print("Transferring", f.url) // // // } // } // // provider.register(track) // return provider // } // This does not } } .contextMenu(forSelectionType: String.self) { items in // ... Button("yoooo") {} } primaryAction: { items in print(items) // This is executed when the row is double clicked } } else { Text("Loading") } // } } } //extension Files.File: Transferable { // public static var transferRepresentation: some TransferRepresentation { // FileRepresentation(exportedContentType: .audio) { url in // SentTransferredFile( self.) // } // } //} struct DraggableTrack: Transferable { var url: URL public static var transferRepresentation: some TransferRepresentation { FileRepresentation (exportedContentType: .fileURL) { item in SentTransferredFile(test_audio.url, allowAccessingOriginalFile: true) } // FileRepresentation(contentType: .init(filenameExtension: "m4a")) { // print("file", $0) // print("Transferring fallback", test_audio.url) // return SentTransferredFile(test_audio.url, allowAccessingOriginalFile: true) // } // importing: { received in // // let copy = try Self.(source: received.file) // return Self.init(url: received.file) // } // ProxyRepresentation(exporting: \.url.absoluteString) } } extension LoadTracksQuery.Data.Track: @retroactive Identifiable { } import UniformTypeIdentifiers extension LoadTracksQuery.Data.Track: @retroactive Transferable { // static func getKind() -> UTType { // var kind: UTType = UTType.item // if let path = self.dropped_source?.path { // if let f = try? File(path: path) { // print("Transferring", f.url) // if (f.extension == "m4a") { // kind = UTType.mpeg4Audio // } // if (f.extension == "mp3") { // kind = UTType.mp3 // } // if (f.extension == "flac") { // kind = UTType.flac // } // if (f.extension == "wav") { // kind = UTType.wav // } // // } // } // return kind // } public static var transferRepresentation: some TransferRepresentation { ProxyRepresentation { $0.dropped_source?.path ?? "" } FileRepresentation(exportedContentType: .fileURL) { <#Transferable#> in SentTransferredFile(<#T##file: URL##URL#>, allowAccessingOriginalFile: <#T##Bool#>) } // FileRepresentation(contentType: .fileURL) { // print("file", $0) // if let path = $0.dropped_source?.path { // if let f = try? File(path: path) { // print("Transferring", f.url) // return SentTransferredFile(f.url, allowAccessingOriginalFile: true) // } // } // print("Transferring fallback", test_audio.url) // return SentTransferredFile(test_audio.url, allowAccessingOriginalFile: true) // } // importing: { received in // // let copy = try Self.(source: received.file) // return Self.init(_fieldData: received.file) // } // ProxyRepresentation(exporting: \.title) } }
0
0
426
Dec ’24
On a navigation bar created by a DocumentGroup, items disappear after renaming the file from the automatic Rename button in the Title Menu
On an iPad or iPhone running iPadOS / iOS 18.2 (built with Xcode 16.2), run the WritingApp sample code from https://developer.apple.com/documentation/SwiftUI/Building-a-document-based-app-with-SwiftUI from WWDC24 Then add the following struct to the project: struct NavigationBarToolbar: ToolbarContent { var body: some ToolbarContent { ToolbarItem(placement: .secondaryAction) { Button("Button 1", systemImage: "1.circle") { } } ToolbarItem(placement: .secondaryAction) { Button("Button 2", systemImage: "2.circle") { } } ToolbarItem(placement: .secondaryAction) { Button("Button 3", systemImage: "3.circle") { } } ToolbarItem(placement: .secondaryAction) { Button("Button 4", systemImage: "4.circle") { } } ToolbarItem(placement: .secondaryAction) { Button("Button 5", systemImage: "5.circle") { } } } } Comment out the original toolbar in the sample project and replace with: .toolbar(content: NavigationBarToolbar.init) Run the project and open or create a document Click on the TitleMenu and choose Rename, in order to rename the file Type in a new name and press Enter. Notice how the items of the toolbar disappear —— This issue has been submitted as feedback with number FB16100225 This issue is linked to the following feedbacks: FB14855728 FB14855668 FB14849205 FB12343963 FB15164292
0
1
275
Dec ’24