首页 > 解决方案 > 如何在屏幕外使用自动布局锚定位视图

问题描述

如何使用屏幕右侧的自动布局锚定位视图?我想稍后将其设置为中心位置。

func setup(){
    _ = firstNameTextField.anchor(nil, 
                                  left: view.leftAnchor, 
                                bottom: lastnameTextField.topAnchor, 
                                 right: view.rightAnchor, 
                           topConstant: 16, 
                          leftConstant: 16, 
                        bottomConstant: 8, 
                         rightConstant: 16, 
                         widthConstant: 0, 
                        heightConstant: 46)
}

标签: swiftanchornslayoutconstraint

解决方案


明确定义您的约束可能是有益的,而不是使用“帮助”函数......它可以让您更容易理解正在发生的事情。

也就是说,您希望将left字段的锚点限制在right视图的锚点上,这将使其“脱离屏幕”。然后,您可以更改它以将字段动画化到视图中......“从右侧滑入”。

为此,请创建一个“开始”约束和一个“结束”约束:

// starting constraint will be leading edge of field 16-pts to the right of view's right edge (off-screen)
firstNameLeadingConstraintStart = firstNameTextField.leadingAnchor.constraint(equalTo: view.trailingAnchor, constant: 16.0)

// ending constraint will be leading edge of field 16-pts from view's left edge
firstNameLeadingConstraintEnd   = firstNameTextField.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16.0)

要将其动画化:

    // de-activate starting constraint
    self.firstNameLeadingConstraintStart.isActive = false

    // activate ending constraint
    self.firstNameLeadingConstraintEnd.isActive = true

    // animate the change
    UIView.animate(withDuration: 0.75, animations: {
        self.view.layoutIfNeeded()
    })

这是一个基本的例子。它包括一个触发动画的按钮:

class SampleViewController: UIViewController {

    var firstNameTextField: UITextField = {
        let v = UITextField()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.borderStyle = .roundedRect
        v.backgroundColor = .orange  // to make it easy to see
        return v
    }()

    var button: UIButton = {
        let v = UIButton()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.setTitle("Tap Me", for: .normal)
        v.setTitleColor(.blue, for: .normal)
        return v
    }()

    // constraint for starting position of field
    var firstNameLeadingConstraintStart: NSLayoutConstraint!

    // constraint for ending position of field
    var firstNameLeadingConstraintEnd: NSLayoutConstraint!

    override func viewDidLoad() {

        view.addSubview(firstNameTextField)

        NSLayoutConstraint.activate([

            // top of field 16-pts from top of view
            firstNameTextField.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16.0),

            // width of field should be width of view minus 32 (16-pts padding on each side)
            firstNameTextField.widthAnchor.constraint(equalTo: view.safeAreaLayoutGuide.widthAnchor, constant: -32.0),

            // height of field 46-pts
            firstNameTextField.heightAnchor.constraint(equalToConstant: 46.0),

            ])

        // starting constraint will be leading edge of field 16-pts to the right of view's right edge (off-screen)
        firstNameLeadingConstraintStart = firstNameTextField.leadingAnchor.constraint(equalTo: view.trailingAnchor, constant: 16.0)

        // ending constraint will be leading edge of field 16-pts from view's left edge
        firstNameLeadingConstraintEnd   = firstNameTextField.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16.0)

        // activate the starting constraint
        firstNameLeadingConstraintStart.isActive = true

        // add a button so we can trigger the animation
        view.addSubview(button)
        NSLayoutConstraint.activate([
            button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            button.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            ])
        button.addTarget(self, action: #selector(didTap(_:)), for: .touchUpInside)
    }

    func animateField() -> Void {

        // de-activate starting constraint
        self.firstNameLeadingConstraintStart.isActive = false

        // activate ending constraint
        self.firstNameLeadingConstraintEnd.isActive = true

        // animate the change
        UIView.animate(withDuration: 0.75, animations: {
            self.view.layoutIfNeeded()
        })

    }

    @objc func didTap(_ sender: Any) {
        animateField()
    }

}

推荐阅读