当我在其中一个视图上按下按钮时,我希望能够显示一个新视图。
从我看过的教程以及此处的其他回答的问题来看,似乎每个人都在导航视图中使用导航按钮,除非错误的导航视图是使我在应用顶部显示菜单栏右箭头的菜单我不要当我将导航按钮放入不是NavigationView的子视图时,它只是在UI上被禁用,因此我无法单击它,所以我想我不能使用它。
我看到的其他示例似乎使用了演示文稿链接/按钮,它们似乎显示了一种弹出视图。
我只是在寻找如何单击常规按钮并以全屏方式显示另一个视图,就像执行旧的处理方式一样。
答案 0 :(得分:4)
可能的解决方案
1。如果要在当前视图的顶部显示(例如,UIKit中的显示样式)
struct ContentView: View {
@State var showingDetail = false
var body: some View {
Button(action: {
self.showingDetail.toggle()
}) {
Text("Show Detail")
}.sheet(isPresented: $showingDetail) {
DetailView()
}
}
}
2。如果要重置当前窗口场景堆栈(例如:登录后显示主屏幕)
Button(action: goHome) {
HStack(alignment: .center) {
Spacer()
Text("Login").foregroundColor(Color.white).bold()
Spacer()
}
}
func goHome() {
if let window = UIApplication.shared.windows.first {
window.rootViewController = UIHostingController(rootView: HomeScreen())
window.makeKeyAndVisible()
}
}
3.push新视图(例如:list-> UIKit导航控制器的详细信息)
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: DetailView()) {
Text("Show Detail View")
}.navigationBarTitle("Navigation")
}
}
}
}
4。基于@state属性更新当前视图,(例如:登录失败时显示错误消息)
struct ContentView: View {
@State var error = true
var body: some View {
...
... //login email
.. //login password
if error {
Text("Failed to login")
}
}
}
答案 1 :(得分:1)
举个简单的例子,您可以使用以下内容
import SwiftUI
struct ExampleFlag : View {
@State var flag = true
var body: some View {
ZStack {
if flag {
ExampleView().tapAction {
self.flag.toggle()
}
} else {
OtherExampleView().tapAction {
self.flag.toggle()
}
}
}
}
}
struct ExampleView: View {
var body: some View {
Text("some text")
}
}
struct OtherExampleView: View {
var body: some View {
Text("other text")
}
}
但是如果您想以这种方式显示更多视图,则看起来很讨厌
您可以使用堆栈来控制视图状态,而无需使用NavigationView
例如:
class NavigationStack: BindableObject {
let didChange = PassthroughSubject<Void, Never>()
var list: [AuthState] = []
public func push(state: AuthState) {
list.append(state)
didChange.send()
}
public func pop() {
list.removeLast()
didChange.send()
}
}
enum AuthState {
case mainScreenState
case userNameScreen
case logginScreen
case emailScreen
case passwordScreen
}
struct NavigationRoot : View {
@EnvironmentObject var state: NavigationStack
@State private var aligment = Alignment.leading
fileprivate func CurrentView() -> some View {
switch state.list.last {
case .mainScreenState:
return AnyView(GalleryState())
case .none:
return AnyView(LoginScreen().environmentObject(state))
default:
return AnyView(AuthenticationView().environmentObject(state))
}
}
var body: some View {
GeometryReader { geometry in
self.CurrentView()
.background(Image("background")
.animation(.fluidSpring())
.edgesIgnoringSafeArea(.all)
.frame(width: geometry.size.width, height: geometry.size.height,
alignment: self.aligment))
.edgesIgnoringSafeArea(.all)
.onAppear {
withAnimation() {
switch self.state.list.last {
case .none:
self.aligment = Alignment.leading
case .passwordScreen:
self.aligment = Alignment.trailing
default:
self.aligment = Alignment.center
}
}
}
}
.background(Color.black)
}
}
struct ExampleOfAddingNewView: View {
@EnvironmentObject var state: NavigationStack
var body: some View {
VStack {
Button(action:{ self.state.push(state: .emailScreen) }){
Text("Tap me")
}
}
}
}
struct ExampleOfRemovingView: View {
@EnvironmentObject var state: NavigationStack
var body: some View {
VStack {
Button(action:{ self.state.pop() }){
Text("Tap me")
}
}
}
}
我认为这是一种糟糕的方式,但是SwiftUI中的导航要糟糕得多