使用 NSLayoutConstraints 在 UIView 上简单的向上滑动动画

Simple slide up animation on UIView using NSLayoutConstraints

我花了一段时间试图解决这个问题,但就是做不到。我在这里可能缺少一些非常简单的东西。我正在尝试为从底部进入的视图设置动画。这是我用于视图的代码:

private let undoView: UIView = {
    let view = UIView()
    view.translatesAutoresizingMaskIntoConstraints = false
    view.backgroundColor = .white
    view.layer.cornerRadius = 15
    view.layer.shadowOffset = .zero
    view.layer.shadowOpacity = 0.3
    view.layer.shadowRadius = 5
    view.layer.shouldRasterize = true
    view.layer.rasterizationScale = UIScreen.main.scale

    let button = UIButton()
    button.translatesAutoresizingMaskIntoConstraints = false
    button.setTitle("Undo", for: .normal)
    button.titleLabel?.textAlignment = .center
    button.setTitleColor(.systemBlue, for: .normal)
    let buttonConstraints = [
        button.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
        button.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
        button.topAnchor.constraint(equalTo: view.topAnchor, constant: 16),
        button.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -16)
    ]
    view.addSubview(button)
    NSLayoutConstraint.activate(buttonConstraints)

    let swipeGesture = UISwipeGestureRecognizer(target: view, action: #selector(undoViewSwiped))
    view.addGestureRecognizer(swipeGesture)

    return view
}()

这是我用来尝试实现动画的代码:

func addUndoView() {
    var bottomConstraint = undoView.topAnchor.constraint(equalTo: view.bottomAnchor, constant: 0)
    let constraints = [
        undoView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
        undoView.widthAnchor.constraint(equalToConstant: view.bounds.width / 3),
        bottomConstraint,
        undoView.heightAnchor.constraint(equalToConstant: 50)
    ]
    view.addSubview(undoView)
    NSLayoutConstraint.activate(constraints)
    undoView.layoutIfNeeded()

    bottomConstraint.isActive = false
    bottomConstraint = undoView.topAnchor.constraint(equalTo: view.layoutMarginsGuide.bottomAnchor, constant: -58)
    bottomConstraint.isActive = true

    UIView.animate(withDuration: 0.5, delay: 0.2, animations: {
        self.undoView.layoutIfNeeded()
    })
}

我希望仅在可见视图下方创建视图,然后在底部布局边距上方向上滑动 8。然而,此代码只是使视图 'expand' 位于其最终位置,而不是从底部进入视图。由于某种原因,使用 self.view.layoutIfNeeded() 会使视图从屏幕的左上角飞入。

你好 我通常使用变换 属性 将一个视图从 x 位置移动到 y 部分,请查看此示例。


class ViewController: UIViewController {

    let button : UIButton = {
        let button = UIButton(type: .custom)
        button.setTitle("Button", for: .normal)
        button.backgroundColor = .gray
        button.translatesAutoresizingMaskIntoConstraints = false
        return button
    }()

    let customView : UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = .red
        return view
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        view.addSubview(button)
        view.addSubview(customView)
        NSLayoutConstraint.activate([
            button.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
            button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            customView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
            customView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
            customView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
            customView.heightAnchor.constraint(equalToConstant: 100)
        ])
    }
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        setupAnimationCustomView()
    }

    private func setupAnimationCustomView(){
        UIView.animate(withDuration: 1, delay: 0 , options: .curveEaseOut, animations: {
            print(self.button.frame.origin.y)
            let translationY = self.view.frame.height - self.button.frame.origin.y - self.button.frame.height - self.customView.frame.height - 8
            self.customView.transform = CGAffineTransform(translationX: 0, y:  translationY * (-1))

        }, completion: nil)
    }

}


在动画上我计算了我需要移动 customView 的距离。