Swiftui的默认导航链接



我正在开发一个应用程序,该应用程序使用带有详细信息视图的传统边栏导航。我综合了这个应用程序来说明两个问题。

  1. 应用启动时,detail视图为空。如何通过编程方式在侧边栏中选择要在详细信息视图中显示的条目?

  2. 侧边栏允许滑动删除。如果所选的行(在详细视图中显示的行)被删除,它仍然显示在详细视图中。如何使用(例如)空视图更新详细视图?

下面是说明问题的应用程序的源代码:

import SwiftUI
class Model: ObservableObject {
var items = [Item("")]

static var loadData: Model {
let model = Model()
model.items = [Item("Books"), Item("Videos"), Item("Pics"), Item("Cars")]

return model
}
}
class Item: Identifiable, Hashable {
static func == (lhs: Item, rhs: Item) -> Bool {
lhs.name == rhs.name
}

func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
let id = UUID()

@Published var name: String

init(_ name: String) {
self.name = name
}
}

@main
struct IBTSimulatorApp: App {
@StateObject var model = Model.loadData

var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(model)
}
}
}
struct ContentView: View {
@EnvironmentObject var model: Model

var body: some View {
NavigationView {
List {
ForEach($model.items, id: .self) { $item in
NavigationLink(item.name, destination: Text(item.name))
}
.onDelete(perform: deleteItems)
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing)  {
Button(action: addItem) {
Label("Add Item", systemImage: "plus")
}
}
}
}
}

private func addItem() {
withAnimation {
model.items.append(Item("New item ((model.items.count))"))
model.objectWillChange.send()
}
}
private func deleteItems(offsets: IndexSet) {
withAnimation {
model.items.remove(atOffsets: offsets)
model.objectWillChange.send()
}
}
}

您可以使用带有标记和选择的NavigationLink版本,并将活动选择保存在持久的AppStorage变量中。

2。我希望您可以将选择设置为nil,但由于某些原因,这不起作用。但是您可以将它设置为侧边栏列表中的第一项。

一般来说,你应该让Item成为一个结构体而不是一个类。只有发布的Model应该是一个类。

class Model: ObservableObject {
var items: [Item] = []

static var loadData: Model {
let model = Model()
model.items = [Item("Books"), Item("Videos"), Item("Pics"), Item("Cars")]

return model
}
}
struct Item: Identifiable { // Change from class to struct!

let id = UUID()
var name: String

init(_ name: String) {
self.name = name
}
}

struct ContentView: View {
@StateObject var model = Model.loadData

@AppStorage("selectemItem") var selected: String? // bind to persisted var here


var body: some View {
NavigationView {
List {
ForEach(model.items) { item in //no .id needed as Item is identifiable
NavigationLink(tag: item.id.uuidString, selection: $selected) { // use link with selection here
Text(item.name)
} label: {
Text(item.name)
}
}
.onDelete(perform: deleteItems)
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing)  {
Button(action: addItem) {
Label("Add Item", systemImage: "plus")
}
}
}

Text("Nothing selected")
}
}

private func addItem() {
withAnimation {
model.objectWillChange.send()
model.items.append(Item("New item ((model.items.count))"))
}
}

private func deleteItems(offsets: IndexSet) {
withAnimation {
//            model.objectWillChange.send() // not necessary if Item is struct
self.selected = nil // for some reaseon this does not work
self.selected = model.items.first?.id.uuidString // selects first item
model.items.remove(atOffsets: offsets)
}
}
}

相关内容

  • 没有找到相关文章

最新更新