Animate UIlabel Width with Fixed Center

Animate UILabel width with fixed center

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.

    UIView.animateWithDuration(2, delay: 0, options: UIViewAnimationOptions.BeginFromCurrentState, animations: { () -> Void in
self.textLabel.transform=CGAffineTransformMakeScale(3, 1);
}, completion: nil)

And if you don't want to stretch the content, than you may try this:

        UIView.animateWithDuration(2, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in

var newWidth:CGFloat = 200.0;

var oldWidth:CGFloat = self.textLabel.frame.width;

var totalChangeWidth:CGFloat = newWidth - oldWidth;

var newHeight:CGFloat = 200.0;

var oldHeight:CGFloat = self.textLabel.frame.width;

var totalChangeHeight:CGFloat = newHeight - oldHeight;

self.textLabel.bounds.size = CGSizeMake(self.textLabel.frame.size.width + totalChangeWidth, self.textLabel.frame.size.height + totalChangeHeight);

self.textLabel.center = CGPointMake(self.view.frame.width/2, self.view.frame.height/2)

}, completion:nil)

Autolayout Animation Keeping UILabel Centered

Add these constraints to your label:

(UIViewAutoresizingFlexibleLeftMargin   | 
UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleBottomMargin)

Animating a width change in a UIButton with a fixed center point

I've just tested this and it works perfectly:

// Button setup (to keep text central during animation)
button.titleLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;

// Animate
[UIView beginAnimations:nil context:nil];
CGRect old = button.frame;
CGFloat diff = 60;
button.frame = CGRectMake(old.origin.x-diff/2.0, old.origin.y, old.size.width+diff, old.size.height);
[UIView commitAnimations];

Animating from top and not center of intrinsic size

So, since it's a control that I wanted to create (checkbox) in this case with an error message, I manipulated the frames directly, based on the bounds. So to get it to work properly, I used a combination of overriding intrinsicContentSize and layoutSubviews and some minor extra stuff. The class contains a bit more than provided, but the provided code should hopefully explain the approach I went with.

open class Checkbox: UIView {

let imageView = UIImageView()
let textView = ThemeableTapLabel()
private let errorLabel = UILabel()
var errorVisible: Bool = false
let checkboxPad: CGFloat = 8

override open var bounds: CGRect {
didSet {
// fixes layout when bounds change
invalidateIntrinsicContentSize()
}
}

open var errorMessage: String? {
didSet {
self.errorVisible = self.errorMessage != nil
UIView.animate(withDuration: 0.3, animations: {
if self.errorMessage != nil {
self.errorLabel.text = self.errorMessage
}
self.setNeedsLayout()
self.invalidateIntrinsicContentSize()
self.layoutIfNeeded()
}, completion: { success in

if self.errorMessage == nil {
self.errorLabel.text = nil
}
})
}
}

func checkboxSize() -> CGSize {
return CGSize(width: imageView.image?.size.width ?? 0, height: imageView.image?.size.height ?? 0)
}

override open func layoutSubviews() {
super.layoutSubviews()

frame = bounds
let imageFrame = CGRect(x: 0, y: 0, width: checkboxSize().width, height: checkboxSize().height)
imageView.frame = imageFrame

let textRect = textView.textRect(forBounds: CGRect(x: (imageFrame.width + checkboxPad), y: 0, width: bounds.width - (imageFrame.width + checkboxPad), height: 10000), limitedToNumberOfLines: textView.numberOfLines)
textView.frame = textRect

let largestHeight = max(checkboxSize().height, textRect.height)
let rect = errorLabel.textRect(forBounds: CGRect(x: 0, y: 0, width: bounds.width, height: 10000), limitedToNumberOfLines: errorLabel.numberOfLines)
//po bourect = rect.offsetBy(dx: 0, dy: imageFrame.maxY)
let errorHeight = errorVisible ? rect.height : 0
errorLabel.frame = CGRect(x: 0, y: largestHeight, width: bounds.width, height: errorHeight)

}

override open var intrinsicContentSize: CGSize {
get {

let textRect = textView.textRect(forBounds: CGRect(x: (checkboxSize().width + checkboxPad), y: 0, width: bounds.width - (checkboxSize().width + checkboxPad), height: 10000), limitedToNumberOfLines: textView.numberOfLines)

let rect = errorLabel.textRect(forBounds: CGRect(x: 0, y: 0, width: bounds.width, height: 10000), limitedToNumberOfLines: errorLabel.numberOfLines)
let errorHeight = errorVisible ? rect.height : 0
let largestHeight = max(checkboxSize().height, textRect.height)
return CGSize(width: checkboxSize().width + 200, height: largestHeight + errorHeight)
}
}

public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}

func setup() {

//...
addSubview(imageView)
imageView.translatesAutoresizingMaskIntoConstraints = false

addSubview(textView)
textView.translatesAutoresizingMaskIntoConstraints = false
textView.numberOfLines = 0
contentMode = .top

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(checkboxTap(sender:)))
self.isUserInteractionEnabled = true
self.addGestureRecognizer(tapGesture)

addSubview(errorLabel)
errorLabel.contentMode = .top
errorLabel.textColor = .red
errorLabel.numberOfLines = 0

}
}

UILabel animating improperly

You could add an UIView and then add UILabel as its subview:

 UIView *view = [[UIView alloc] initWithFrame:CGRectMake(40, 20, 100, 50)];
[view setBackgroundColor:[UIColor blueColor]];
[self.view addSubview:view];

UILabel *label = [[UILabel alloc] init];
[label setText:@"Label Name"];
[label setBackgroundColor:[UIColor clearColor]];
[label setFont:[UIFont systemFontOfSize:17.0]];
[label setTextColor:[UIColor blackColor]];
[label setTextAlignment:NSTextAlignmentCenter];
[label sizeToFit];
[label setNumberOfLines:0];
[label setFrame:CGRectOffset(label.frame, (view.frame.size.width - label.frame.size.width)/2, (view.frame.size.height - label.frame.size.height)/2)];
[view addSubview:label];

[UIView animateWithDuration:3 animations:^{
[view setFrame:CGRectMake(40, 20, 200, 300)];
[label setFrame:CGRectMake((view.frame.size.width - label.frame.size.width)/2, (view.frame.size.height - label.frame.size.height)/2, label.frame.size.width, label.frame.size.height)];
} completion:^(BOOL finish){

}];

UILabel change height, animation expands from center

Faced same problem!
Try to set label' contentMode to Top in code:

label.contentMode = UIViewContentModeTop;

Is there a way to animate changing a UILabel's textAlignment?

Set the UILabel frame size to exactly contain the text and center the UILabel in your view.

self.monthLabel.text = @"February";
[self.monthLabel sizeToFit];
self.monthLabel.center = parentView.center; // You may need to adjust the y position

Then set the alignment which should not affect the layout since there will be no extra space.

self.monthLabel.textAlignment = NSTextAlignmentLeft;

Next, animate the UILabel frame size so it slides over where you want it.

[UIView animateWithDuration:0.5
animations:^{
CGRect frame = self.monthLabel.frame;
frame.origin.x = 10;
self.monthLabel.frame = frame;
} completion:nil];

Animating Frame of UILabel smoothly

Hooray for answering a two-year dead question, but I found the answer. Either in Interface Builder or in code, change the contentMode property of the label. Yours seems to be set on scaleToFill; try left or right.



Related Topics



Leave a reply



Submit