美文网首页iOS 开发_...
SwiftUI 关键词解析

SwiftUI 关键词解析

作者: 猿姑凉 | 来源:发表于2020-08-12 14:50 被阅读0次

    1、guard 控制流语句

    guard类似于if-else、switch

    func submit() {
        guard let name = nameField.text else {
            show("No name to submit")
            return
        }
    
        guard let address = addressField.text else {
            show("No address to submit")
            return
        }
    
        guard let phone = phoneField.text else {
            show("No phone to submit")
            return
        }
    
        sendToServer(name, address: address, phone: phone)
    }
    

    2、as! as?

    2.1 ? 自动解析

    var myString:String? = nil  值可以为nil
    

    2-2 !强制解析

    var myString:String! = "数值" 表示会一定有值
    

    2-3 as :用在有保证的转换,从派生类->基类 (向上转换)

    as? (optional可选类型 意思是可有可无) 无的话会返回一个 nil 对象。有的话返回可选类型值(optional)

    var dic  = [String:Any]()
    dic["title"] = "内容"
    let str = dic["title"] as? String
    //  print(str) //Optional("我是title")
    let str0 = dic["icon"] as? String
    print(str0) // nil dict里面没有icon字段
    
    1.开发中 用的最多的就是as?关键字,但是要进行非空判断 if let ,guard 保证程序正常进行下去
    2.其次as! 如果用as!的话,一定要保证有值
    3.然后as(这个关键字一般都是系统智能提示要用这个)
    4.开发中要是接收后台返回的字段建议最好用可选类型  as? 后台的情况千变万化 尽量不适用as! 进行接收
    
    

    3、@State

    通过使用 @State 修饰器我们可以关联出 View 的状态. SwiftUI 将会把使用过 @State 修饰器的属性存储到一个特殊的内存区域,并且这个区域和 View struct 是隔离的. 当 @State 装饰过的属性发生了变化,SwiftUI 会根据新的属性值重新创建视图

    struct ButtonView: View {
        @State private var showFavorited: Bool = false
    
        var body: some View {
            Button(action: {
                self.showFavorited.toggle()
            }) {
                Text("Change filter")
            }
        }
    }
    

    4、@ Binding

    把一个视图的属性传至子节点中,但是又不能直接的传递给子节点,因为在 Swift 中值的传递形式是值类型传递方式,也就是传递给子节点的是一个拷贝过的值。但是通过 @Binding 修饰器修饰后,属性变成了一个引用类型,传递变成了引用传递,这样父子视图的状态就能关联起来了。

    struct FilterView: View {
        @Binding var showFavorited: Bool
        var body: some View {
            Toggle(isOn: $showFavorited) {
                Text("Change filter")
            }
        }
    }
    
    struct ProductsView: View {
        let products: [Product]
        @State private var showFavorited: Bool = false
        var body: some View {
            List {
                FilterView(showFavorited: $showFavorited)
                ForEach(products) { product in
                    if !self.showFavorited || product.isFavorited {
                        Text(product.title)
                    }
                }
            }
        }
    }
    在 FilterView 视图里,Toggle 组件的创建也使用 $showFavorited 这种格式,因为 Toggle 组件会修改传入的值,如果是一个纯读的组件比如 Text 就不需要 使用 $showFavorited, 直接 Text(showFavorited) 使用
    

    在 FilterView 视图里用 @Binding 修饰 showFavorited 属性, 在传递属性是使用 $ 来传递 showFavorited 属性的引用,这样 FilterView 视图就能读写父视图 ProductsView 里的状态值了,并且值发生了修改 SwiftUI 会更新 ProductsView 和 FilterView 视图

    5、@ ObservedObject

    @ObservedObject 的用处和 @State 非常相似,从名字看来它是来修饰一个对象的,这个对象可以给多个独立的 View 使用。如果你用 @ObservedObject 来修饰一个对象,那么那个对象必须要实现 ObservableObject 协议,然后用 @Published 修饰对象里属性,表示这个属性是需要被 SwiftUI 监听的

    final class PodcastPlayer: ObservableObject {
        @Published private(set) var isPlaying: Bool = false
    
        func play() {
            isPlaying = true
        }
    
        func pause() {
            isPlaying = false
        }
    }
    

    定义了一个 PodcastPlayer 类,这个类可以给不同的 View 使用,SwiftUI 会追踪使用 View 里经过 @ObservableObject 修饰过的对象里进过 @Published 修饰的属性变换,一旦发生了变换,SwiftUI 会更新相关联的 UI

    struct EpisodesView: View {
        @ObservedObject var player: PodcastPlayer
        let episodes: [Episode]
    
        var body: some View {
            List {
                Button(action: {
                    if self.player.isPlaying {
                        self.player.pause()
                    } else {
                        self.player.play()
                    }
                }) {
                    Text(player.isPlaying ? "Pause" : "Play")
                }
    
                ForEach(episodes) { episode in
                    Text(episode.title)
                }
            }
        }
    }
    

    6、@ EnvironmentObject

    这个修饰器是针对全局环境的。通过它,我们可以避免在初始 View 时创建 ObservableObject, 而是从环境中获取 ObservableObject

    1.SceneDelegate.swift 文件
    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
        var window: UIWindow?
    
        func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            let window = UIWindow(frame: UIScreen.main.bounds)
            let episodes = [
                Episode(id: 1, title: "First episode"),
                Episode(id: 2, title: "Second episode")
            ]
    
            let player = PodcastPlayer()
            window.rootViewController = UIHostingController(
                rootView: EpisodesView(episodes: episodes)
                    .environmentObject(player)
            )
            self.window = window
            window.makeKeyAndVisible()
        }
    }
    
    2.EpisodesView.swift 文件
    struct EpisodesView: View {
        @EnvironmentObject var player: PodcastPlayer
        let episodes: [Episode]
    
        var body: some View {
            List {
                Button(
                    action: {
                        if self.player.isPlaying {
                            self.player.pause()
                        } else {
                            self.player.play()
                        }
                    }) {
                    Text(player.isPlaying ? "Pause" : "Play")
                }
    
                ForEach(episodes) { episode in
                    Text(episode.title)
                }
            }
        }
    }
    

    我们获取 PodcastPlayer 这个 ObservableObject 是通过 @EnvironmentObject 修饰器,但是在入口需要传入 .environmentObject(player) 。@EnvironmentObject 的工作方式是在 Environment 查找 PodcastPlayer 实例。

    7、@ Environment

    继续上面一段的说明,我们的确开一个从 Environment 拿到用户自定义的 object,但是 SwiftUI 本身就有很多系统级别的设定,我们开一个通过 @Environment 来获取到它们

    struct CalendarView: View {
        @Environment(\.calendar) var calendar: Calendar
        @Environment(\.locale) var locale: Locale
        @Environment(\.colorScheme) var colorScheme: ColorScheme
    //模态跳转
        @Environment(\.presentationMode) var presentationMode
    
        var body: some View {
            return Text(locale.identifier)
        }
    }
    

    通过 @Environment 修饰的属性,我们开一个监听系统级别信息的变换,这个例子里一旦 Calendar, Locale, ColorScheme 发生了变换,我们定义的 CalendarView 就会刷新

    相关文章

      网友评论

        本文标题:SwiftUI 关键词解析

        本文链接:https://www.haomeiwen.com/subject/hrqzrktx.html