Resize uiview with UILabel and animate it correctly

I have a UIView as a container with a UILabel inside:

------------- --------- | | | | |Label text | |Label..| | | --> | | | | | | | | | | ------------- --------- 

Now when I use:

UIView animateWithDuration:animations:

and try to set a smaller width of the UIView (which contains the UILabel), then during the animation the UILabel will suddenly replace "..." without having a smooth transition to it. I am setting up an autoresizingmask UILabel for UIViewAutoresizingFlexibleWidth, UIViewAutoresizingFlexibleRightMargin to keep it to the left and set the content to the left.

Trying to use a different content mode, such as: Scale to fill, Aspect fits, The fill aspect does not solve my problem, as they scale the text, and then it looks weird.

Does anyone have an idea how to achieve a smooth transition for UILabel?

+4
source share
4 answers

I animated my label as described some time ago, but you should put some features into it. Main idea: - Add a shortcut to the content list using clipToBounds: YES. - Do not animate the label frame, but do not create a frame with the contents, so your shortcut will have a smooth transition. - Use a separate label for Elipsis (...) so you can animate this part.

+5
source

Unfortunately, labels do not scale; changing its frame changes where the text is, but the size of the text does not scale in this way. Thus, the main animation is missing, an alternative is to turn off the timer, which compresses the label frame by a predetermined amount each time the timer fires.

Of course, you'll want to set the label properties of setAdjustsFontSizeToFitWidth to YES .

NOTE. . If possible, avoid actually starting the timer every 5/1000 seconds.

 - (void)fireTimer { timer = [NSTimer scheduledTimerWithTimeInterval:0.005 target:self selector:@selector(animate) userInfo:nil repeats:YES]; } - (void)animate { [label setAdjustsFontSizeToFitWidth:YES]; if (label.frame.size.width > 100) { [label setFrame:CGRectMake(label.frame.origin.x, label.frame.origin.y, label.frame.size.width-1, label.frame.size.height)]; }else{ [timer invalidate]; timer = nil; } } 
0
source

I had a similar problem when resizing UILabel during autorotation and solving it using CADisplayLink like this.

First call displayLinkTimer in the willAnimateRotationToInterfaceOrientation method.

 displayLinkTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(resizeTextLabel)]; [displayLinkTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 

Then resize the label by resizing it at the same speed as the invisible UIView that I created using textView. The TextView has a frame identical to what I want my UILabel frame to be and its size is changed in the willAnimateRotationToInterfaceOrientation method. I was able to resize at the same speed by accessing the textView presentationLayer.

 - (void)resizeTextLabel{ if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) { if (textLabel.frame.size.width < textView.frame.size.width -20) { textLabel.frame = CGRectMake(0, 0, [[textView.layer presentationLayer] frame].size.width, [[textView.layer presentationLayer] frame].size.height); }else{ [timer invalidate]; timer = nil; } } else{ if (textLabel.frame.size.width > textView.frame.size.width -20) { textLabel.frame = CGRectMake(0, 0, [[textView.layer presentationLayer] frame].size.width, [[textView.layer presentationLayer] frame].size.height); }else{ [timer invalidate]; timer = nil; } } } 

Hope this helps someone.

0
source

Old question, but it helped me:

  override var frame: CGRect { didSet { self.layoutSubviews() } } 
0
source

Source: https://habr.com/ru/post/1432872/


All Articles