美文网首页
SwiftUI全攻略——2.数据流和修饰符

SwiftUI全攻略——2.数据流和修饰符

作者: Sunooo | 来源:发表于2020-09-20 11:43 被阅读0次

1. @Binding and @State

@Binding SwiftUI中的View都是结构体,在Swift中,结构体都是值传递,使用@Binding修饰的属性会变成引用传递,一般用于连接两边的View,传递数据。
@State 也是用来修饰属性,当@State修饰的属性值改变的时候,View层也会自动变化,我们称之为响应式编程,数据视图双向绑定。


struct PlayerView: View {
    var episode: Episode
    @State private var isPlaying: Bool = false

    var body: some View {
        VStack {
            Text(episode.title)
                .font(.title)
            if isPlaying {
                Text(episode.description)
                    .font(.body)
            }
            PlayButton(isPlaying: $isPlaying)
        }
        .padding()
    }
}

struct PlayerView_Previews: PreviewProvider {
    static var previews: some View {
        PlayerView(episode: Episode.data())
            
    }
}

struct PlayButton: View {
    @Binding var isPlaying: Bool

    var body: some View {
        Button(action: {
            self.isPlaying.toggle()
        }) {
            Image(systemName: isPlaying ? "pause.circle" : "play.circle")
        }
    }
}

struct PlayButton_Previews: PreviewProvider {
    @State static private var isPlaying = false
    static var previews: some View {
        PlayButton(isPlaying: $isPlaying)
    }
}

PlayerViewisPlaying@State修饰,之后传递给子View PlayButton,在PlayButton中使用@Binding修饰的isPlaying接收到了传递过来的数据,在内部修改,可以直接更新父View。
自此就实现了数据和View的双向绑定,更多细节可以参考Combine框架,MVVM设计思想,RxSwfit设计思想。

2. @State or @ObservedObject ?

首先使用场景不同,
@State一般声明为private,只用于当前View。
@ObservedObject 适用于由外部向View内传递数据,在MVVM架构中ViewModel要用@ObservedObject修饰
其次修饰的数据类型不同,
@State无法修饰Class类型的数据,一般就修饰Struct Bool String
@ObservedObject必须修饰Class类型的数据,Class也要遵守ObservableObject协议。内部需要观察的属性也需要添加@Published 修饰符,这样被标记的属性更新,才会通知到View

struct PlayerView: View {
    var episode: Episode
    @ObservedObject var user: User
    
    @State private var isPlaying: Bool = false

    var body: some View {
        VStack {
            
            Text(episode.title)
                .font(.title)
            if isPlaying {
                Text(episode.description)
                    .font(.body)
            }
            
            PlayButton(isPlaying: $isPlaying, user: user)

        }
        .padding()
    }
}

struct PlayerView_Previews: PreviewProvider {
    static var previews: some View {
        PlayerView(episode: Episode.data(), user: User(name: "", age: 0, score: 0))
    }
}

import Combine

final class User: ObservableObject {
    var name: String = ""
    var age: Int = 0
    @Published var score: Int = 0
    init(name: String, age: Int, score: Int) {
        self.name = name
        self.age = age
        self.score = score
    }
    
    init() {
    }
}

github仓库地址 https://github.com/SunZhiC/LearningSwiftUI

References

Introducing SwiftUI: Building Your First App
@State vs @ObservableObject - which and when?

相关文章

网友评论

      本文标题:SwiftUI全攻略——2.数据流和修饰符

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