ios - 使用具有约束持续时间的动画快速移动按钮并在此期间检测触摸

标签 ios swift swift2 constraints animatewithduration

我想将一个按钮从 A 点移动到 B 点。A 点:leadingConstraint = 120, topConstraint = 400。 B 点:leadingConstraint = 120, topConstraint = 200。为了我的游戏目的,我不能使用框架。我还希望能够在它移动时检测到它的触摸(我不知道该怎么做)。我有这段代码,我试图移动按钮(使用带持续时间的动画)但发生的事情是它从左上角(小尺寸)开始而不是从 A 点开始。然后它转到 B 点(正常尺寸)。这是代码:

@IBAction func Start(sender: UIButton) { 
    var topAnchorforButton: NSLayoutConstraint!
    let button = UIButton()
    button.setTitle("button", forState: .Normal)
    button.setTitleColor(UIColor.blackColor(), forState: .Normal)
    button.addTarget(self, action: "buttonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
    self.view.addSubview(button)
    button.translatesAutoresizingMaskIntoConstraints = false
    topAnchorforButton = button.topAnchor.constraintEqualToAnchor(view.topAnchor, constant: 400)
    NSLayoutConstraint.activateConstraints([
    button.widthAnchor.constraintEqualToConstant(75),
    button.heightAnchor.constraintEqualToConstant(75),
    button.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor, constant: 120),
    topAnchorforButton
        ])
    [UIView.animateWithDuration(5.0, delay: 0.0, options: [.CurveLinear, .AllowUserInteraction], animations: {
    topAnchorforButton.constant = 200                         
    self.view.layoutIfNeeded()
        }, completion: nil)]    
   }
func buttonPressed(sender: UIButton) {
    print("hi")
}

请帮忙。我也不想使用 CADisplayLink。提前致谢...安东

最佳答案

你的问题有3个问题:

  1. 按钮必须从 A 点开始,而不是从左上角开始。
  2. 按钮必须有正常尺寸而不是小尺寸。
  3. 按钮在移动时可以点击。

对于 (1) 和 (2),您必须移动代码以在 viewDidLoad() 中添加按钮,并且还需要为 button 保留实例topAnchorForButton.

首先,您为 buttontopAnchorForButton 声明了两个属性。

var button: UIButton!
var topAnchorForButton: NSLayoutConstraint!

接下来,添加按钮并在 viewDidLoad() 中设置它的位置。

override func viewDidLoad() {
    super.viewDidLoad()

    button = UIButton()
    button.setTitle("button", forState: .Normal)
    button.setTitleColor(UIColor.blackColor(), forState: .Normal)
    button.addTarget(self, action: "buttonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
    self.view.addSubview(button)
    button.translatesAutoresizingMaskIntoConstraints = false

    topAnchorForButton = button.topAnchor.constraintEqualToAnchor(view.topAnchor, constant: 400)
    NSLayoutConstraint.activateConstraints([
        topAnchorForButton,
        button.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor, constant: 120),
    ])
}

func buttonPressed(sender: UIButton) {
    print("hi")
}

@IBAction func start(sender: AnyObject) {
    topAnchorForButton.constant = 200

    [UIView.animateWithDuration(5.0, delay: 0.0, options: [.CurveLinear, .AllowUserInteraction], animations: {
        self.view.layoutIfNeeded()
        }, completion: nil)]
}

对于 (3),要点击移动按钮,您需要对按钮的 .layer.presentationLayer 属性 进行点击测试。

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    guard let touch = (touches as NSSet).anyObject() as? UITouch else {
        return
    }

    let touchLocation = touch.locationInView(self.view)
    if button.layer.presentationLayer()?.hitTest(touchLocation) != nil {
        self.buttonPressed(button)
    }
}

如果您想在每次按下开始按钮时创建一个新按钮,您可以将要添加的代码放入 start: 方法中并设置它的位置。您不再需要为 buttontopAnchorForButton 保留实例。您可以使用标签来检索按钮。

@IBAction func start(sender: AnyObject) {
    // Remove the previous button
    if let previousButton = self.view.viewWithTag(100) as? UIButton {
        previousButton.removeFromSuperview()
    }

    let button = UIButton()
    button.tag = 100 // Set a tag so you can retrieve the button
    button.setTitle("button", forState: .Normal)
    button.setTitleColor(UIColor.blackColor(), forState: .Normal)
    button.addTarget(self, action: "buttonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
    self.view.addSubview(button)
    button.translatesAutoresizingMaskIntoConstraints = false

    let topAnchorForButton = button.topAnchor.constraintEqualToAnchor(view.topAnchor, constant: 400)
    NSLayoutConstraint.activateConstraints([
        topAnchorForButton,
        button.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor, constant: 120),
        ])

    self.view.layoutIfNeeded()

    [UIView.animateWithDuration(5.0, delay: 0.0, options: [.CurveLinear, .AllowUserInteraction], animations: {
        topAnchorForButton.constant = 200
        self.view.layoutIfNeeded()
        }, completion: nil)]
}

更新 touchesBegan:withEvent 事件的代码:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    guard let touch = (touches as NSSet).anyObject() as? UITouch else {
        return
    }

    guard let button = self.view.viewWithTag(100) as? UIButton else {
        return
    }

    let touchLocation = touch.locationInView(self.view)
    if button.layer.presentationLayer()?.hitTest(touchLocation) != nil {
        self.buttonPressed(button)
    }
}

请注意,如果您不喜欢使用标签来检索按钮,您可以为该按钮声明一个属性。

关于ios - 使用具有约束持续时间的动画快速移动按钮并在此期间检测触摸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34561882/

相关文章:

ios - 如何使用xcodebuild正确构建armv7静态库

ios - 如何在单元格 TableView 上右对齐 UILabel?

与 Lynda 一起学习 iOS : Getting error can't invoke 'init' with argument of type @lvalue String

ios - subview 滚动不起作用 SWIFT

ios - TapGesture 添加到 UIView+SomeCategory。我如何使用这个添加到我的 UIViewController 的 UIView?

xcode - Swift 2.0 : Could not find overload. 需要解释

swift - 如何更新列表中的一对多内容?

iOS swift : dynamic function graph/chart

ios - 如何创建取消按钮?

xcode - 仅设置 "All Exceptions"断点时,Xcode 7 始终在应用程序启动时停止