代码之家  ›  专栏  ›  技术社区  ›  pajevic

UILabel大小更改不会使用自动布局设置动画

  •  2
  • pajevic  · 技术社区  · 8 年前

    我有一个动态宽度 UILabel (灰绿色表示可见性),对相邻视图(绿色和红色视图)具有固定的前导和尾随约束。我想让这张桌子在它的一个邻居被移动时调整它的宽度(圆形的红色/绿色视图)。但是,我对这种更改的动画有一个问题,因为我的标签的宽度“跳”到它的新值而没有动画。对于我的右对齐标签,这意味着文本本身也会跳转。

    enter image description here

    我正在为红色/绿色视图的移动设置动画,如下所示:

    - (void)show {
        self.edgeConstraint.constant = 0;
        [UIView animateWithDuration:0.25 animations:^{
            [self.contentView layoutIfNeeded];
        }];
    }
    
    - (void)hide {
        self.edgeConstraint.constant = -100;
        [UIView animateWithDuration:0.25 animations:^{
            [self.contentView layoutIfNeeded];
        }];
    }
    
    1 回复  |  直到 8 年前
        1
  •  2
  •   beyowulf    8 年前

    问题在于 UILabel 内容模式。您看到了类似的问题 here . 因为要缩短绘制文本的标签,所以标签会进行绘制过程,但它会使用动画块的最后一帧进行更新。创建平滑动画的最简单方法是使用 greaterThanOrEqualTo 引导约束并设置 textAlignment .natural .

    当我这样做的时候,我得到了与设置一致的结果 文本对齐方式 .right 在底部。

    Screencast

    演示的源代码:

    import UIKit
    import PlaygroundSupport
    
    final class ViewController: UIViewController {
    
        var constraint: NSLayoutConstraint?
        var otherConstraint: NSLayoutConstraint?
    
        lazy private var sideView: UIView = {
            let view = UIView()
            view.translatesAutoresizingMaskIntoConstraints = false
            self.view.addSubview(view)
            view.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
            self.constraint = view.leadingAnchor.constraint(equalTo: self.view.trailingAnchor)
            self.constraint?.isActive = true
            view.widthAnchor.constraint(equalToConstant: 100).isActive = true
            view.heightAnchor.constraint(equalToConstant: 44).isActive = true
            view.backgroundColor = .yellow
            return view
        }()
    
        lazy private var secondSideView: UIView = {
            let view = UIView()
            view.translatesAutoresizingMaskIntoConstraints = false
            self.view.addSubview(view)
            view.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 44.0).isActive = true
            self.otherConstraint = view.leadingAnchor.constraint(equalTo: self.view.trailingAnchor)
            self.otherConstraint?.isActive = true
            view.widthAnchor.constraint(equalToConstant: 100).isActive = true
            view.heightAnchor.constraint(equalToConstant: 44).isActive = true
            view.backgroundColor = .yellow
            return view
        }()
    
        lazy private var label: UILabel = {
            let label = UILabel()
            label.text = "Label"
            label.translatesAutoresizingMaskIntoConstraints = false
            self.view.addSubview(label)
            label.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
            label.leadingAnchor.constraint(greaterThanOrEqualTo: self.view.leadingAnchor, constant: 8.0).isActive = true
            label.trailingAnchor.constraint(equalTo: self.sideView.leadingAnchor).isActive = true
            return label
        }()
    
        lazy private var secondLabel: UILabel = {
            let label = UILabel()
            label.textAlignment = .right
            label.text = "Label"
            label.translatesAutoresizingMaskIntoConstraints = false
            self.view.addSubview(label)
            label.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 44.0).isActive = true
            label.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 8.0).isActive = true
            label.trailingAnchor.constraint(equalTo: self.sideView.leadingAnchor).isActive = true
            return label
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            view.backgroundColor = .white
            self.secondSideView.isHidden = false
            self.secondLabel.isHidden = false
            self.sideView.isHidden = false
            self.label.isHidden = false
        }
    
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
            self.perform(#selector(self.showSideView), with: nil, afterDelay: 5.0)
        }
    
        @objc private func showSideView() {
            self.view.layoutIfNeeded()
            UIView.animate(withDuration: 1.5, delay: 0.0, options: [.autoreverse, .repeat], animations: {
                self.otherConstraint?.constant = -100
                self.constraint?.constant = -100
                self.view.layoutIfNeeded()
            })
        }
    }
    
    PlaygroundPage.current.liveView = ViewController()