簡體   English   中英

SwiftUI onTapGesture不適用於Mac app中的ObservedObject

[英]SwiftUI onTapGesture does not work with ObservedObject in Mac app

我想基於另一個視圖(LeftView)中輕擊手勢的操作來更新視圖(RightView)。 下面是我的示例代碼來完成此任務:

AppState.swift

import Foundation

class AppState: ObservableObject {
    @Published var tapCount: Int = 0

    func incrementTapCount() {
        self.tapCount += 1
        print("tap count \(self.tapCount)")
    }
}

LeftView.swift

import SwiftUI

struct LeftView: View {
    @ObservedObject var appState = AppState()

    var body: some View {
        VStack {
            Text("Left View")
        }
        .frame(width: 100, height: 200)
        .onTapGesture {
            print("tapped left view")
            self.appState.incrementTapCount()
        }
    }
}

RightView.swift

import SwiftUI

struct RightView: View {
    @ObservedObject var appState = AppState()

    var body: some View {
        VStack {
            Text("Right View")
            Text("Tap Count: \(self.appState.tapCount)")
        }.frame(width: 200, height: 200)
    }
}

ContentView.swift

import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack {
            LeftView()
            RightView()
        }.frame(width: 300, height: 200)
    }
}

不幸的是,RightView文本不會隨着點擊數更新。 但是,如果我在ObservableObject類中使用計時器來更新拍數,則RightView會正確更新。

import Foundation

class AppState: ObservableObject {
    @Published var tapCount: Int = 0

    init() {
        Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
            self.tapCount += 1
        }
    }

    func incrementTapCount() {
        self.tapCount += 1
        print("tap count \(self.tapCount)")
    }
}

為什么LeftView中的輕擊手勢不會更新RightView文本?

LeftViewRightView各自初始化各自的AppState對象,因此它們不會觀察相同的狀態。

在兩個視圖中,都將@ObservedObject保留為未初始化的屬性:

LeftView.swift和RightView.swift

@ObservedObject var appState: AppState

當您在SwiftUI視圖中具有未初始化的屬性時,您需要在每次使用該視圖時為其提供一個值。

PreviewProvider使用視圖的實例,因此Xcode可以在畫布上向您顯示該實例,並且只需要您為appState提供占位符值。 該值並不是很重要(除了Xcode畫布,它沒有在其他任何地方使用),因此您只需要提供正確類型的值即可:

#if DEBUG
struct LeftView_Previews: PreviewProvider {
    static var previews: some View {
        LeftView(appState: AppState())
    }
}
#endif

最后,在ContentView您需要將對單個共享 AppState的引用向下傳遞到LeftViewRightView以便它們可以觀察相同的對象:

ContentView.swift

import SwiftUI

struct ContentView: View {
    var sharedAppState = AppState()

    var body: some View {
        HStack {
            LeftView(appState: sharedAppState)
            RightView(appState: sharedAppState)
        }.frame(width: 300, height: 200)
    }
}

現在,兩個視圖都在觀察AppState的相同實例,它們都將在其屬性更改時更新。

您也可以使用@EnvironmentObject在應用程序中所有視圖之間共享狀態,但是由於這里我們只關注兩個視圖,因此@ObservedObject是一個務實的選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM