您的代码存在一些问题。
您的第一个问题是您需要模型数据和视图之间的绑定 - 通过创建绑定,视图将在模型更改时自动更新。
第二个问题是您只能通过以下方式访问磁力计数据一次motionManager.magnetometerData
而不是设置一个闭包来监视更新startMagnetometerUpdates(to:withHandler:)
.
您可以使用ObservableObject
来自Combine
框架和@ObservedObject
在您看来创建适当的绑定。
首先创建一个类来包装您的运动管理器:
import Foundation
import Combine
import CoreMotion
class MotionManager: ObservableObject {
private var motionManager: CMMotionManager
@Published
var x: Double = 0.0
@Published
var y: Double = 0.0
@Published
var z: Double = 0.0
init() {
self.motionManager = CMMotionManager()
self.motionManager.magnetometerUpdateInterval = 1/60
self.motionManager.startMagnetometerUpdates(to: .main) { (magnetometerData, error) in
guard error == nil else {
print(error!)
return
}
if let magnetData = magnetometerData {
self.x = magnetData.magneticField.x
self.y = magnetData.magneticField.y
self.z = magnetData.magneticField.z
}
}
}
}
该类符合ObservableObject
and @Publish
es 它的三个属性,x,y 和 z。
简单地在磁力计更新闭包中为这些属性分配新值将导致发布者触发并更新任何观察者。
现在,在您看来,您可以声明@ObservedObject
为您的运动管理器类并绑定属性。
struct ContentView: View {
@ObservedObject
var motion: MotionManager
var body: some View {
VStack {
Text("Magnetometer Data")
Text("X: \(motion.x)")
Text("Y: \(motion.y)")
Text("Z: \(motion.z)")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(motion: MotionManager())
}
}
请注意,您需要传递一个实例MotionManager
在你的SceneDelegate.swift
file:
let contentView = ContentView(motion: MotionManager())