2015-12-30 1 views
0

Я создаю игру, в которой кнопка, которая создается, перемещается с одной стороны экрана на другую, когда я нажимаю кнопку, называемую start. Проблема в том, что когда я нажимаю кнопку запуска до того, как кнопка, которая двигается, достигает конечной точки, она останавливается, а не продолжает (и другая созданная кнопка начинает двигаться, как ожидалось). Должен ли я создавать новый CADisplayLink каждый раз, когда я нажимаю кнопку запуска? Если да, то как мне это сделать? Вот код:Кнопка перестает двигаться при создании новой кнопки, которая перемещает

var button1 = UIButton() 
var displayLink: CADisplayLink? 
var startTime: CFAbsoluteTime? 
let duration = 2.0 
var leadingConstraint: NSLayoutConstraint! 
var topConstraint: NSLayoutConstraint! 
var l1 = false 
@IBAction func start(sender: UIButton) { 
    n1() 
} 
func n1() { 
    l1 = false 
    startTime = CFAbsoluteTimeGetCurrent() 
    displayLink = CADisplayLink(target: self, selector: "handleDisplayLink:") 
    displayLink?.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes) 
} 
func handleDisplayLink(displayLink: CADisplayLink) { 
    if l1 == false { // so it doesn't randomize leading constraint twice 
     button1 = createButton() 
     let randomNumber = Int(arc4random_uniform(180) + 30) 
     let elapsed = CFAbsoluteTimeGetCurrent() - startTime! 
     var percentComplete = CGFloat(elapsed/duration) 
     if percentComplete >= 1.0 { 
      percentComplete = 1.0 
      // self.button1.removeFromSuperview() 
      displayLink.invalidate() 
      button1.hidden = true 
     } 
     leadingConstraint.constant = CGFloat(randomNumber) 
     topConstraint.constant = 390 - 350 * percentComplete 
     NSLayoutConstraint.activateConstraints([ 
      leadingConstraint, 
      topConstraint, 
      button1.widthAnchor.constraintEqualToConstant(75), 
      button1.heightAnchor.constraintEqualToConstant(75) 
      ]) 
     l1 = true 
    } 
    else{ 
     let elapsed = CFAbsoluteTimeGetCurrent() - startTime! 
     var percentComplete = CGFloat(elapsed/duration) 
     if percentComplete >= 1.0 { 
      percentComplete = 1.0 
      displayLink.invalidate() 
      button1.hidden = true 
     } 
     topConstraint.constant = 390 - 350 * percentComplete 
     NSLayoutConstraint.activateConstraints([ 
      leadingConstraint, 
      topConstraint, 
      button1.widthAnchor.constraintEqualToConstant(75), 
      button1.heightAnchor.constraintEqualToConstant(75) 
      ]) 
    } 
} 
func buttonPressed(sender: UIButton!) { 
    button1.hidden = true 
    displayLink?.invalidate() 
} 
func createButton() ->UIButton { 
    let button = UIButton() 
    button.setImage(UIImage(named: "BlueBall.png")!, forState: UIControlState.Normal) 
    button.addTarget(self, action: "buttonPressed:", forControlEvents: UIControlEvents.TouchUpInside) 
    self.view.addSubview(button) 
    button.translatesAutoresizingMaskIntoConstraints = false 
    leadingConstraint = button.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor, constant: 0) 
    topConstraint = button.topAnchor.constraintEqualToAnchor(view.topAnchor, constant: 0) 
    NSLayoutConstraint.activateConstraints([ 
     leadingConstraint, 
     topConstraint, 
     button.widthAnchor.constraintEqualToConstant(75), 
     button.heightAnchor.constraintEqualToConstant(75) 
     ]) 
    return button 
} 

Пожалуйста, помогите. Было бы очень благодарно. Заранее спасибо. Anton

+0

Я бы не использовать CADisplayLink; вместо этого создайте кнопку с нужными ограничениями и анимируйте ограничение через UIView.animate ... каждый раз, когда вы добавляете другую кнопку. Это должно перемещать вновь созданную кнопку всегда до конца желаемого целевого адресата. Также вы можете просто добавить и забыть ограничение, если оно вам не понадобится впоследствии. –

+0

@Christian 'fuzi' Orgler Я избегаю UIView.animate, потому что я видел, что движение происходит не так же быстро, как все (медленнее в начале и в конце). Кроме того, я уверен, что обнаружил прикосновение к кнопке (я могу это сделать, только если я использую .presentationlayer, я считаю) –

+0

Это звучит для меня, облегчая вашу анимацию, тогда, если вы поместите UIViewAnimationOptionsCurveLInear, то это линейная анимация :) Вам нужно определить касание кнопки во время движения? –

ответ

0

Okay Anton O; как обсуждалось, я отправляю ответ, как обнаружить прикосновение к движущемуся UIView. Это работает как, CAAnimation и UIView.animationWith ..

Сначала я создал расширение CGRect, для удобства:

extension CGRect { 
    init(position: CGPoint, size: CGSize) { 
     self.origin = CGPoint(x: position.x - (size.width/2.0), y: position.y - (size.height/2.0)) 
     self.size = size 
    } 
} 

Затем я создал два метода, которые создают и двигают вид. Вы можете адаптировать код к вашим потребностям. (Я держу глобальную переменную NEXTVIEW сохранить ссылку на представление, также может быть продлен на массив, конечно)

Создать Вид:

private func createView(index: Int) { 
     nextView?.removeFromSuperview() 

     nextView = UIView() 
     nextView?.bounds = CGRect(x: 0, y: 0, width: 60, height: 60) 
     nextView?.backgroundColor = UIColor.redColor() 
     nextView?.center = CGPoint(x: 30, y: CGRectGetMidY(self.view.bounds)) 

     if let nextView = nextView { 
      view.addSubview(nextView) 
     } 
    } 

Move View:

private func moveView() { 
     guard let nextView = nextView else { 
      return 
     } 

     UIView.animateWithDuration(5.0) {() -> Void in 
      nextView.center = CGPoint(x: CGRectGetMaxX(self.view.bounds) + 30, y: CGRectGetMidY(self.view.bounds)) 
     } 
    } 

Detect Прикосновение:

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     super.touchesEnded(touches, withEvent: event) 

     if let touch = touches.first, nextView = nextView { 
      let touchRect = CGRect(position: touch.locationInView(self.view), size: CGSize(width: 20, height: 20)) 

      guard let viewPosition = nextView.layer.presentationLayer()?.position else { 
       return 
      } 

      let viewRect = CGRect(position: viewPosition, size: nextView.bounds.size) 

      if CGRectIntersectsRect(touchRect, viewRect) { 
       print(" ") 
      } else { 
       print("") 
      } 
     } 
    } 

Вы можете расширить методы для ваших нужд, а также добавить некоторую «производительность» усиливающую проверки (например, если вид виден и двигаться дальше или вернуться прямо в методе touchesEnded и т.д.)

+0

Спасибо ... что делает добавление частного до функции? –

+0

Это означает, что при использовании экземпляра этого класса эти методы не видны другим классам. Я настоятельно рекомендую вам прочитать быструю книгу из яблока: https://itunes.apple.com/at/book/swift-programming-language/id881256329?mt=11 –

+0

Спасибо ... Также книга кажется замечательной! –