2015-12-30 137 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

谢谢...另外这本书看起来很棒! –