使用具有约束持续时间的动画在 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 点(正常尺寸)。这是代码:
@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个问题:
- 按钮必须从 A 点开始,而不是从左上角开始。
- 按钮必须是正常尺寸,不能是小尺寸。
- 按钮在移动时可以点击
对于 (1) 和 (2),您必须移动代码以在 viewDidLoad()
内添加按钮,并且还需要为 button
和 topAnchorForButton
.[=26 保留实例=]
首先,您为 button
和 topAnchorForButton
声明两个属性。
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),要点击一个移动的按钮,你需要在button's .layer.presentationLayer property
上做点击测试。
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:
方法中并设置其位置。您不再需要为 button
和 topAnchorForButton
保留实例。您可以使用标签来检索按钮。
@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 event:
的代码
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)
}
}
请注意,如果您不喜欢使用标签来检索按钮,您可以为按钮声明一个属性。
我想将一个按钮从 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个问题:
- 按钮必须从 A 点开始,而不是从左上角开始。
- 按钮必须是正常尺寸,不能是小尺寸。
- 按钮在移动时可以点击
对于 (1) 和 (2),您必须移动代码以在 viewDidLoad()
内添加按钮,并且还需要为 button
和 topAnchorForButton
.[=26 保留实例=]
首先,您为 button
和 topAnchorForButton
声明两个属性。
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),要点击一个移动的按钮,你需要在button's .layer.presentationLayer property
上做点击测试。
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:
方法中并设置其位置。您不再需要为 button
和 topAnchorForButton
保留实例。您可以使用标签来检索按钮。
@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 event:
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)
}
}
请注意,如果您不喜欢使用标签来检索按钮,您可以为按钮声明一个属性。