我正在开发一个应用程序,它可以将滤镜应用于图像。滤镜有许多用户可以修改的参数。我已经创建了一个包含这些参数的ObservableObject。每当其中一个参数发生变化时,即使视图显示的值与以前相同,也会出现视图的可见更新。当我将参数建模为单独的@State变量时,不会发生这种情况。
如果这是预期的(在所有观察对象确实改变之后,因此依赖于它的每个视图都会更新),那么ObservedObject是这项工作的正确工具吗?另一方面,将参数建模为单独的@State/@Binding变量似乎非常不方便,特别是当大量参数(例如10+)需要传递给多个子视图时!
所以我问:
我在这里正确使用了ObservedObject吗?可见的更新是意外的,但可以接受的,还是在swiftUI中有更好的解决方案来处理这个问题?
使用@ObservedObject的示例:
import SwiftUI
class Parameters: ObservableObject {
@Published var pill: String = "red"
@Published var hand: String = "left"
}
struct ContentView: View {
@ObservedObject var parameters = Parameters()
var body: some View {
VStack {
// Using the other Picker causes a visual effect here...
Picker(selection: self.$parameters.pill, label: Text("Which pill?")) {
Text("red").tag("red")
Text("blue").tag("blue")
}.pickerStyle(SegmentedPickerStyle())
// Using the other Picker causes a visual effect here...
Picker(selection: self.$parameters.hand, label: Text("Which hand?")) {
Text("left").tag("left")
Text("right").tag("right")
}.pickerStyle(SegmentedPickerStyle())
}
}
}
字符串
使用@State变量的示例:
import SwiftUI
struct ContentView: View {
@State var pill: String = "red"
@State var hand: String = "left"
var body: some View {
VStack {
Picker(selection: self.$pill, label: Text("Which pill?")) {
Text("red").tag("red")
Text("blue").tag("blue")
}.pickerStyle(SegmentedPickerStyle())
Picker(selection: self.$hand, label: Text("Which hand?")) {
Text("left").tag("left")
Text("right").tag("right")
}.pickerStyle(SegmentedPickerStyle())
}
}
}
型
3条答案
按热度按时间djmepvbi1#
警告:这个答案不太理想。如果参数的属性将在另一个视图中更新(例如,额外的选择器),则选择器视图将不更新。
ContentView不应该“observe”参数;参数的更改将导致它更新其内容(在Pickers的情况下是可见的)。为了防止需要observed属性 Package 器,我们可以为参数的属性提供显式绑定。ContentView的子视图可以在参数上使用@Observed。
字符串
zz2j4svz2#
第二次尝试
ContentView不应该观察参数(这会导致不希望的可见更新)。参数的属性也应该是ObservableObjects,以确保视图可以在特定属性更改时更新。
由于String是结构体,它们不能符合ObservableObject;一个小的 Package 器'ObservableValue'是必要的。
MyPicker是Picker的一个小 Package 器,用于使视图在更改时更新。默认的Picker接受绑定,因此依赖于层次结构中的视图来执行更新。
这种方法感觉是可扩展的:
缺点:
字符串
ycggw6v23#
快进到2023年。ObservedObject的原始示例不再导致不需要的可见更新,这似乎表明这确实是SwiftUI中的一个小“bug”。请注意,如果ContentView示例化参数,则需要使用@StateObject而不是@ObservedObject。否则,您应该将参数传递给ContentView。