【问题标题】:Animate UILabel resizing from center?动画 UILabel 从中心调整大小?
【发布时间】:2016-03-29 13:28:00
【问题描述】:

我想从中心调整标签大小并为该过程设置动画。但是,我可以使用的唯一选项是 CGAffineTransformMakeScale,其默认锚点为相应的 CALayer。

[UIView animateWithDuration:0.5 animations:^{
    self.title.transform = CGAffineTransformMakeScale(2.0,1.0);
}];

但它压扁了里面的文字。我考虑过这个answer,看起来问题在 Swift 中得到了解决。

但是,我不能只修改size 的一部分frame。如何在 Obj C 中解决这个问题?

【问题讨论】:

  • 您到底想实现什么?更改标签的框架大小?
  • @EridB 动画从中心改变标签的宽度

标签: ios objective-c xcode uilabel ios9


【解决方案1】:

这对你有用。您只需要为宽度和高度指定比例(默认为 1,这将无效)。这将为您的视图框架设置动画并将其设置回原始状态。

[UIView animateWithDuration:0.5
                  delay:0
                options:UIViewAnimationOptionBeginFromCurrentState
             animations:(void (^)(void)) ^{
                 self.textLabel.transform=CGAffineTransformMakeScale(3, 1);
             }
             completion:^(BOOL finished){
                 self.textLabel.transform=CGAffineTransformIdentity;
             }];

如果你不想恢复效果,那么你可以这样做

[UIView animateWithDuration:0.5
                  delay:0
                options:UIViewAnimationOptionBeginFromCurrentState
             animations:(void (^)(void)) ^{
                 self.textLabel.transform=CGAffineTransformMakeScale(3, 1);
             }
             completion:nil];

【讨论】:

  • 这与问题中的代码有何不同?
  • @efimovD 您没有为 UIViewAnimationOptionBeginFromCurrentState 提供选项,而答案提供了该选项。这就是区别。如果你想尝试,那么你可以,因为当我为swift问题写答案时,我最初是用obj-c写的,然后我将它转换为swift。
  • 这对我不起作用。你能附上一些 gif 来告诉我你得到了什么吗?
【解决方案2】:

据我了解,您想通过动画更改 UILabel 的大小而不是文本。这可以通过抓取当前标签帧的副本,然后对其进行修改并重新设置来实现。

var frame = self.myLabel.frame
// frame modification ...
self.myLabel.frame = frame

解决方案

代码

对于sizeTranformAction:,您可以使用一个简单的按钮并将其连接以测试其行为。

class SizeTransformViewController: UIViewController {
    var myLabel: UILabel! = nil

    // MARK: - View lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self.setupLabel()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Setups

    func setupLabel() {
        self.myLabel = UILabel()
        self.myLabel.center = self.view.center
        self.myLabel.text = "Text"
        self.myLabel.sizeToFit()

        self.myLabel.textAlignment = NSTextAlignment.Center
        self.myLabel.backgroundColor = UIColor.redColor()

        self.view.addSubview(self.myLabel)
    }

    // MARK: - Actions

    @IBAction func sizeTranformAction(sender: AnyObject) {
        var frame = self.myLabel.frame
        let size = frame.size
        frame.size = CGSize(width: 2*size.width, height: size.height)
        frame.origin.x = self.view.center.x - size.width

        UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveLinear, animations: { 
            self.myLabel.frame = frame
        }, completion: nil)
    }
}

输出

【讨论】:

  • 嗯,我想从中心拉伸它的原因是我想避免你得到的抽搐。在所有动画期间,文本必须与中心对齐。否则看起来很难看
  • 您可以为此创建自定义视图,因为标签等待设置框架,然后设置 textAligment,从而导致此行为
  • @efimovD 或者另一种方法是在过渡期间隐藏文本,然后在动画完成时显示它。
  • 感谢您的帮助,@EridB。不,实际上这会产生不希望的闪烁。还是谢谢你!
【解决方案3】:

我实际上最终得到了 2 个标签。动画序列如下:

  • 创建一个没有文本的临时标签,属性如 bg 颜色、字体、字体大小等应与您的主标签相同。

  • 将临时标签放在主标签上方。将主标签的文本属性设置为 nil

  • 将主标签的框架设置为所需的值
  • 动画结束后,将主标签的文本属性设置回原始值(大概在animateWithDuration:的完成处理程序中)
  • 隐藏临时标签/完全删除它

【讨论】:

    【解决方案4】:

    您可以更改常量以在缩放后补偿新宽度。这会有帮助吗?

    layoutIfNeeded()
    
    let scale: CGFloat = 0.72
    
    let consLeft = NSLayoutConstraint(
        item: titleLabel,
        attribute: .left,
        relatedBy: .equal,
        toItem: self,
        attribute: .left,
        multiplier: 1,
        constant: titleLabel.frameWidth * -(1-scale)/2
      )
    
    consLeft.isActive = true
    
    let animations = {
      self.titleLabel.transform = CGAffineTransform(scaleX: scale, y: scale)
      self.layoutIfNeeded()
    }
    UIView.animate(withDuration: 0.25, delay: 0, options: [.curveEaseOut],
                         animations: animations,
                         completion: nil)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-27
      • 1970-01-01
      • 1970-01-01
      • 2017-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-07
      相关资源
      最近更新 更多