更改其定位点时保持视图的位置

时间:2018-04-06 18:41:10

标签: ios swift uilabel nslayoutconstraint cgaffinetransform

我有一个以编程方式创建的UILabel并使用约束设置:

NSLayoutConstraint.activate([
            theLabel.topAnchor.constraint(equalTo: otherView.topAnchor),
            theLabel.leadingAnchor.constraint(equalTo: otherView.trailingAnchor, constant: otherView.frame.width/2),
            theLabel.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.5),
            theLabel.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.2),
])

然后我想把标签增加到场景中:

theLabel.transform = CGAffineTransform(scaleX: 0.0001, y: 0.0001)
theLabel.isHidden = false

UIView.animate(withDuration: 0.8, delay: 0.0, options: UIViewAnimationOptions(), animations: {
    self.theLabel.transform = CGAffineTransform(scaleX: 1.0, y: 1.0) //or CGAffineTransform.identity
}, completion: nil)

但是标签是左对齐的,它从中心开始增长,因此我更改了锚点以修复问题,但这导致标签出现在右侧,而不是应该出现。 (我明白这是因为我现在在视图的左侧描述它的位置而不再是中心的位置)

theLabel.layer.anchorPoint = CGPoint(x: 0.0, y: 0.5)

我在设置anchorPoint之后尝试更换它的框架及其中心点(另外,我首先尝试了框架,然后是中心)但这些解决方案都没有对应用程序中的视图显示方式产生任何影响:

let oldFrame = theLabel.frame
theLabel.layer.anchorPoint = CGPoint(x: 0.0, y: 0.5)
theLabel.frame = oldFrame

let oldCenter = theLabel.center
theLabel.layer.anchorPoint = CGPoint(x: 0.0, y: 0.5)
theLabel.center = oldCenter

任何其他建议或解释,以帮助我了解如何在更改其锚点时有效保留视图的位置?谢谢大家!

1 个答案:

答案 0 :(得分:2)

一种方法:将标签的前导约束保存在变量中,然后更改其常量以考虑anchorPoint中的更改。

你应该可以按原样运行它。点击按钮为标签设置动画。

class LabelTransformViewController: UIViewController {

    let btn: UIButton = {
        let b = UIButton()
        b.translatesAutoresizingMaskIntoConstraints = false
        b.setTitle("Tap Me", for: .normal)
        b.backgroundColor = .red
        return b
    }()

    let theLabel: UILabel = {
        let v = UILabel()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = UIColor.cyan
        v.text = "This is a label"
        return v
    }()

    let otherView: UIView = {
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = UIColor.yellow
        return v
    }()

    var leadingConstraint = NSLayoutConstraint()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor(red: 1.0, green: 0.85, blue: 0.5, alpha: 1.0)

        view.addSubview(btn)

        btn.addTarget(self, action: #selector(didTap(_:)), for: .touchUpInside)

        btn.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        btn.topAnchor.constraint(equalTo: view.topAnchor, constant: 20.0).isActive = true

        view.addSubview(otherView)

        NSLayoutConstraint.activate([
            otherView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100.0),
            otherView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20.0),
            otherView.widthAnchor.constraint(equalToConstant: 30.0),
            otherView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.2),
            ])

        view.addSubview(theLabel)

        NSLayoutConstraint.activate([
            theLabel.topAnchor.constraint(equalTo: otherView.topAnchor),
            theLabel.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.5),
            theLabel.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.2),
            ])

        leadingConstraint = theLabel.leadingAnchor.constraint(equalTo: otherView.trailingAnchor, constant: otherView.frame.width/2)
        leadingConstraint.isActive = true

        // presumably, you would start with theLabel hidden
        // but we're leaving it visible so we can see its original size and position
//      theLabel.isHidden = true

    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        // move the anchorPoint from the label frame's center (the default)
        // to the left edge, vertical center
        theLabel.layer.anchorPoint = CGPoint(x: 0.0, y: 0.5)

        // adjust the label's leading constraint by 1/2 of its width
        // to account for the anchorPoint change
        // need this in viewDidAppear so the frame is already set
        leadingConstraint.constant -= (theLabel.frame.size.width * 0.5)
    }

    @objc func didTap(_ sender: Any?) -> Void {

        theLabel.transform = CGAffineTransform(scaleX: 0.0001, y: 0.0001)
        theLabel.isHidden = false

        UIView.animate(withDuration: 0.8, delay: 0.0, options: UIViewAnimationOptions(), animations: {
            self.theLabel.transform = CGAffineTransform(scaleX: 1.0, y: 1.0) //or CGAffineTransform.identity
        }, completion: nil)

    }

}