2015-12-30 192 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 
    } 
} 

然後,我創建了創建和移動視圖兩種方法。您可以根據需要調整代碼。 (I持有一個稱爲新思維,以保持參考視圖全局變量,還可以擴展到課程的陣列)

創建視圖:

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) 
     } 
    } 

移動檢視:

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 Touch:

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

這意味着當你使用這個類的實例時,這個方法對其他類是不可見的。我強烈建議你閱讀蘋果公司的swift書:https://itunes.apple.com/at/book/swift-programming-language/id881256329?mt = 11 –

+0

謝謝...另外這本書看起來很棒! –