Swiftui 主详图视图:在视图之间跳转

Swiftui 主详图视图:在视图之间跳转,swiftui,swiftui-navigationlink,Swiftui,Swiftui Navigationlink,[简略版] 我需要在视图之间导航的帮助。我已经完成了我的家庭作业,并发现这可以通过一个布尔变量来实现,该布尔变量与isActive具有读/写绑定。但到目前为止还不起作用 下面是代码的摘录。在顶级视图中,它显示了一个人员列表,其中每个人都有一个用于编辑人员属性的导航链接 目前,我有两个其他视图来管理列表:ClearList和NewPerson。我已经嵌入这两个作为进一步的导航链接 我现在想要实现的是,当按下ClearList中的按钮时,视图会自动更改为NewPerson 下面是几次失败的尝试之一。

[简略版]

我需要在视图之间导航的帮助。我已经完成了我的家庭作业,并发现这可以通过一个布尔变量来实现,该布尔变量与isActive具有读/写绑定。但到目前为止还不起作用

下面是代码的摘录。在顶级视图中,它显示了一个人员列表,其中每个人都有一个用于编辑人员属性的导航链接

目前,我有两个其他视图来管理列表:ClearList和NewPerson。我已经嵌入这两个作为进一步的导航链接

我现在想要实现的是,当按下ClearList中的按钮时,视图会自动更改为NewPerson

下面是几次失败的尝试之一。我在AppState中包含了布尔变量,以便从所有视图中访问它,但当它被更改时,什么也不会发生

再次感谢您的帮助

struct Person: Identifiable, Hashable {
    let id: Int
    var name: String
}

class AppState : ObservableObject {
    @Published var activeIds : [Int] = [0,1]
    @Published var persons: [Person] = [Person(id: 0, name: "Dummy1"),
                                    Person(id: 1, name: "Dummy2"),
                                    Person(id: 2, name: "Dummy3")]
    
    @Published var newPersonViewActive: Bool = false // by setting this variable to true,
                                                     // I want to switch to the newPerson view.
                                                     // Doesn't work so far... 

    var activePersons : [Person] {
        return activeIds.compactMap { id in
            persons.first(where: { $0.id == id
            })
        }
    }
        
}

struct ContentView: View {
    @StateObject var state = AppState()
    
    var body: some View {
        TabView {
            NavigationView {
                List {
                    NavigationLink(
                        destination: ClearList(state: state)
                        label: {Text("clear list")}
                    )
                    ForEach(state.activePersons, id: \.self) { person in
                        NavigationLink(
                            destination: EditPerson(person: state.bindingForId(id: person.id)),
                            label: {
                                VStack (alignment: .leading) {
                                    Text(person.name)
                                        .font(.system(size: 26, weight: .regular))
                         
                                }.padding(15)
                            })
                    }
                    NavigationLink(
                        destination: NewPerson(state: state),
                        isActive: $state.newPersonViewActive,
                        label: {Image(systemName: "person.crop.circle.badge.plus")})
                }.environment(\.defaultMinListRowHeight, 30)
                .navigationTitle("Participants")
            }
            .tabItem{
                Image(systemName: "square.and.pencil")
                Text("Planning")
            }
        }
    }
}

struct EditPerson : View {
    
    // manage the current order of a particular person

    }
}

struct ClearList : View {
    @ObservedObject var state : AppState
    
    var body: some View {
        Button(action: {
            state.activePersonsIds = []
            state.newPersonViewActive = true // I thought this would make the
                                             // newPerson view active.
                                             // It doesn't...

    }
}

struct NewPerson: View {
    @ObservedObject var state : AppState
    var body: some View {

// add a new person
        
    }
}

与其将“清除”按钮设置为转到另一个要清除的按钮的页面的
NavigationLink
,不如设置一个非导航链接按钮来清除列表并按下
NewPerson
视图:

struct ContentView: View {
    @StateObject var state = AppState()
    
    var body: some View {
        TabView {
            NavigationView {
                List {
                    Button(action: { //<-- Here
                        state.activeIds = []
                        state.newPersonViewActive = true
                    }) {
                        Text("Clear")
                    }
                    ForEach(state.activePersons, id: \.self) { person in
                        NavigationLink(
                            destination: EditPerson(person: state.bindingForId(id: person.id)),
                            label: {
                                VStack (alignment: .leading) {
                                    Text(person.name)
                                        .font(.system(size: 26, weight: .regular))
                                    
                                }.padding(15)
                            })
                    }
                    NavigationLink(
                        destination: NewPerson(state: state),
                        isActive: $state.newPersonViewActive,
                        label: {Image(systemName: "person.crop.circle.badge.plus")})
                }.environment(\.defaultMinListRowHeight, 30)
                .navigationTitle("Participants")
            }
            .tabItem{
                Image(systemName: "square.and.pencil")
                Text("Planning")
            }
        }
    }
}

struct Person: Identifiable, Hashable {
    let id: Int
    var name: String
}

class AppState : ObservableObject {
    @Published var activeIds : [Int] = [0,1]
    @Published var persons: [Person] = [Person(id: 0, name: "Dummy1"),
                                        Person(id: 1, name: "Dummy2"),
                                        Person(id: 2, name: "Dummy3")]
    
    @Published var newPersonViewActive: Bool = false
    
    var activePersons : [Person] {
        return activeIds.compactMap { id in
            persons.first(where: { $0.id == id
            })
        }
    }
    
    func bindingForId(id: Int) -> Binding<Person> {
        .init { () -> Person in
            self.persons.first(where: { $0.id == id }) ?? Person(id: -1, name: "()")
        } set: { (newValue) in
            self.persons = self.persons.map {
                if $0.id == id {
                    return newValue
                } else {
                    return $0
                }
            }
        }
        
    }
    
}

struct EditPerson : View {
    @Binding var person : Person
    
    var body: some View {
        Text("Edit")
    }
}

struct NewPerson: View {
    @ObservedObject var state : AppState
    var body: some View {
        Text("New person")
    }
}

我想,我找到了一个解决方案,正如最初的预期:显然“onDisappear{state.newPersonViewActive=true}”(正如lorem ipsum所建议的,谢谢,顺便说一句)可以与“.dislose()”结合使用:


结构ClearList:视图{
@ObservedObject变量状态:AppState
@环境(\.presentationMode)变量presentationMode:绑定
var body:一些观点{
按钮(操作:{
state.activeIds.removeAll()

self.presentationMode.wrappedValue.discouse()文件//你是在要求别人帮你写代码吗?这不是一个代码编写服务。不,我不想比这里的任何人得到更多的帮助。我只是需要一些建议。这是一个不起作用的积极的东西。我应该以什么方式寻求帮助?我应该发布失败尝试的代码吗?我应该提供更少的背景吗d?当然,我没有必要描述我的项目。你认为SO只提供所需的信息更合适吗?你应该查看以改进、编辑和格式化你的问题。删除所有不必要的代码阅读a是什么当你有明确的计划时,我们可以试着帮你解决问题,但就目前而言您要求为您编写所有内容,以便我们提供一个可接受的答案。好的,谢谢。我已经开始缩短代码。我稍后会完成。我已经缩短了代码,并包含了我尝试过的许多版本中不起作用的一个。希望这是可以的。事实上,这将是最简单的解决方案。但是,我想继续nt防止用户无意中单击“清除”和导航链接是实现此目的的一种方法。实现此目的的正常方法是通过
警报
操作表
,允许他们确认自己的选择。我已更新了我的答案,以包括您似乎要求的内容。不过,我建议不要使用此选项。
struct ClearList : View {
    @ObservedObject var state : AppState
    @Environment(\.presentationMode) private var presentationMode

    var body: some View {
        Button(action: {
            state.activeIds = []
            presentationMode.wrappedValue.dismiss()
            DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                state.newPersonViewActive = true
            }
        }) {
            Text("Clear")
        }
    }
}

struct ClearList: View {
    @ObservedObject var state : AppState
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    
    var body: some View {
        Button(action: {
            state.activeIds.removeAll()
            self.presentationMode.wrappedValue.dismiss()     //  <---       
        }) {
            Text("clear list")
        }.onDisappear{state.newPersonViewActive = true}      //  <---
    }