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
Swift Xcode 7 Beta 5 Type Cannot Refer to Itself as a Requirement
iOS-Charts Error: Thread1: Exc_Bad_Access (Code=2, Address=0X2A0C220)
How to Prevent SQL Injections with User-Search-Terms in Vapor 4 (Fluent 4)
Pass and Print All Cases in an Enum in Swift
How to Change an Associated Value Within an Enum
How to Make First Responder in Swiftui Macos
Compiler Segmentation Fault While Using Set in Swift
Passing Data Between 2 View Controllers in Swift
Swift Unsafemutablepointer & Unsafemutablepointer<Unsafepointer<Sometype>>
How Does Swift Disambiguate Type Arguments in Expression Contexts
3 Component Dynamic Multi UIpickerview Swift
How to Set Default Clouse Param in View Method
How to Make Alamofire Post Request with "Form-Data" Parameters
Switch Statement Where Value Is Int But Case Can Contain Array