前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SwiftUI监听ViewModel变化

SwiftUI监听ViewModel变化

作者头像
YungFan
发布2024-03-10 08:04:39
970
发布2024-03-10 08:04:39
举报
文章被收录于专栏:学海无涯学海无涯

SwiftUI 中 ViewModel 的变化会引起 UI 的变化,如何能做到监听 ViewModel?常见的有如下几种方式。

@Published属性

代码语言:javascript
复制
class ContentViewModel: ObservableObject {
    @Published var changingColor = Color.blue

    init() {
        Timer.scheduledTimer(
            withTimeInterval: 1.0,
            repeats: true,
            block: { _ in
                self.changingColor = self.randomColor()
            }
        )
    }

    private func randomColor() -> Color {
        return Color(red: Double.random(in: 0.0 ... 1.0),
                     green: Double.random(in: 0.0 ... 1.0),
                     blue: Double.random(in: 0.0 ... 1.0))
    }
}

struct ContentView: View {
    @StateObject var viewModel = ContentViewModel()

    var body: some View {
        RoundedRectangle(cornerRadius: 20.0)
            .frame(width: 100, height: 100)
            .foregroundColor(viewModel.changingColor)
    }
}

onchange Modifier

代码语言:javascript
复制
class ContentViewModel: ObservableObject {
    @Published var changingColor = Color.blue

    init() {
        Timer.scheduledTimer(
            withTimeInterval: 1.0,
            repeats: true,
            block: { _ in
                self.changingColor = self.randomColor()
            }
        )
    }

    private func randomColor() -> Color {
        return Color(red: Double.random(in: 0.0 ... 1.0),
                     green: Double.random(in: 0.0 ... 1.0),
                     blue: Double.random(in: 0.0 ... 1.0))
    }
}

struct ContentView: View {
    @StateObject var viewModel = ContentViewModel()
    @State private var degrees = 0.0

    var body: some View {
        RoundedRectangle(cornerRadius: 20.0)
            .frame(width: 100, height: 100)
            .foregroundColor(viewModel.changingColor)
            .rotationEffect(Angle.degrees(degrees))
            .onChange(of: viewModel.changingColor, perform: { value in
                degrees += 15
            })
    }
}

task Modifier

代码语言:javascript
复制
class ContentViewModel: ObservableObject {
    @Published var changingColor = Color.blue
    @Published var number = 0

    init() {
        Timer.scheduledTimer(
            withTimeInterval: 1.0,
            repeats: true,
            block: { _ in
                self.number = Int.random(in: 0 ... Int.max)
            }
        )
    }

    private func randomColor() -> Color {
        return Color(red: Double.random(in: 0.0 ... 1.0),
                     green: Double.random(in: 0.0 ... 1.0),
                     blue: Double.random(in: 0.0 ... 1.0))
    }

    @MainActor
    func randomColor() async {
        changingColor = Color(red: Double.random(in: 0.0 ... 1.0),
                              green: Double.random(in: 0.0 ... 1.0),
                              blue: Double.random(in: 0.0 ... 1.0))
    }
}

struct ContentView: View {
    @StateObject var viewModel = ContentViewModel()
    @State private var degrees = 0.0

    var body: some View {
        RoundedRectangle(cornerRadius: 20.0)
            .frame(width: 100, height: 100)
            .foregroundColor(viewModel.changingColor)
            .rotationEffect(Angle.degrees(degrees))
            .onChange(of: viewModel.changingColor, perform: { _ in
                degrees += 15
            })
            .task(id: viewModel.number) {
                await viewModel.randomColor()
            }
    }
}

Notification

代码语言:javascript
复制
class DataService {
    static let notificationName = "CHANGE_SIZE"
    static let sharedInstance = DataService()

    private init() { }

    func startService() {
        // 不停发通知
        Timer.scheduledTimer(
            withTimeInterval: 2.0,
            repeats: true, block: { _ in
                NotificationCenter.default.post(
                    name: Notification.Name(
                        rawValue: DataService.notificationName),
                    object: nil)
            })
    }
}

class ContentViewModel: ObservableObject {
    @Published var changingColor = Color.blue
    @Published var isLargeSize = true
    private var changeSizeMessageObserver: NSObjectProtocol?

    init() {
        Timer.scheduledTimer(withTimeInterval: 1.0,
                             repeats: true, block: { _ in
                                 self.changingColor = self.randomColor()
                             })
        // 收到通知
        changeSizeMessageObserver =
            NotificationCenter.default.addObserver(
                forName: Notification.Name(
                    rawValue: DataService.notificationName),
                object: nil,
                queue: nil) { _ in
                withAnimation {
                    self.isLargeSize.toggle()
                }
            }
    }

    deinit {
        // 移除通知
        if let obs = changeSizeMessageObserver {
            NotificationCenter.default.removeObserver(obs)
        }
    }

    private func randomColor() -> Color {
        return Color(red: Double.random(in: 0.0 ... 1.0),
                     green: Double.random(in: 0.0 ... 1.0),
                     blue: Double.random(in: 0.0 ... 1.0))
    }
}

struct ContentView: View {
    @StateObject var viewModel = ContentViewModel()

    var body: some View {
        RoundedRectangle(cornerRadius: viewModel.isLargeSize ? 40 : 100)
            .foregroundColor(viewModel.changingColor)
            .frame(width: 200,
                   height: 200)
            .onAppear(perform: {
                DataService.sharedInstance.startService()
            })
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-03-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • @Published属性
  • onchange Modifier
  • task Modifier
  • Notification
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档