ios - 你如何在一个类中进行双向绑定?
问题描述
使用 @EnvironmentObject 我创建了一个继承自 ObservableObject 的类,它是 @Published 全局变量的中心。不过,我无法从类中创建双向绑定。我怎样才能做到这一点?$ 在类中不起作用,因为它只适用于@State,而@State 在类中不起作用。我需要双向绑定,因为当用户在屏幕上移动子实例时,每个子实例都必须具有屏幕位置的实时数据变化。这是我的代码:
import SwiftUI
struct ContentView: View {
@EnvironmentObject var settings: DataBridge
var body: some View {
ZStack {
ForEach(self.settings.childInstances.indices , id: \.self) { index in
self.settings.childInstances[index]
}
VStack {
ForEach(self.settings.childInstanceData.indices, id: \.self) { index in
Text("\(index). y: \(self.settings.childInstanceData[index].height) : x: \(self.settings.childInstanceData[index].width)")
}
}
.offset(y: -250)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
import SwiftUI
struct Child: View {
@EnvironmentObject var settings: DataBridge
@Binding var stateBinding: CGSize
@State var isInitalDrag = true
@State var isOnce = true
@State var currentPosition: CGSize = .zero
@State var newPosition: CGSize = .zero
var body: some View {
Circle()
.frame(width: 50, height: 50)
.foregroundColor(.blue)
.offset(self.currentPosition)
.gesture(
DragGesture()
.onChanged { value in
if self.isInitalDrag && self.isOnce {
// Call function in DataBridge here:
self.settings.addChild()
self.isOnce = false
}
self.currentPosition = CGSize(
width: CGFloat(value.translation.width + self.newPosition.width),
height: CGFloat(value.translation.height + self.newPosition.height)
)
self.stateBinding = self.currentPosition
}
.onEnded { value in
self.newPosition = self.currentPosition
self.isOnce = true
self.isInitalDrag = false
}
)
}
}
struct Child_Previews: PreviewProvider {
static var previews: some View {
Child(stateBinding: .constant(.zero))
}
}
class DataBridge: ObservableObject {
@Published var childInstances: [Child] = []
@Published var childInstanceData: [CGSize] = []
@Published var childIndex = 0
func addChild() {
self.childInstanceData.append(.zero)
// This where I want two-way binding with the childInstanceData array:
self.childInstances.append(Child(stateBinding: $childInstanceData[childIndex]))
self.childIndex += 1
}
}
解决方案
你所拥有的正是我会做的,但我会使用自定义绑定Child
class DataBridge: ObservableObject {
@Published var childInstances: [Child] = []
@Published var childInstanceData: [CGSize] = []
@Published var childIndex = 0
func addChild() {
self.childInstanceData.append(.zero)
// This where I want two-way binding with the childInstanceData array:
let child = Child(stateBinding: Binding(get: {
return self.childInstanceData[self.childIndex]
}, set: {
self.childInstanceData[self.childIndex] = $0
}))
self.childInstances.append(child)
self.childIndex += 1
}
}
这基本上使用自定义绑定来实现您的目标。
推荐阅读
- r - psych::corr.p():如何将 p 值四舍五入到小数点后三位?
- c# - 获取可执行文件当前位置的路径
- java - 如何反序列化数组以包装 pojo?
- machine-learning - 这是使用 Pytorch 训练和测试模型的正确方法吗?
- python - Matplotlib 散点图的自定义图例格式
- javascript - JavaScript .animate() 在 Iphone6 上不起作用
- java - 反应式流与线程池有何不同?
- scala - 在 Spark DataFrame 列中获取不同的单词
- javascript - 使用 react-csv 进行 API 调用
- c# - Unity Muzzleflash 将不断循环播放,尽管没有循环播放。不知道如何解决