使用UIView.Animate将按钮移回原始位置

时间:2017-09-24 14:43:17

标签: ios swift uibutton uiviewanimation

我在另一个功能中以编程方式创建了14个按钮,我为它们添加了目标并让它们全部动画,当我按下任何按钮时我都会瞄准目标,我的问题如何回到原始位置使用 UIView.Animate ??

正如这个Gif:

Demo

代码:

var tileArrayXAxis: [Int] = [] // X-Axis of the my 14 buttons
var tileArrayYAxis: [Int] = [] // Y-Axis of the my 14 buttons
var tileArrayWidth: [Int] = [] // Width of the my 14 buttons
var tileArrayHeight: [Int] = [] // Heigh of the my 14 buttons

var targetArrayXAxis: [Int] = [] // X-Axis of the target
var targetArrayYAxis: [Int] = [] // Y-Axis of the target
var targetArrayWidth: [Int] = [] // Width of the target
var targetArrayHeight: [Int] = [] // Heigh of the target

var i : Int = 0

func moveButton(sender: UIButton) {

    var xS = Int()
    var yS = Int()
    var widthS = Int()
    var heightS = Int()

    if i < targetArrayXAxis.count && i < targetArrayYAxis.count && i < targetArrayWidth.count && i < targetArrayHeight.count {

        xS = targetArrayXAxis[i]
        yS = targetArrayYAxis[i]
        widthS = targetArrayWidth[i]
        heightS = targetArrayHeight[i]
        yS -= widthS

        let startS = CGPoint(x: xS, y: yS)

        let sizeS = CGSize(width: widthS, height: heightS)
        sender.frame = CGRect(x: startS.x, y: startS.y, width: sizeS.width, height: sizeS.width)

    }

    UIView.animate(withDuration: 2, delay: 0, usingSpringWithDamping: 0.2, initialSpringVelocity: 6, options: .allowUserInteraction, animations: { [weak self] in

        sender.transform = .identity
        self?.i += 1        
    })
}

1 个答案:

答案 0 :(得分:0)

在将帧设置为新值后将变换设置为identity将不会移动按钮,因为它只会返回新帧。

要么:在将旧框架设置为新值之前,需要将旧框架存储在变量中:

let oldFrame : CGRect = sender.frame
// Now set the frame to its new value
sender.frame = ....

然后在动画块中:

sender.frame = oldFrame

或者:不为发送者分配新的帧但是为其分配转换变换,然后在动画块中将变换设置为identity以撤消变换并将按钮发送回原来的位置。

编辑:根据要求,一个简单的ViewController实现如下:

import UIKit

类ViewController:UIViewController {

fileprivate var buttonOne : UIButton!
fileprivate var buttonTwo : UIButton!
fileprivate var buttonOneFrame : CGRect {
    return CGRect(origin: CGPoint(x: view.bounds.width / 2 - 200, y: 100),
    size: CGSize(width: 150, height: 100))
}

override func viewDidLoad() {
    super.viewDidLoad()

    buttonOne = {
        let bO : UIButton = UIButton()
        bO.backgroundColor = .red
        bO.setTitle("Frame Method", for: .normal)
        bO.addTarget(self, action: #selector(frameMethodMove(sender:)), for: .touchUpInside)
        bO.frame = buttonOneFrame
        return bO
    }()

    buttonTwo = {
        let bT : UIButton = UIButton()
        bT.backgroundColor = .blue
        bT.setTitle("Transform Method", for: .normal)
        bT.addTarget(self, action: #selector(transformMethodMove(sender:)), for: .touchUpInside)
        bT.frame = CGRect(origin: CGPoint(x: view.bounds.width / 2 + 50, y: 100),
                          size: CGSize(width: 150, height: 100))
        return bT
    }()

    view.addSubview(buttonOne)
    view.addSubview(buttonTwo)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@objc fileprivate func frameMethodMove(sender: UIButton) -> Void {

    let newFrame : CGRect = CGRect(origin: CGPoint(x: buttonOneFrame.origin.x, y: buttonOneFrame.origin.y + 500),
                                   size: buttonOneFrame.size)

    sender.frame = newFrame

    sender.removeTarget(self, action: #selector(frameMethodMove(sender:)), for: .touchUpInside)
    sender.addTarget(self, action: #selector(frameMethodMoveBack(sender:)), for: .touchUpInside)
}

@objc fileprivate func frameMethodMoveBack(sender: UIButton) -> Void {

    UIView.animate(withDuration: 0.5, delay: 0, options: .allowUserInteraction, animations: {
        sender.frame = self.buttonOneFrame
    }, completion: ({ _ in

        sender.removeTarget(self, action: #selector(self.frameMethodMoveBack(sender:)), for: .touchUpInside)
        sender.addTarget(self, action: #selector(self.frameMethodMove(sender:)), for: .touchUpInside)
    }))

}

@objc fileprivate func transformMethodMove(sender: UIButton) -> Void {

    sender.transform = CGAffineTransform.init(translationX: 0, y: 500)

    sender.removeTarget(self, action: #selector(transformMethodMove(sender:)), for: .touchUpInside)
    sender.addTarget(self, action: #selector(transformMethodMoveBack(sender:)), for: .touchUpInside)
}

@objc fileprivate func transformMethodMoveBack(sender: UIButton) -> Void {

    UIView.animate(withDuration: 0.5, delay: 0, options: .allowUserInteraction, animations: {
        sender.transform = .identity
    }, completion: ({ _ in
        sender.removeTarget(self, action: #selector(self.transformMethodMoveBack(sender:)), for: .touchUpInside)
        sender.addTarget(self, action: #selector(self.transformMethodMove(sender:)), for: .touchUpInside)
    }))
}

}