Animate UILabel resizing from center?

北城以北 提交于 2019-12-13 05:32:00

问题


I want to resize my label from center and animate that process. However, the only option I can use there is CGAffineTransformMakeScale with default anchor point of corresponding CALayer.

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

But it squished the text inside. I considered this answer and it looks like the problem is solved in Swift.

However, I can't modify only size part of the frame. How to approach this in Obj C?


回答1:


This will work for you. You just need to give scale for width and height (default 1, which will have no effect). And this will animate your view's frame and set it back to the original.

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

If you dont want revert effect than you can do like this

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



回答2:


From what I understood you want to change the size of UILabel not the text via animation. This can be achieved by grabbing a copy of the current label's frame and then modify it and set it back.

i.e

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

Solution

Code

For the sizeTranformAction: you can a simple button and connect it to test the behavior.

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)
    }
}

Output




回答3:


I actually ended up with 2 labels. Animation sequence is following:

  • Create a temporary label with no text in it, attributes like bg color, font, font size, etc should be the same as of your main label.

  • Place the temporary label above your main label. Set main label's text property to nil

  • Animate the frame of main label to a desired value
  • When animation finishes, set back main label's text property to original value (presumably, in completion handler of animateWithDuration:)
  • Hide temporary label / remove it at all



回答4:


You can change your constant to compensate the new width after scaling. Would this help?

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)


来源:https://stackoverflow.com/questions/36285732/animate-uilabel-resizing-from-center

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!