简体   繁体   English

UILabel不会更新核心动作闭包内调用的文本

[英]UILabel doesn't update the text called inside a core motion closure

I am trying to change the text of a UILabel each time the device gets shaken. 每次设备震动时我都会尝试更改UILabel的文本。 I needed some workaround to capture the shake more frequently than the UIEventSubtype shake. 我需要一些解决方法来比UIEventSubtype震动更频繁地捕捉震动。

The motionMethod gets called, though the text of my UILabel stays the same for several seconds before it finally updates. 调用motionMethod ,虽然我的UILabel文本在最终更新之前会保持相同的几秒钟。

So here is my code: 所以这是我的代码:

let delegate = (UIApplication.sharedApplication().delegate as AppDelegate)

var player:Player!
var motionManager: CMMotionManager?

let accThreshold = 1.0

var referenceTime = NSDate()
let timeThreshold = 0.2

override func viewDidLoad() {
    super.viewDidLoad()

    player = delegate.chancesPlayer
    let queue = NSOperationQueue()

    motionManager = delegate.motionManager
    motionManager?.startDeviceMotionUpdatesToQueue(queue, withHandler: {
        (motion: CMDeviceMotion!, error:NSError!) in
        self.motionMethod(motion)
        })
}

and the motionMethod : motionMethod

func motionMethod(deviceMotion: CMDeviceMotion){
    var acceleration = deviceMotion.userAcceleration
    if fabs(acceleration.x) > accThreshold || fabs(acceleration.y) > accThreshold || fabs(acceleration.z) > accThreshold{
        if -referenceTime.timeIntervalSinceNow > timeThreshold{
            referenceTime = NSDate()
            player.grow()
            println("Player ist now at size: \(player.growth)")         //this gets called frequently...
            growthTF.text = "Player ist now at size: \(player.growth)"  //...that doesn't
        }
    }
}

So why is there a delay in the update of the text? 那么为什么文本更新有延迟?

You're updating the label on a thread other than the main (UI) thread, which is undefined behavior. 您正在更新主(UI)线程以外的线程上的标签,这是未定义的行为。 You should either use GCD to dispatch back to the main thread for the UI updates inside the closure, like this: 您应该使用GCD将主要线程分派回闭包内的UI更新,如下所示:

func motionMethod(deviceMotion: CMDeviceMotion){
    var acceleration = deviceMotion.userAcceleration
    if fabs(acceleration.x) > accThreshold || fabs(acceleration.y) > accThreshold || fabs(acceleration.z) > accThreshold{
        if -referenceTime.timeIntervalSinceNow > timeThreshold{

            referenceTime = NSDate()
            player.grow()

            dispatch_async(dispatch_get_main_queue()) {
                growthTF.text = "Player ist now at size: \(player.growth)"  //...that doesn't
            }
        }
    }
}

Or, you could specify that the updates should happen on the main queue. 或者,您可以指定更新应在主队列上进行。

motionManager?.startDeviceMotionUpdatesToQueue(NSOperationQueue.mainQueue(), withHandler: {

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM