【问题标题】:Move back button to original position with UIView.Animate使用 UIView.Animate 将按钮移回原始位置
【发布时间】:2017-09-24 14:43:16
【问题描述】:

我在另一个函数中以编程方式创建了 14 个按钮,我向它们添加了目标并让它们为每个按钮设置动画,当我按下任何按钮时我都有目标转到目标,我的问题 如何返回使用 UIView.Animate ??

的原始位置

就像这个 Gif 一样:

代码:

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        
    })
}

【问题讨论】:

  • sender.transform = .identity 不要移回原来的位置?
  • 否@Arrabidas92

标签: ios swift uibutton uiviewanimation


【解决方案1】:

将框架设置为新值后将转换设置为标识根本不会移动按钮,因为它只会返回新框架。

要么:您需要将旧帧存储在变量中,然后再将其设置为新值:

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

然后在你的动画块中:

sender.frame = oldFrame

或者:不给发送者分配一个新的帧,而是给它分配一个平移变换,然后在动画块中将变换设置为标识以撤消变换并将按钮发送回原来的位置。

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

import UIKit

类视图控制器: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)
    }))
}

}

【讨论】:

  • 我正在尝试您的解决方案,但它会自动回到原始位置 我想手动回到原始位置 我的意思是按下它,我该怎么做??
  • 请看我的 GIF,看看动画 4 按钮是如何通过按下他们的@Sparky 来定位和跳过位置并回到原来的位置
  • @user1.develop 我了解您要执行的操作-单击返回按钮很简单。您可以通过将方法一分为二并替换按钮目标来实现。对于 frame 方法,您还需要将原始按钮位置保存为类属性(该属性或 UIButton 子类);在我看来,变换方法可能更优雅。请查看我的编辑。
猜你喜欢
  • 2014-02-02
  • 1970-01-01
  • 1970-01-01
  • 2022-11-08
  • 1970-01-01
  • 1970-01-01
  • 2020-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多