第八章 封装MVVM|onTapGesture|AppStorage

对于服务器选择这一控件,我们希望当没有默认的服务器地址的时候,我们提示 【请选择服务器地址】,当选择服务器地址就将选择的服务器地址保存在 UserDefault 中。

因为 ServerSelectMenuView 是登陆界面的一部分,我们希望将 SwiftUI 和 MVVM 相结合。那么

ServerSelectMenuView 所有的变量都要从 LoginPage 的 ViewModel 中获取。

我们在 Define 文件夹的同级创建一个 Common 的文件夹,存放我们的 BaseViewModel.swift。

swift 复制代码
class BaseViewModel: ObservableObject {    
}

我们目前先暂时还不需要进行封装,我们暂时创建方便后续进行扩展。

我们在 LoginPage 文件夹中新建一个 ViewModel 文件夹,创建 LoginPageViewModel.swift。

swift 复制代码
class LoginPageViewModel: BaseViewModel {    
}

为了让 ServerSelectMenuView 及时的展示我们选择的服务器地址, 我们新增一个变量。

swift 复制代码
/// 当前 App 的服务器地址
@Published var currentAppServer:String = ""

为了让 ServerSelectMenuView 所在 LoginPage 的 ViewModel, 我们采用 @EnvironmentObject 进行注入。

swift 复制代码
@StateObject private var viewModel:LoginPageViewModel = LoginPageViewModel()

在 ServerSelectMenuView 视图中,我们新建一个 Get 方法获取当前显示服务器地址。

swift 复制代码
private var serverTitle:String {
    guard !viewModel.currentAppServer.isEmpty else {
        return "请选择服务器地址"
    }
    return viewModel.currentAppServer
}

我们将 CenterView的代码更改一下

swift 复制代码
private var centerView:some View {
    Text(serverTitle)
      .frame(maxWidth:.infinity,
             alignment: .leading)
      .lineLimit(1)
      .foregroundColor(Color(uiColor: appColor.c_cccccc))
}

这样当 currentAppServer 发生改变的时候,我们的界面 UI 对应也会发生更新。

使用 onTapGesture 实现点击方法

为了验证,我们对于 ServerSelectMenuView 新增一个点击方法,点击的时候让 AppServer 的值更改为 xiaozhuanlan.com/u/junshang

swift 复制代码
LoginValueContentView(left: leftView,
                      center: centerView,
                      right: rightView)
    .onTapGesture {
        viewModel.currentAppServer = "https://xiaozhuanlan.com/u/junshang"
    }

点击之后,我们的界面果然发生了更新,诚不欺我。

使用 @AppStorage 将本地缓存值实时更新

我现在有一个需求,我不希望用户每次进来都要重新选择服务器,那么就需要将刚才更新的服务器地址保存在本地。

对于 SwiftUI 中,将对应值更新到本地可以用到 @AppStorage 这个属性包装器。

我们将LoginPageViewModel的 currentAppServer 的属性如下

swift 复制代码
/// 当前 App 的服务器地址
@AppStorage("currentAppServer")
var currentAppServer:String = ""

我们运行一下看看效果,发现效果依然存在。我们会有些奇怪,那么 @AppStorage 岂不是 和 @Published 一样效果,完全多余呀。

非也非也!你可以再次运行看看,我惊呼一声,卧槽!

运行之后服务器展示已经展示上次运行选中的服务器地址,就问这功能厉不厉害!

相关推荐
传奇开心果编程2 天前
【SwiftUI提高练中学】第9课 安全与隐私
swiftui·移动开发·swift·编程语言理论·开发范式·编程框架·声明式ui
传奇开心果编程3 天前
【声明式UI开发实用技术学与练】第8课 状态提升与下放
学习·flutter·react native·ui·swiftui·composer
东坡肘子3 天前
Swift Server,又多了一个 Google -- 肘子的 Swift 周报 #156
人工智能·swiftui·swift
传奇开心果编程4 天前
【现代声明式UI学与练】第4课 列表渲染与 key——如何高效渲染列表、key 的作用、列表重排时的状态保持
学习·flutter·react native·ui·swiftui·android jetpack
传奇开心果编程4 天前
【SwiftUI提高练中学】第8课 网络层架构:拦截器、重试、缓存与离线优先
学习·macos·ui·ios·swiftui
传奇开心果编程4 天前
【现代声明式UI学与练】第7课 组件通信——父传子、子传父、跨层级通信、状态提升与 Context
学习·flutter·react native·ui·swiftui·android jetpack
tink5 天前
告别 Xcode IDE:用 VS Code + SweetPad + XcodeGen 开发 iOS 应用的完整指南
ios·swiftui·xcode
传奇开心果编程5 天前
【现代声明式UI学与练】第9课 性能优化——渲染优化、列表优化、内存优化、启动优化
学习·flutter·react native·ui·性能优化·swiftui·android jetpack
传奇开心果编程8 天前
【现代声明式UI学与练】第1课 从命令式UI到声明式UI
学习·flutter·ui·swiftui·react·android jetpack
传奇开心果编程8 天前
【SwiftUI提高练中学】第13课 实时活动与灵动岛:ActivityKit 实战
学习·ui·ios·swiftui·swift