在swift中移动按钮,使用带有约束的持续时间动画,并在其期间检测触摸 [英] Moving a button in swift using animate with duration with constraints and detecting a touch during it
问题描述
我想将按钮从点A移动到点B.点A: leadingConstraint = 120,topConstraint = 400
。点B: leadingConstraint = 120,topConstraint = 200
。对于我的游戏目的,我不能使用框架。我也想要能够检测到它在它移动时的触摸(我不知道如何做到这一点)。我有这个代码,我试图移动按钮(使用动画持续时间),但发生的是,它从左上角开始(小尺寸),而不是从点A开始。然后去B点(正常尺寸)。这是代码:
I want to move a button from point A to point B. Point A: leadingConstraint = 120, topConstraint = 400
. Point B: leadingConstraint = 120, topConstraint = 200
. For my game purpose, I can't use frames. I also want to be able to detect a touch on it while its moving (I have no idea how to do this). I have this code where I'm attempting to move the button (using animate with duration) but whats happening is that its starting from the top left corner (small size) instead of starting from point A. It then goes to point B (normal size). Here is the code:
@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
。提前感谢... Anton
Please help. I also don't want to use CADisplayLink
. Thanks in advance... Anton
推荐答案
您的问题有3个问题:
- 按钮必须从A点开始,而不是从左上角开始。
- 按钮必须有正常尺寸,而不是小尺寸。
- 该按钮可以在移动时点击。
(2),您必须在 viewDidLoad()
中移动代码以添加按钮,并且还需要保留按钮的实例
topAnchorForButton
。
For (1) and (2), you must move code to add button inside the viewDidLoad()
and also need to keep instances for button
and topAnchorForButton
.
首先,为按钮声明两个属性
和 topAnchorForButton
。
var button: UIButton!
var topAnchorForButton: NSLayoutConstraint!
接下来,添加按钮并将其位置设置在 viewDidLoad / code>。
Next, you add button and set its position inside the 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)]
}
$ b b
对于(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:
方法中。您不需要再保留按钮
和 topAnchorForButton
的实例。您可以使用标签来检索按钮。
If you want to create a new button every time the start button is pressed, you put the code to add and set its position inside the start:
method. You don't need to keep instances for button
and topAnchorForButton
anymore. You can use tag to retrieve the button.
@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)
}
}
请注意,如果您不想使用标签来检索按钮,可以为按钮声明属性。
Note that if you don't like to use tag to retrieve the button, you can declare a property for the button.
这篇关于在swift中移动按钮,使用带有约束的持续时间动画,并在其期间检测触摸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!