置顶
菜鸟入门,各位大佬轻喷,如有谬误之处欢迎讨论建议,也欢迎各位道友与我同行
"不积跬步,无以至千里;不积小流,无以成江海"
继续
上文中已经实现登陆后将登陆信息 ( 名称、是否已经登陆 )的缓存,在todo页面中显示用户名
并且使这个登陆状态在退出APP后再打开可以保持
本文将继续实现退出登陆功能
即在设置界面中有一个退出按钮,点击后将弹出登陆弹框
并且退出app后登陆状态也同步消失,效果如下:
iShot_2022-11-18_22.21.17.gif实现
与前文同理,设置页面也应该是一个独立的页面
前文已知 @AppStorage
变量的值会同步更新,并且更新视图
那我们可以直接在 SettingView.swift
页面中修改 isLogin
的值,它会响应到 IndexView.swift
页面中
// SettingView.swift
import SwiftUI
struct SettingView: View {
@AppStorage("isLogin") private var isLogin:Bool = false;
@AppStorage("userName") private var userName:String = "";
var body:some View{
VStack{
Text(userName).font(.title)
Spacer()
Button("退出登陆"){
// 直接修改 isLogin 其他用到这个值的页面也会同步更改
// 类似于vue中的vuex全局状态
isLogin = false;
// 退出登陆后将用户名置空
userName = "";
}
Spacer()
}
}
}
struct SettingView_Previews: PreviewProvider {
static var previews: some View {
SettingView()
}
}
那么接下来在 IndexView.swift
中对 isLogin
的变化进行响应
由于是否显示需要登录的 Alert
是一个 $showAlert
即 Binding
类型
func alert(isPresented: Binding<Bool>, content: () -> Alert) -> some View
因此,我们需要构造一个 Binding
类型的变量,其 get
方法是 isLogin 的取反
如下 :
import SwiftUI
struct IndexView: View{
// 是否已经登陆
@AppStorage("isLogin") private var isLogin:Bool = false;
// 显示提示登陆
@State private var showAlertOrigin:Bool = true;
// 显示登陆表单
@State private var showLogin:Bool = false;
@AppStorage("tabIndex") private var tabIndex:Int = 0;
var body: some View{
// 构造一个 Binding 类型的变量
let showAlert = Binding<Bool>(get:{
// get 方法直接返回 ! isLogin
// 这样在 isLogin 变化的时候,这个变量会跟着变化
return !self.isLogin;
}, set: {
showAlertOrigin = $0
})
VStack{
// ... 省略
}
// 绑定这个 Binding
.alert(isPresented: showAlert){
// ... 省略
}
}
总结
-
@AppStorage
比较类似于vue
中vuex+localstorage
的逻辑 - 自行构造 Binding,类似于在
vue
中watch
变量执行操作 - 由于类型的限定,普通的
@State
或其他 ( 非Binding
类型 )不能用到isPresented
属性中,所以要自行构造 - 当然,如果类比
Vue
,那么这应该是组件传值的内容,除了以状态传递,应该也会有其他的方式,后续继续研究
网友评论