ios 无法在TextView中显示`CMMotionManager.attitude`?

0x6upsns  于 5个月前  发布在  iOS
关注(0)|答案(3)|浏览(41)

我的应用程序依赖于iPhone的握持方式。出于多种原因,我需要使用带有CoreMotion.attitude属性的设备传感器。当用户为我的应用程序设置配置时,阅读设备的姿态只会使用几次/秒。
我已经尝试了pullpush两种方法来处理运动数据,但我都不知道如何存储CMAttitude的值,以便在其他地方访问它们。

在下面的代码中...

  • manager.startDeviceMotionUpdates闭包中的print语句工作正常。
  • 但是.我不能访问闭包外的.attitude值。
  • 如果我尝试在姿态数据中包含TextView,Xcode预览版以及在我设备上运行的应用程序都会崩溃。

这是我的代码.

import SwiftUI
import CoreMotion

let manager = CMMotionManager()
let queue = OperationQueue()

struct ContentView: View {
   
   @State var myAttitude: CMAttitude = CMAttitude()
   
   var body: some View {
      VStack {
         Image(systemName: "globe")
            .imageScale(.large)
            .foregroundStyle(.tint)
         Text("Hello, world!")
         Button(action: {
            
            guard manager.isDeviceMotionAvailable else { return }
            
            manager.startDeviceMotionUpdates(to: queue) { (motion, error) in
               guard let motion else {
                  return
               }
               
               let currentAttitude = motion.attitude
               myAttitude = currentAttitude
               print("🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢")
               print("Attitude-Pitch: \(myAttitude)")//  ←←← These Work Fine!
               print("Attitude-Pitch: \(myAttitude.pitch.formatted(.number.precision(.fractionLength(5))))")
               print("Attitude-Yaw: \(myAttitude.yaw.formatted(.number.precision(.fractionLength(5))))")
               print("Attitude-Roll: \(myAttitude.roll.formatted(.number.precision(.fractionLength(5))))")
               print("🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴")
            }
         }, label: {
            Text("Check Your Attitude")
               .foregroundStyle(.cyan)
         })
         Text("Attitude-Pitch: \(myAttitude)") //  ←←← App Crashes Here!
//         Text("Attitude-Pitch: \(myAttitude.pitch.formatted(.number.precision(.fractionLength(5))))")
//         Text("Attitude-Yaw: \(myAttitude.yaw.formatted(.number.precision(.fractionLength(5))))")
//         Text("Attitude-Roll: \(myAttitude.roll.formatted(.number.precision(.fractionLength(5))))")
      }
      .padding()
   }
}

#Preview {
   ContentView(myAttitude: CMAttitude())
}

字符串

velaa5lx

velaa5lx1#

你的代码有两个问题

  1. @State应该始终标记为private,因为memberwise初始化器被认为是不安全的。
    https://developer.apple.com/documentation/swiftui/state
    1.当CMAttitude()编译时,它没有文档,所以你不应该使用它。它来自NSObject,它并不真正属于CMAttitude(这是一个bug)。
    https://developer.apple.com/documentation/coremotion/cmattitude
    一旦你纠正了这两个问题,你的代码将不再崩溃。
import SwiftUI
import CoreMotion

let manager = CMMotionManager()
let queue = OperationQueue()

struct SampleAttitudeView: View {
    //State should always be private.
    // Mark optional
    @State private var myAttitude: CMAttitude?
    
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(.tint)
            Text("Hello, world!")
            Button(action: {
                
                guard manager.isDeviceMotionAvailable else { return }
                
                manager.startDeviceMotionUpdates(to: queue) { (motion, error) in
                    guard let motion else {
                        return
                    }
                    
                    let currentAttitude = motion.attitude
                    myAttitude = currentAttitude
                    print("🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢")
                    print("Attitude-Pitch: \(myAttitude!)")//  ←←← These Work Fine!
                    print("Attitude-Pitch: \(myAttitude!.pitch.formatted(.number.precision(.fractionLength(5))))")
                    print("Attitude-Yaw: \(myAttitude!.yaw.formatted(.number.precision(.fractionLength(5))))")
                    print("Attitude-Roll: \(myAttitude!.roll.formatted(.number.precision(.fractionLength(5))))")
                    print("🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴")
                }
            }, label: {
                Text("Check Your Attitude")
                    .foregroundStyle(.cyan)
            })
            // Show the attitude once it is available.
            if let myAttitude {
                Text("Attitude-Pitch: \(myAttitude)") //  ←←← App  Crashes Here!
                Text("Attitude-Pitch: \(myAttitude.pitch.formatted(.number.precision(.fractionLength(5))))")
                Text("Attitude-Yaw: \(myAttitude.yaw.formatted(.number.precision(.fractionLength(5))))")
                Text("Attitude-Roll: \(myAttitude.roll.formatted(.number.precision(.fractionLength(5))))")
            } else {
                Text("Waiting for Attitude")
            }
            
        }
        .padding()
    }
}

#Preview {
    SampleAttitudeView()
}

字符串

wb1gzix0

wb1gzix02#

你能试试这个吗?我认为你可以修改@State变量,CAAtutyde类型可能是一个问题。

struct ContentView: View {
   
   @State private var pitch: Double = 0.0
   @State private var roll: Double = 0.0
   @State private var yaw: Double = 0.0
   
   var body: some View {
      VStack {
         // ... (other UI components)
         Text("Attitude-Pitch: \(pitch.formatted(.number.precision(.fractionLength(5))))")
         Text("Attitude-Roll: \(roll.formatted(.number.precision(.fractionLength(5))))")
         Text("Attitude-Yaw: \(yaw.formatted(.number.precision(.fractionLength(5))))")
      }
      .onAppear {
         guard manager.isDeviceMotionAvailable else { return }
         
         manager.startDeviceMotionUpdates(to: queue) { (motion, error) in
            guard let motion = motion else { return }
            
            let currentAttitude = motion.attitude
            DispatchQueue.main.async {
               pitch = currentAttitude.pitch
               roll = currentAttitude.roll
               yaw = currentAttitude.yaw
            }
         }
      }
   }
}

字符串

bvhaajcl

bvhaajcl3#

nil作为默认值

@State var myAttitude: CMAttitude?

字符串
并更新主队列中的状态:

DispatchQueue.main.async {
    myAttitude = currentAttitude
}

相关问题