美文网首页
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