重复计时器会中断平滑的UIImage拖动

时间:2018-10-23 22:33:30

标签: iphone swift timer drag

当我开始拖动图像时,它会触发一个计时器,但是每秒(当计时器重复执行时)拖动都会中断,并且图像会在开始位置出现几毫秒。这是video。如果我删除计时器,则拖动可以正常工作。

我为可拖动图像(DragItem)创建了自定义类,其中当图像被触摸时会在其中发布通知,从而在ViewController上触发计时器。

我认为此故障可能与 RunLoop.main.add(timer,forMode:RunLoop.Mode.common)有关,但是,我无法弄清楚如何解决它。有什么想法吗?

以下是我能够找到的最接近的主题:Timer not working when draggingtimer pauses when scrolling

  

DragItem:UIImageView类

var dragItemOrigin: CGPoint!
var dropTaget: UIView?

override init(frame: CGRect) {
    super.init(frame: frame)
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "touchedDragItem"), object: nil)
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in (touches) {
        let location = touch.location(in: self.superview)
        self.center = location
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    UIView.animate(withDuration: 0.3, animations: {
        if let touch = touches.first, let target = self.dropTaget {
            let position = touch.location(in: self.superview)
            if target.frame.contains(position) {
                NotificationCenter.default.post(name: NSNotification.Name(rawValue: "onTargetDropped"), object: nil)
            }
        }
    }) 
}
  

ViewController

var counter = 4.0
var timer: Timer!
var isTimerRunning = false
var MAX_PENALTIES = 3
var penalties: Int = 0

let dragItemInCode: DragItem = {
    let imageView = DragItem(frame: CGRect.zero)
    imageView.image = UIImage(named: "Oval1.png")
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.isUserInteractionEnabled = true
    return imageView
}()

override func viewDidLoad() {
    super.viewDidLoad()

    view.addSubview(dragItemInCode)
    counter = 4

    view.bringSubviewToFront(dragItemInCode)

    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.dragItemTouched(_:)), name:NSNotification.Name(rawValue: "touchedDragItem"), object: nil)

    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.dragItemDroppedOnDropItem(_:)), name:NSNotification.Name(rawValue: "onTargetDropped"), object: nil)
    setupLayout()
}

private func setupLayout() {
    dragItemInCode.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    dragItemInCode.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
    dragItemInCode.widthAnchor.constraint(equalToConstant: 35).isActive = true
    dragItemInCode.heightAnchor.constraint(equalToConstant: 35).isActive = true
    //dragItemInCode.layoutIfNeeded()
}

@objc func dragItemTouched(_ sender: NSNotification) {
     print("item touched")
    startTimer()
}


func startTimer() {
    timer = Timer(timeInterval: 4, target: self, selector: #selector(ViewController.changeGameState), userInfo: nil, repeats: true)
    RunLoop.main.add(timer, forMode: RunLoop.Mode.common)
}


@objc func dragItemDroppedOnDropItem(_ sender: NSNotification) {
    print("item dropped")
}

func timerLabelUpdates() {
      timerLbl.text = String(format: "%.1f", counter)

    if counter <= 0 {
        penalties += 1
    } else {
        self.counter -= 0.1
    }
}


@objc func changeGameState() {
     timerLbl.text = String(format: "%.1f", counter)
    if counter > 0 {
        self.counter -= 1
    } else {
        gameOver()
    }

func gameOver() {
    timer.invalidate()
    dropItemLbl.playDeathAnimation()
    UIView.animate(withDuration: 1, delay: 0.5, options: .curveEaseInOut, animations: {
        Vibration.error.vibrate()
        self.dragItemInCode.alpha = 0
        self.explosion()
    }, completion: nil)
}

func explosion() {
    let emitter = ExplodeView.get(with: #imageLiteral(resourceName: "particle"))
    emitter.emitterPosition = CGPoint(x: dragItemInCode.frame.width / 2, y: dragItemInCode.frame.height/2)
    emitter.emitterSize = dragItemInCode.bounds.size

    dragItemInCode.layer.addSublayer(emitter)

}

}

0 个答案:

没有答案