继续

续接上篇文章,我们在一个简单的登陆界面中实现了表单提示,然后再自动聚焦到输入框中。

那么按照正常的登陆流程,接下来我们应该是进行跳转,然后展示一个带有底部导航栏的的页面

最终的结果如下:

swiftui 点击tabview 返回 swiftui button页面跳转_swift

重新整理逻辑

按照原定计划,我现在要做的是一个todolist的小app

那么我们重新整理一下初次进入的交互逻辑

  1. 打开是首页
  2. 发现没有登陆
  3. 弹出提示框请登录,这个框只有一个按钮,名为去登录
  4. 点击后弹出一个登陆界面,即我们之前编写的那个
  5. 登陆完成后关闭自己即可,即返回首页

一个新的页面

我们新建一个文件 IndexView.swift

这个文件为首页,除了上述的首页的登陆判断逻辑以及弹出登陆表单之外

它应该具有一个底部的tabbar

既然作为首页,首先就要修改入口文件处的引用

将 helloworldApp.swift 文件中的 ContentView() 改为 IndexView()

IndexView.swift 内容如下:

import SwiftUI

// 假设这里是 todo list 的页面
struct TodoView:View{
    var body:some View{
        Text("这里是todo页面")
    }
}

// 假设这里是 设置的页面
struct SettingView:View{
    var body:some View{
        Text("这里是设置页面")
    }
}

struct IndexView: View{
    // 是否已经登陆
    @State private var isLogin:Bool = false;
    // 显示提示登陆
    @State private var showAlert:Bool = true;
    // 显示登陆表单
    @State private var showLogin:Bool = false;
    var body: some View{
        VStack{
            // 一个简单的tabview,底部导航栏
            TabView {
                TodoView()
                    .tabItem {
                        Image(systemName: "list.dash")
                        Text("TODO")
                    }
                SettingView()
                    .tabItem {
                        Image(systemName: "gear.circle")
                        Text("设置")
                    }
            }
            .font(.headline)
        }.alert(isPresented: $showAlert){
            // 提示登陆的Alert
            Alert(
                title: Text("提示"),
                message: isLogin ? Text("您已登录!") : Text("您尚未登陆,请登录!"),
                dismissButton: isLogin ? .default(Text("好的")):.destructive(Text("去登录")){
                    // 显示login表单
                    showLogin = true;
                }
            )
        }
        // .sheet 会弹出一个类似vue中模态框的东西
        //        .sheet(isPresented:$showLogin,onDismiss: {
        //            // 避免被手动下滑关闭
        //            showLogin = true;
        //        } ,content: {
        //            ContentView()
        //        })
        // 这种会直接弹出页面占据全屏
        .fullScreenCover(isPresented: $showLogin ,content: {
            ContentView()
        })
    }
}

struct IndexView_Previews: PreviewProvider {
    static var previews: some View {
        IndexView()
    }
}

以下将 .fullScreenCover 和 .sheet 两种形式的结果都展示出来

swiftui 点击tabview 返回 swiftui button页面跳转_swift_02


swiftui 点击tabview 返回 swiftui button页面跳转_swift_03

ContentView 中新增如下代码

struct ContentView: View {
	@Environment(\.presentationMode) var presentationMode;
	// ... 省略部分代码、
	if(res == "登陆成功" || res == "请输入。。。"){
		focus = .clear
		// 这里需要返回首页,登陆成功后销毁本页面
		self.presentationMode.wrappedValue.dismiss()
	}
}

总结

  1. 这里只涉及到了跳转的 sheet 和 fullscreencover 两种形式
  2. 还有navigationView 后续在其他功能中介绍
  3. 登陆的状态没有被传递,导致了一些问题
  4. 如果类比vue组件的话,这里应该有组件间传值才更合理