Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
379 views
in Technique[技术] by (71.8m points)

ios - Why are animations on bounds of an UILabel only working when increasing the size?

I noticed that when i change the bounds of an UILabel in an animation block it only works if i increase the size, when i decrease the size the UILabel just changes his size but doesn't animate. Replacing the UILabel with a plain UIView works as intended.

Note: Changing the contentMode property of the UILabel to UIViewContentModeScaleToFill fixes this issue, but i still don't understand why it works when increasing the size without changing the contentMode property.

#import "FooView.h"

@interface FooView ()
@property (strong, nonatomic) UILabel   *label;
@property (assign, nonatomic) BOOL       resized;
@end

@implementation FooView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor lightGrayColor];

        self.label = [[UILabel alloc] initWithFrame:(CGRect){0, 0, frame.size}];
        self.label.backgroundColor = [UIColor greenColor];
        [self addSubview:self.label];
        _resized = false;

        UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(changeSize)];
        tapRecognizer.numberOfTapsRequired = 1;
        [self addGestureRecognizer:tapRecognizer];
    }
    return self;
}

- (void)changeSize {
    [UIView animateWithDuration:0.8
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseIn
                     animations:^{
                         CGRect bounds = self.label.bounds;
                         if (self.resized) {
                             bounds.size.height *= 2;
                             bounds.size.width  *= 2;
                         } else {
                             bounds.size.width  /= 2;
                             bounds.size.height /= 2;
                         }
                         self.label.bounds = bounds;
                     }
                     completion:^(BOOL finished) {
                         self.resized = !self.resized;
                     }];
}

@end
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

It's because UILabel sets its layer's contentsGravity to the direction text is being rendered, which happens to default to UIViewContentModeLeft (or @"left"). Thus, when the layer is told to animate, it first takes a glance at its contents gravity and bases subsequent animations on that. Because it sees @"left" where there should be @"resize", it assumes that the scaling animation should begin from the left, but it also has to respect the constraints you've given it (the bounds changes), so your label appears to jump into its final size then settle where it should in the center of the screen.

If you want to leave contentMode alone, use CATransform3D's and scale the label's layer that way instead of a bounds change.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...