SwiftUI 2.0:关闭按钮没有关闭视图 - 如何将关闭按钮设置为 return 到上一个视图?
SwiftUI 2.0: Close button is not dismissing the view - how do I get the Close button to return to the previous view?
在这个频道和网上进行研究时,我尝试使用各种示例中的按钮和导航链接。 NavigationLink 没问题,只是 NavigationView 将我视图中的所有内容都向下推。
我有一个包含图像和文本的视图,如下所示:( x Close) 但是当我使用下面的代码时,“关闭”按钮没有任何作用。
在 ContentView()
中,我有一个 (?) 按钮,它将我从 WalkthroughView()
,然后转到 PageTabView,然后转到此视图,TabDetailsView:
ContentView():
ZStack {
NavigationView {
VStack {
Text("Hello World")
.padding()
.font(.title)
.background(Color.red)
.foregroundColor(.white)
}
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button {
withAnimation {
showOnBoarding = true
}
} label: {
Image(systemName: "questionmark.circle.fill")
}
}
}
}
.accentColor(.red)
.disabled(showOnBoarding)
.blur(radius: showOnBoarding ? 3.0 : 0)
if showOnBoarding {
WalkthroughView(isWalkthroughViewShowing: $isWalkthroughViewShowing)
}
}
.onAppear {
if !isWalkthroughViewShowing {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
withAnimation {
showOnBoarding.toggle()
isWalkthroughViewShowing = true
}
}
}
}
WalkthroughView():
var body: some View {
ZStack {
GradientView()
VStack {
PageTabView(selection: $selection)
// shows Previous/Next buttons only
ButtonsView(selection: $selection)
}
}
.transition(.move(edge: .bottom))
}
PageTabView():
var body: some View {
TabView(selection: $selection) {
ForEach(tabs.indices, id: \.self) { index in
TabDetailsView(index: index)
}
}
.tabViewStyle(PageTabViewStyle())
}
下面是 TabDetailsView():
在视图的顶部是这个关闭按钮,按下时应该会返回到 ContentView,但什么也没有发生。
struct TabDetailsView: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
let index: Int
然后,体内:
VStack(alignment: .leading) {
Spacer()
VStack(alignment: .leading) {
// Button to close each walkthrough page...
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
Image(systemName: "xmark.circle.fill")
Text("Close")
}
.padding(.leading)
.font(.title2)
.accentColor(.orange)
Spacer()
VStack {
Spacer()
Image(tabs[index].image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 415)
.padding(.leading, 10)
Text(tabs[index].title)
.font(.title)
.bold()
Text(tabs[index].text)
.padding()
Spacer()
}
.foregroundColor(.white)
}
}
if showOnBoarding {
WalkthroughView(isWalkthroughViewShowing: $isWalkthroughViewShowing)
}
像上面那样插入视图并不是标准意义上的演示,这就是提供的代码不起作用的原因。
因为这个视图是通过 showOnBoarding
显示的,所以它也应该通过 showOnBoarding
隐藏,因此解决方案是将绑定到这个状态的视图传递到视图中,它将被切换回来。
由于层次结构较深,最合适的方法是使用自定义环境值。为简单起见,我们使用 中的 ResetDefault
(您可以在代码中重命名)
因此需要修改:
if showOnBoarding {
WalkthroughView(isWalkthroughViewShowing: $isWalkthroughViewShowing)
.environment(\.resetDefault, $showOnBoarding)
}
并且在子视图中
struct TabDetailsView: View {
@Environment(\.resetDefault) var showOnBoarding
// .. other code
Button(action: {
self.showOnBoarding.wrappedValue.toggle()
}) {
Image(systemName: "xmark.circle.fill")
Text("Close")
}
在这个频道和网上进行研究时,我尝试使用各种示例中的按钮和导航链接。 NavigationLink 没问题,只是 NavigationView 将我视图中的所有内容都向下推。
我有一个包含图像和文本的视图,如下所示:( x Close) 但是当我使用下面的代码时,“关闭”按钮没有任何作用。
在 ContentView()
中,我有一个 (?) 按钮,它将我从 WalkthroughView()
,然后转到 PageTabView,然后转到此视图,TabDetailsView:
ContentView():
ZStack {
NavigationView {
VStack {
Text("Hello World")
.padding()
.font(.title)
.background(Color.red)
.foregroundColor(.white)
}
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button {
withAnimation {
showOnBoarding = true
}
} label: {
Image(systemName: "questionmark.circle.fill")
}
}
}
}
.accentColor(.red)
.disabled(showOnBoarding)
.blur(radius: showOnBoarding ? 3.0 : 0)
if showOnBoarding {
WalkthroughView(isWalkthroughViewShowing: $isWalkthroughViewShowing)
}
}
.onAppear {
if !isWalkthroughViewShowing {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
withAnimation {
showOnBoarding.toggle()
isWalkthroughViewShowing = true
}
}
}
}
WalkthroughView():
var body: some View {
ZStack {
GradientView()
VStack {
PageTabView(selection: $selection)
// shows Previous/Next buttons only
ButtonsView(selection: $selection)
}
}
.transition(.move(edge: .bottom))
}
PageTabView():
var body: some View {
TabView(selection: $selection) {
ForEach(tabs.indices, id: \.self) { index in
TabDetailsView(index: index)
}
}
.tabViewStyle(PageTabViewStyle())
}
下面是 TabDetailsView():
在视图的顶部是这个关闭按钮,按下时应该会返回到 ContentView,但什么也没有发生。
struct TabDetailsView: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
let index: Int
然后,体内:
VStack(alignment: .leading) {
Spacer()
VStack(alignment: .leading) {
// Button to close each walkthrough page...
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
Image(systemName: "xmark.circle.fill")
Text("Close")
}
.padding(.leading)
.font(.title2)
.accentColor(.orange)
Spacer()
VStack {
Spacer()
Image(tabs[index].image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 415)
.padding(.leading, 10)
Text(tabs[index].title)
.font(.title)
.bold()
Text(tabs[index].text)
.padding()
Spacer()
}
.foregroundColor(.white)
}
}
if showOnBoarding { WalkthroughView(isWalkthroughViewShowing: $isWalkthroughViewShowing) }
像上面那样插入视图并不是标准意义上的演示,这就是提供的代码不起作用的原因。
因为这个视图是通过 showOnBoarding
显示的,所以它也应该通过 showOnBoarding
隐藏,因此解决方案是将绑定到这个状态的视图传递到视图中,它将被切换回来。
由于层次结构较深,最合适的方法是使用自定义环境值。为简单起见,我们使用 ResetDefault
(您可以在代码中重命名)
因此需要修改:
if showOnBoarding {
WalkthroughView(isWalkthroughViewShowing: $isWalkthroughViewShowing)
.environment(\.resetDefault, $showOnBoarding)
}
并且在子视图中
struct TabDetailsView: View {
@Environment(\.resetDefault) var showOnBoarding
// .. other code
Button(action: {
self.showOnBoarding.wrappedValue.toggle()
}) {
Image(systemName: "xmark.circle.fill")
Text("Close")
}