如何在 macOS 上的 SwiftUI 中从边栏列表中干净地删除元素
How do I cleanly delete elements from a Sidebar List in SwiftUI on macOS
我想为用户提供从 macOS 中 SwiftUI 应用侧边栏中删除 List
元素的选项。
这是我目前拥有的:
import Foundation
import SwiftUI
@main
struct FoobarApp: App {
@StateObject private var modelData = ModelData()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(modelData)
}
.commands {
}
}
}
class ModelData: ObservableObject {
@Published var myLinks = [URL(string: "https://google.com")!, URL(string: "https://apple.com")!, URL(string: "https://amazon.com")!]
}
struct ContentView: View {
@EnvironmentObject var modelData: ModelData
@State private var selected: URL?
var body: some View {
NavigationView {
List(selection: $selected) {
Section(header: Text("Bookmarks")) {
ForEach(modelData.myLinks, id: \.self) { url in
NavigationLink(destination: Text("Viewing detailed data for: \(url)") ) {
Text(url.absoluteString)
}
.tag(url)
}
}
}
.onDeleteCommand {
if let selection = selected {
modelData.myLinks.remove(at: modelData.myLinks.firstIndex(of: selection)!)
}
}
.toolbar {
Button("Selected") {
print(selected ?? "Nothing selected")
}
}
Text("Choose a link")
}
.frame(minWidth: 200, minHeight: 500)
}
}
当我 select 侧边栏之一 link 并按下键盘上的 delete
按钮时,link 会被删除,但详细视图不会'总是被清除。
这是我所指内容的 gif:
我希望详细视图在用户删除 link 后恢复为默认文本 Choose a link
。有办法解决这个问题吗?
此外,我注意到在 link 被删除后 ContentView.selected
没有被清除。这是预期的吗? (我包含了一个 Selected
按钮来打印这个变量的内容)
我正在使用 macOS 12.2.1 & Xcode 13.2.1.
提前致谢。
这不起作用的原因是,当侧边栏中的状态发生变化时,右侧的 Destinationview 不会更新。将逻辑移动到视图模型并创建一个指定的视图,其中包含 UI 的详细信息。
将选定的变量移动到您的视图模型:
class ModelData: ObservableObject {
@Published var myLinks = [
URL(string: "https://google.com")!,
URL(string: "https://apple.com")!,
URL(string: "https://amazon.com")!]
@Published var selected: URL?
}
为目的地创建新视图:
struct DestinationView: View{
@EnvironmentObject var modelData: ModelData
var body: some View{
if let selected = modelData.selected{
Text("Viewing detailed data for: \(selected)")
}else{
Text("Choose a link")
}
}
}
更改导航视图目的地:
NavigationLink(destination: DestinationView() ) {
Text(url.absoluteString)
}
更改您的 ondelete 修饰符:
if let selection = modelData.selected {
modelData.myLinks.remove(at: modelData.myLinks.firstIndex(of: selection)!)
}
modelData.selected = nil
我想为用户提供从 macOS 中 SwiftUI 应用侧边栏中删除 List
元素的选项。
这是我目前拥有的:
import Foundation
import SwiftUI
@main
struct FoobarApp: App {
@StateObject private var modelData = ModelData()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(modelData)
}
.commands {
}
}
}
class ModelData: ObservableObject {
@Published var myLinks = [URL(string: "https://google.com")!, URL(string: "https://apple.com")!, URL(string: "https://amazon.com")!]
}
struct ContentView: View {
@EnvironmentObject var modelData: ModelData
@State private var selected: URL?
var body: some View {
NavigationView {
List(selection: $selected) {
Section(header: Text("Bookmarks")) {
ForEach(modelData.myLinks, id: \.self) { url in
NavigationLink(destination: Text("Viewing detailed data for: \(url)") ) {
Text(url.absoluteString)
}
.tag(url)
}
}
}
.onDeleteCommand {
if let selection = selected {
modelData.myLinks.remove(at: modelData.myLinks.firstIndex(of: selection)!)
}
}
.toolbar {
Button("Selected") {
print(selected ?? "Nothing selected")
}
}
Text("Choose a link")
}
.frame(minWidth: 200, minHeight: 500)
}
}
当我 select 侧边栏之一 link 并按下键盘上的 delete
按钮时,link 会被删除,但详细视图不会'总是被清除。
这是我所指内容的 gif:
我希望详细视图在用户删除 link 后恢复为默认文本 Choose a link
。有办法解决这个问题吗?
此外,我注意到在 link 被删除后 ContentView.selected
没有被清除。这是预期的吗? (我包含了一个 Selected
按钮来打印这个变量的内容)
我正在使用 macOS 12.2.1 & Xcode 13.2.1.
提前致谢。
这不起作用的原因是,当侧边栏中的状态发生变化时,右侧的 Destinationview 不会更新。将逻辑移动到视图模型并创建一个指定的视图,其中包含 UI 的详细信息。
将选定的变量移动到您的视图模型:
class ModelData: ObservableObject { @Published var myLinks = [ URL(string: "https://google.com")!, URL(string: "https://apple.com")!, URL(string: "https://amazon.com")!] @Published var selected: URL? }
为目的地创建新视图:
struct DestinationView: View{ @EnvironmentObject var modelData: ModelData var body: some View{ if let selected = modelData.selected{ Text("Viewing detailed data for: \(selected)") }else{ Text("Choose a link") } } }
更改导航视图目的地:
NavigationLink(destination: DestinationView() ) { Text(url.absoluteString) }
更改您的 ondelete 修饰符:
if let selection = modelData.selected { modelData.myLinks.remove(at: modelData.myLinks.firstIndex(of: selection)!) } modelData.selected = nil