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