为有牺牲多壮志,敢教日月换新天。

[Swift UI]二、实用控件-(11)如何通过定时器实现环形进度条的定时隐藏

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(let_us_code)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址: https:////www.cnblogs.com/strengthen/p/12293381.html
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

在第二章第十篇的文章中,通过定时器实现环形进度条的定时隐藏,

本文借助ObservableObject可观察对象,实现环形进度条的定时隐藏。

【SceneDelegate.swift】

 1 func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
 2         // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
 3         // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
 4         // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
 5 
 6         // Use a UIHostingController as window root view controller
 7         if let windowScene = scene as? UIWindowScene {
 8             let window = UIWindow(windowScene: windowScene)
 9             //修改此处的代码,同样给ContentView实例传递环境对象。
10             //这样就可以在模拟器或真机上运行项目时,使用可观察对象。
11             //初始化
12             let model = Store()
13             //设置激活属性的值
14             model.isActive = true
15             //然后将可观察对象作为环境对象,传递给ContentView的实例。
16             window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(model))
17             self.window = window
18             window.makeKeyAndVisible()
19         }
20     }

【ContentView.swift】

 1 import SwiftUI
 2 import UIKit
 3 //首先导入需要用到的框架。
 4 import Combine
 5 
 6 //定义一个类,该类遵循可观察对象协议,
 7 //可观察对象和@State标记非常相似,
 8 //区别是ObservableObject是用来修饰一个对象的。
 9 class Store : ObservableObject
10 {
11     //@Published属性包装器经常和ObservableObject配合使用,
12     //运行可观察对象的属性被监视,
13     //从而起到和@State类似的作用。
14     @Published var isActive = false
15     //AnyCancellable是可擦除类型的可取消对象,该对象在被取消时执行提供的闭包。
16     //在此将使用该属性,对环形进度条进行定时隐藏。
17     var cancelableSubscriber: AnyCancellable? = nil
18     
19     //添加一个初始化方法,对实例的属性进行初始化。
20     init()
21     {
22         cancelableSubscriber = $isActive
23             //在3秒钟的时间间隔内。发布由位于主线程的上游发布者,所发布的最新元素或第一个元素。
24             //简单点说,就是停留3秒钟之后,执行后面的动作。
25             .throttle(for: 3, scheduler: RunLoop.main, latest: true)
26             //使用提供的闭包,转换上游发布者的所有元素,
27             //就是说在3秒钟之后,发布内容为false的信息。
28             .map{val in false}
29             //最后将由map处理后的false信息,发布给self的isActive属性,
30             //从而修改该属性的值为false,以隐藏环形进度条。
31             .assign(to:\.isActive, on:self)
32     }
33 }
34 
35 struct ContentView : View
36 {
37     @EnvironmentObject var store : Store
38     
39     var body: some View
40     {
41         LoadingView(isActive: $store.isActive)
42     }
43 }
44 
45 struct ActivityIndicator: UIViewRepresentable
46 {
47     @Binding var isActive: Bool
48     func makeUIView(context: UIViewRepresentableContext<ActivityIndicator>) -> UIActivityIndicatorView
49     {
50         return UIActivityIndicatorView(style: UIActivityIndicatorView.Style.large)
51     }
52     
53     func updateUIView(_ uiView: UIActivityIndicatorView, context: UIViewRepresentableContext<ActivityIndicator>)
54     {
55         isActive ? uiView.startAnimating() : uiView.stopAnimating()
56     }
57 }
58 
59 struct LoadingView: View
60 {
61     @Binding var isActive: Bool
62     
63     var body: some View
64     {
65         ZStack
66             {
67                 VStack
68                     {
69                         Text("Waiting...")
70                         
71                         ActivityIndicator(isActive: self.$isActive)
72                 }
73                 .frame(width: UIScreen.main.bounds.width / 2,
74                        height: UIScreen.main.bounds.height / 5)
75                     .background(Color.orange)
76                     .cornerRadius(20)
77                     .foregroundColor(Color.primary)
78                     .opacity(self.isActive ? 1 : 0)
79         }
80     }
81 }
82 
83 #if DEBUG
84 struct ContentView_Previews : PreviewProvider
85 {
86     static var previews: some View
87     {
88         //为里能够在预览窗口使用可观察对象,
89         //我们需要在PreviewProvider里,对可观察对象进行初始化。
90         let model = Store()
91         model.isActive = true
92         //然后将可观察对象作为环境对象,传递给ContentView的实例。
93         //关于环境对象的使用,将在第六章进行更细致的讲解
94         return ContentView().environmentObject(model)
95     }
96 }
97 #endif

 

posted @ 2020-02-10 23:14  为敢技术  阅读(267)  评论(0编辑  收藏  举报