网站首页 > 开源技术 正文
置顶
菜鸟入门,各位大佬轻喷,如有谬误之处欢迎讨论建议,也欢迎各位道友与我同行
“不积跬步,无以至千里;不积小流,无以成江海”
继续
上文中我们引入了第三方库 Popup,所以本文我们来讨论 Popup 的封装,实现一个 全局Toast 的功能
效果如下:
在这里插入图片描述
期望的调用方式如下:
showToast("测试");
hideToast();
思考
按照上文的调用方式描述,很显然我们不希望这几个方法被定义在本身的视图上,一定是在另一个文件中定义好,这里可以直接使用
所以我们将会用到 extension
同样的我们也不希望这个封装会大量地放到某一个视图中去,最好是直接在封装的地方就能做完,同时在原来的页面视图中只需要进行调用即可,最好是直接在初始化的时候用一次即可。
所以我们将会用到 ViewModifier
结合之前我们用到的 @AppStorage ,完全可以实现一个全局的 Toast
实现
我们新增一个文件:Toast.swift 用来存放所有的对 Toast 的封装,内容如下:
import SwiftUI
import ExytePopupView
/// extension 顾名思义即扩展
/// extension 可以给指定的对象、类型、struct、protocol 等扩展 func,不用再在具体的结构里面显式声明方法
/// 很好的一个横向解耦方式,很像PHP中的 Trait
/// 假如以后有相同方法的两个view,我们完全可以抽象到一起
extension View{
// 初始化启动Toast 返回一个 some View
public func enableToast() -> some View{
@AppStorage("showGlobalToast") var showGlboalToast:Bool = false;
@AppStorage("globalToastText") var globalToastText:String = "";
// 这里将全局变量重置,以避免正好在显示Toast的时候退出了app
// 导致下次打开app的时候就有一个 Toast
showGlboalToast = false
globalToastText = ""
// 这里调用了一个view modifier
return self.modifier(initToast())
}
// 显示一个Toast,传入内容
public func showToast(content:String){
@AppStorage("showGlobalToast") var showGlboalToast:Bool = false;
@AppStorage("globalToastText") var globalToastText:String = "";
// 修改全局变量
showGlboalToast = true;
globalToastText = content;
}
}
/// view modifier 相当于在外面修改某个视图的结构
/// body方法中提供了一个content就是调用你的那个视图
/// 你也可以理解为这是在跳转页面,但是把原始页面的实例给你了
struct initToast:ViewModifier{
@AppStorage("showGlobalToast") var showGlboalToast:Bool = false;
@AppStorage("globalToastText") var globalToastText:String = "";
public func body(content: Content) -> some View {
// 直接给 content 调用popup
content.popup(isPresented: $showGlboalToast, type:.default, position: .bottom, animation: .easeOut(duration: 0), autohideIn: 2, dragToDismiss: false,closeOnTap: false,closeOnTapOutside: true,backgroundColor: .clear
){
Text(globalToastText)
.frame(width: 150, height: 80)
.background(.gray)
.foregroundColor(.white)
.cornerRadius(20.0)
}
}
}
整个的封装过程就结束
接下来就是调用部分
修改 helloworldApp.swift ,即你的 APP入口文件
import SwiftUI
@main
struct helloworldApp: App {
var body: some Scene {
WindowGroup {
IndexView()
// 调用封装中扩展的方法即可
.enableToast()
}
}
}
在新增 todo 的按钮上进行调用
Button("添加"){
// 这里可以直接调用 showToast()
showToast(content: "添加成功")
todos.add(name: newItem)
newItem = ""
}
因为我们是对 View 进行的扩展,所以,所有的页面和视图都可以调用这些方法
以上,我们实现了一个全局的 Toast
踩坑
我曾经思考过,封装一个方法在 View 上,可以用以下方式调用
self.body.showToast("asdfasdf")
这样我就可以省略入口文件的那个启用方法 enableToast()
但是实际上并不会成功,中途倒是没报几个错,但是 toast 的效果一直都没出来
.popup 一定要写在视图定义的后面,而不能在中途的方法调用中动态的执行
也许这就是所谓的 强类型 + 声明式视图?
总结
- extension 是扩展方法,就说所有的结构都能扩展,包括基础数据类型,用法与 js 中的 prototype比较类似
- ViewModifier 是对视图的修改,你可以拿到视图本身,添加方法调用,也可以再加一些其他的元素进去,可以理解为拿得到上个页面视图的页面的跳转
- 全局 Loading 可以参照上面的实现,无非就是在文字上面加一个 Loading 的 gif 动图,本文不再赘述。
- 包括一些全局的 prompt 、confirm框等,也可以参照以上实现
- 貌似 popup 这个库引入得比较多余,我直接在 modifier 里面加一个框框在中间,使用 ZStack 这个框框显示在原始视图的上面不就完事儿了?但是怎么消除Toast是个问题,或许SwiftUI自己处理了这些不显示的视图?这个后续再继续讨论。。。
欢迎关注微信公众号【思跃喵】,一起探讨。
猜你喜欢
- 2024-09-19 一篇文章带你了解Telerik UI for WPF中热门的深色主题
- 2024-09-19 【2.UI元素】6.Scrollbar and Scroll View
- 2024-09-19 Graphics View绘图架构:构建交互式和可扩展的绘图应用
- 2024-09-19 Web View 结合 MAUI Blazor:实现 Web 与 WPF 的双边互补,附带案例
- 2024-09-19 揭秘Graphics View绘图架构设计方案:从基本概念到实际应用
- 2024-09-19 iOS-启动项目(一)设置 rootViewController
- 2024-09-19 三星 One UI 3.1更新,Galaxy S21系列同步升级
- 2024-09-19 UIActivityViewController属性和使用?
- 2024-09-19 iOS开发——使用UICollectionView实现一个列表头部拉伸效果的案例
- 2024-09-19 android-如何在子线程中更新ui(android子线程崩溃导致进程崩溃)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- jdk (81)
- putty (66)
- rufus (78)
- 内网穿透 (89)
- okhttp (70)
- powertoys (74)
- windowsterminal (81)
- netcat (65)
- ghostscript (65)
- veracrypt (65)
- asp.netcore (70)
- wrk (67)
- aspose.words (80)
- itk (80)
- ajaxfileupload.js (66)
- sqlhelper (67)
- express.js (67)
- phpmailer (67)
- xjar (70)
- redisclient (78)
- wakeonlan (66)
- tinygo (85)
- startbbs (72)
- webftp (82)
- vsvim (79)
本文暂时没有评论,来添加一个吧(●'◡'●)