我想知道SwiftUI(在我撰写本文时为Xcode 11 beta 6)中onAppear和onDisappear的行为是开发人员会发现更有用的东西,还是仅仅是一个问题而不是功能。
现在,如果我们使用级联导航,就像您在我附加的示例代码中发现的那样(在Xcode 11b6中编译并运行良好),则来回导航的用户的控制台输出只会在出现以下情况时触发onAppear:向前的新 View 加载(意味着更深入)。
在导航中:
根-> NestedView1-> NestedView2-> NestedView3,
在每个 View 阶段添加调试助手时,
.onAppear(perform: {print("onAppear level N")})
.onDisappear(perform: {print("onDisappear level N")})
调试控制台将显示
onAppear root level 0
onAppear level 1
onAppear level 2
onAppear level 3
(没有onDisappear触发)
但是回去
根
调试控制台将不显示任何内容
(没有onAppear或onDisappear触发)
struct NestedViewLevel3: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
var body: some View {
VStack {
Spacer()
Text("Level 3")
Spacer()
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
Text("Back")
.padding(.horizontal, 15)
.padding(.vertical, 2)
.foregroundColor(Color.white)
.clipped(antialiased: true)
.background(
RoundedRectangle(cornerRadius: 20)
.foregroundColor(Color.blue)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 40, alignment: .center)
)
}
Spacer()
}
.navigationBarBackButtonHidden(false)
.navigationBarTitle("Level 3", displayMode: .inline)
.onAppear(perform: {print("onAppear level 3")})
.onDisappear(perform: {print("onDisappear level 3")})
}
}
struct NestedViewLevel2: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
var body: some View {
VStack {
Spacer()
NavigationLink(destination: NestedViewLevel3()) {
Text("To level 3")
.padding(.horizontal, 15)
.padding(.vertical, 2)
.foregroundColor(Color.white)
.clipped(antialiased: true)
.background(
RoundedRectangle(cornerRadius: 20)
.foregroundColor(Color.gray)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 40, alignment: .center)
)
.shadow(radius: 10)
}
Spacer()
Text("Level 2")
Spacer()
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
Text("Back")
.padding(.horizontal, 15)
.padding(.vertical, 2)
.foregroundColor(Color.white)
.clipped(antialiased: true)
.background(
RoundedRectangle(cornerRadius: 20)
.foregroundColor(Color.blue)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 40, alignment: .center)
)
}
Spacer()
}
.navigationBarBackButtonHidden(false)
.navigationBarTitle("Level 2", displayMode: .inline)
.onAppear(perform: {print("onAppear level 2")})
.onDisappear(perform: {print("onDisappear level 2")})
}
}
struct NestedViewLevel1: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
var body: some View {
VStack {
Spacer()
NavigationLink(destination: NestedViewLevel2()) {
Text("To level 2")
.padding(.horizontal, 15)
.padding(.vertical, 2)
.foregroundColor(Color.white)
.clipped(antialiased: true)
.background(
RoundedRectangle(cornerRadius: 20)
.foregroundColor(Color.gray)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 40, alignment: .center)
)
.shadow(radius: 10)
}
Spacer()
Text("Level 1")
Spacer()
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
Text("Back")
.padding(.horizontal, 15)
.padding(.vertical, 2)
.foregroundColor(Color.white)
.clipped(antialiased: true)
.background(
RoundedRectangle(cornerRadius: 20)
.foregroundColor(Color.blue)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 40, alignment: .center)
)
}
Spacer()
}
.navigationBarBackButtonHidden(false)
.navigationBarTitle("Level 1", displayMode: .inline)
.onAppear(perform: {print("onAppear level 1")})
.onDisappear(perform: {print("onDisappear level 1")})
}
}
struct RootViewLevel0: View {
var body: some View {
NavigationView {
VStack {
Spacer()
NavigationLink(destination: NestedViewLevel1()) {
Text("To level 1")
.padding(.horizontal, 15)
.padding(.vertical, 2)
.foregroundColor(Color.white)
.clipped(antialiased: true)
.background(
RoundedRectangle(cornerRadius: 20)
.foregroundColor(Color.gray)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 40, alignment: .center)
)
.shadow(radius: 10)
}
Spacer()
}
}
.navigationBarTitle("Root level 0", displayMode: .inline)
.navigationBarBackButtonHidden(false)
.navigationViewStyle(StackNavigationViewStyle())
.onAppear(perform: {print("onAppear root level 0")})
.onDisappear(perform: {print("onDisappear root level 0")})
}
}
struct ContentView: View {
var body: some View {
RootViewLevel0()
}
}
}
现在,开发人员宁愿拥有onAppear和onDisappear:
1)被触发以启动仅需一次且仅当用户向前行驶时才执行的 Action ,例如当前观察到的行为。
2)每次 View 出现时都会触发,更像是 Action 名称的意思,即向后,向前和任意次数。
我会选择选项2,简单而又残酷(以及当前需要什么),但是我在NavigationView上还是个天真的新手,而选项2可能会打破很多我没有考虑的既定范例。
您的反馈将帮助我了解SwiftUI的相应Feedback Assistant案例是否有正当理由。
最佳答案
这是苹果公司的错误。.onAppear()
现在可以在iOS 13.1和Xcode 11 Beta 7中正常工作。
前后导航到NavigationView时,.onAppear()
将触发。