我如何在SwiftUI视图之间共享/绑定@StateObject ?



我有以下SwiftUIView"PaletteBar";

struct PaletteBar: View {
final class State: ObservableObject {
@Published var selectedColor: Color? = .black
@Published var isEraserSelected = false
}
private enum Constants {
static let colors: [Color] = [.black, .white, .blue, .green, .yellow, .red]
static let eraserColor: Color = .black.opacity(0.7)
}
// MARK: - Properties
@ObservedObject var state = State()
// MARK: - Body
var body: some View {
HStack {
PaletteItem(color: Constants.eraserColor, isSelected: Binding(
get: { state.isEraserSelected },
set: {
state.isEraserSelected = $0
state.selectedColor = $0 ? nil : state.selectedColor
}
))
.overlay { Image(systemName: "pencil.slash") }
.foregroundColor(.white)
.frame(maxWidth: .infinity)
ForEach(Constants.colors, id: .self) { color in
PaletteItem(color: color, isSelected: Binding(
get: { state.selectedColor == color },
set: {
state.selectedColor = $0 ? color : nil
state.isEraserSelected = $0 ? false : state.isEraserSelected
}
))
.frame(maxWidth: .infinity)
}
}
}
}

将状态存储在@ObservedObject中。我想将此状态传递到层次结构中,例如PaletteBarAnnotateImageToolbar的子视图:

struct AnnotateImageToolbar: View {
final class State: ObservableObject {
@Published var selectedColor: Color? = .black
@Published var isEraserSelected = false
}
private enum Constants {
static let spacing: CGFloat = 12.0
static let backgroundColor: Color = .black.opacity(0.7)
static let colorsInsets = EdgeInsets(top: 12.0, leading: 16.0, bottom: 0.0, trailing: 16.0)
static let sliderInsets = EdgeInsets(top: 0.0, leading: 16.0, bottom: 12.0, trailing: 16.0)
static let radius: CGFloat = 8.0
}
// MARK: - State
@StateObject var state = State()
var body: some View {
VStack(spacing: Constants.spacing) {
PaletteBar()
.padding(Constants.colorsInsets)
ZStack {
SizeBar()
.foregroundColor(.gray)
.frame(maxHeight: 12.0)
BrushSizeSlider()
}
.padding(Constants.sliderInsets)
}
.background(Constants.backgroundColor)
.clipShape(RoundedCorners(radius: Constants.radius, corners: [.topLeft, .topRight]))
}
}

这里我创建了一个相同的状态对象@StateObject var state = State()。是否有一种方法可以将PaletteBar中的状态值绑定到AnnotateImageToolbar中的状态?或者我应该创建一个状态对象并将其注入到每个视图中?

将其作为环境对象注入,如

@StateObject var state = State()
var body: some View {
VStack(spacing: Constants.spacing) {
// ... other code
}
.background(...)
.clipShape(...)
.environmentObject(state)  // << here !!

并在子元素中使用:

struct PaletteBar: View {
// MARK: - Properties
@EnvironmentObject var state: State  // << injected by parent !!
// ...
}

最新更新