gpt4 book ai didi

SwiftUI onTapGesture 不适用于 Mac 应用程序中的 ObservedObject

转载 作者:行者123 更新时间:2023-11-28 13:30:57 35 4
gpt4 key购买 nike

我想根据来自另一个 View (LeftView) 中点击手势的操作来更新 View (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 对象,因此它们不会观察到相同的状态。

在您的两个 View 中,将 @ObservedObject 保留为未初始化的属性:

LeftView.swift & RightView.swift

@ObservedObject var appState: AppState

当您在 SwiftUI View 中有这样一个未初始化的属性时,您需要在任何时候想要使用该 View 时为其提供一个值。

PreviewProvider 使用您的 View 实例,因此 Xcode 可以在 Canvas 上向您显示它,它只需要您为 提供一个占位符值应用状态。该值并不是很重要(除了 Xcode Canvas 外,它没有在任何地方使用)所以您只需要提供正确类型的东西:

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

最后,在 ContentView 中,您需要将对单个 shared 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)
}
}

现在两个 View 都在观察 AppState 的同一个实例,当它的属性发生变化时它们都会更新。

您还可以使用 @EnvironmentObject 在您应用中的所有 View 之间共享状态,但由于我们在这里只关心两个 View @ObservedObject 是一个务实的选择。

关于SwiftUI onTapGesture 不适用于 Mac 应用程序中的 ObservedObject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57348113/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com