SwiftUI onTapGesture不适用于Mac app中的ObservedObject [英] SwiftUI onTapGesture does not work with ObservedObject in Mac app

查看:72
本文介绍了SwiftUI onTapGesture不适用于Mac app中的ObservedObject的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想基于另一个视图(LeftView)中轻击手势的操作来更新视图(RightView).下面是我的示例代码来完成此操作:

I would like to update a view (RightView) based on actions from a tap gesture in another view (LeftView). Below is my example code to accomplish this:

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会正确更新.

Unfortunately, the RightView text does not update with the tap count. However, if I use a timer in the ObservableObject class to update the tap count, then the RightView updates correctly.

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文本?

Why does the tap gesture in LeftView not update the RightView text?

推荐答案

LeftView RightView 都分别初始化了自己的单独的 AppState 对象,所以他们不会观察到相同的状态.

LeftView and RightView are each initializing their own separate AppState objects, so they aren't observing the same state.

在两个视图中,都将 @ObservedObject 保留为未初始化的属性:

In both of your views, leave the @ObservedObject as an uninitialized property:

LeftView.swift&RightView.swift

@ObservedObject var appState: AppState

在SwiftUI视图中具有未初始化的属性时,您需要在每次使用该视图时为其提供一个值.

When you have an uninitialized property like this in a SwiftUI view, you need to provide a value for it any time you want to use the view.

PreviewProvider 使用视图的实例,因此Xcode可以在画布上向您显示该视图,并且只需要您为提供一个 placeholder 值.appState .该值并不是很重要(除了Xcode画布,它没有在其他任何地方使用),因此您只需要提供正确类型的值即可:

The PreviewProvider uses an instance of your view so Xcode can show it to you on the canvas, and it only needs you to supply a placeholder value for appState. The value isn't really important (it isn't used anywhere but the Xcode canvas) so you just need to provide something of the correct type:

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

最后,在 ContentView 中,您需要将对单个 shared AppState 的引用传递到 LeftView RightView ,这样它们就可以观察相同的对象:

Finally in ContentView you'll want to pass a reference to a single shared AppState down to LeftView and RightView so they can each observe the same object:

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 的相同实例,当它们的属性更改时,它们都将更新.

Now that both views are observing the same instance of AppState, they'll both update when its properties change.

您还可以使用 @EnvironmentObject 在应用程序中所有所有视图之间共享状态,但是由于这里我们只关注两个视图,因此 @ObservedObject是一个务实的选择.

You can also use @EnvironmentObject to share state between all the views in your app, but since we're only concerned with two views here @ObservedObject is a pragmatic choice.

这篇关于SwiftUI onTapGesture不适用于Mac app中的ObservedObject的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆