Как обновить экран, когда я рисую линию для данных в реальном времени
В моей текущей программе swift одна функция отображает данные ускорения в реальном времени на экране в виде линии. Поэтому я использовал класс drawRect
, В результате, график ускорения может быть нарисован, но не в режиме реального времени каждый раз, когда я обновляю его (выключите приложение и снова откройте). Я знаю, что я должен использовать какой-то метод, такой как setNeedsDisplay()
перерисовать это. Но это было бесполезно. Возможно я написал это неправильно. Вот мой код:
import UIKit
import CoreMotion
class draw: UIView, UIAccelerometerDelegate {
var motionManager = CMMotionManager()
override func drawRect(rect: CGRect) {
motionManager.deviceMotionUpdateInterval = 0.1
var acc_x: Double = 0.0
var temp_x: Double = 0.0
var i: CGFloat = 0
var accLine_x = UIGraphicsGetCurrentContext()
if(motionManager.deviceMotionAvailable) {
var queue = NSOperationQueue.mainQueue()
motionManager.startDeviceMotionUpdatesToQueue(queue, withHandler: {
(deviceMotion: CMDeviceMotion!, error: NSError!) in
temp_x = acc_x
acc_x = deviceMotion.userAcceleration.x
CGContextSetLineWidth(accLine_x, 2)
CGContextSetStrokeColorWithColor(accLine_x, UIColor.redColor().CGColor)
CGContextMoveToPoint(accLine_x, i + 10, self.screenHeight * 436 + CGFloat(temp_x * 100))
CGContextAddLineToPoint(accLine_x, i + 13, self.screenHeight * 436 + CGFloat(acc_x * 100))
CGContextStrokePath(accLine_x)
i = (i + 3) % 320
})
}
}
}
2 ответа
Хорошо, вот некоторый переписанный код... важно отметить, что вы должны изолировать код чертежа от обновлений:
var acc_x : Double = 0.0
var temp_x : Double = 0.0
var i: CGFloat = 0
func startMonitoring() {
motionManager.deviceMotionUpdateInterval = 0.1
if(motionManager.deviceMotionAvailable) {
var queue = NSOperationQueue.mainQueue()
motionManager.startDeviceMotionUpdatesToQueue(queue, withHandler: {
(deviceMotion: CMDeviceMotion!, error: NSError!) in
temp_x = acc_x
acc_x = deviceMotion.userAcceleration.x
// update things here
self.setNeedsDisplay()
})
}
}
override func drawRect(rect: CGRect) {
var accLine_x = UIGraphicsGetCurrentContext()
CGContextSetLineWidth(accLine_x, 2)
CGContextSetStrokeColorWithColor(accLine_x, UIColor.redColor().CGColor)
CGContextMoveToPoint(accLine_x, i + 10, self.screenHeight * 436 + CGFloat(temp_x * 100))
CGContextAddLineToPoint(accLine_x, i + 13, self.screenHeight * 436 + CGFloat(acc_x * 100))
CGContextStrokePath(accLine_x)
i = (i + 3) % 320
}
Обратите внимание, что я сделал это очень быстро, но убедитесь, что вы вызываете функцию "startMonitoring", которая должна затем получать обновления от акселерометра, сохранять пару соответствующих переменных (которые вы использовали) и затем вызывать setNeedsDisplay. И в какой-то момент будет вызываться drawRect и использовать переменные, которые вы сохранили, для правильного рисования.
Метод drawRect вызывается в результате того, что вы вызвали вызов setNeedsDisplay. SetNeedsDisplay сообщает системе, что вы хотите обновить чертеж, и в какой-то момент в будущем система вызовет метод drawRect (для этого обновления).
Поэтому, если у вас есть подпрограмма, которая вызывается при изменении базовых данных, ТОГДА выполните вызов setNeedsDisplay.