林建设某种滚动标签,这基本上是一个包含我的动画标记一个UIView,造成孩子标签去来回如果文本比UIView的大;滚动的UILabel动画无法启动
@implementation ScrollLabel
static float DEFAULT_SPEED_IN_PIXELS_PER_SECOND = 30.0;
static float DEFAULT_ANIMATION_DELAY = 2.0;
#pragma mark - Properties
#pragma mark - Initialization and Memory Management
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
label1 = [[UILabel label] retain];
[label1 setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
[label1 setBackgroundColor:[UIColor clearColor]];
[label1 setNumberOfLines:1];
[self addSubview:label1];
speedInPixelsPerSecond = DEFAULT_SPEED_IN_PIXELS_PER_SECOND;
scrollAnimationDelay = DEFAULT_ANIMATION_DELAY;
scrollType = theScrollType;
//[self setBackgroundColor:[UIColor greenColor]];
[self setClipsToBounds:YES];
return self;
}
- (void)dealloc
{
[label1 release];
[super dealloc];
}
#pragma mark - Public Static Methods
#pragma mark - Public Instance Methods
// Implement this method if you need more precise control over the layout of your subviews than the autoresizing behaviors provide.
- (void)layoutSubviews
{
[super layoutSubviews];
[self setLabelSize];
[self checkToStartOrStopAnimating];
}
- (void)setText:(NSString *)text
{
if(text == [label1 text]) return;
[self stopAnimating];
[label1 setText:text];
[self setNeedsLayout];
scrollAnimationDelay = DEFAULT_ANIMATION_DELAY;
}
- (void)checkToStartOrStopAnimating
{
if ([self shouldAnimate])
{
[self startAnimating];
}
else
{
[self stopAnimating];
}
}
- (void)setLabelSize
{
[label1 sizeToFit];
[label1 setFrame:CGRectMake(0, 0, [label1 frame].size.width, [label1 frame].size.height)];
}
- (void)startAnimating
{
if (!animating)
{
animating = YES;
[self animateForwards];
}
}
- (void)stopAnimating
{
if(animating)
{
animating = NO;
[[label1 layer] removeAllAnimations];
}
}
- (BOOL)isAnimating
{
return animating;
}
#pragma mark - Private Methods
- (void)animateForwards
{
float distanceToTravel = [label1 frame].size.width - [self frame].size.width;
if(distanceToTravel > 0 && animating)
{
CGRect rect = [label1 frame];
[UIView animateWithDuration:distanceToTravel/speedInPixelsPerSecond
delay:scrollAnimationDelay
options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveLinear
animations:^(void)
{
[label1 setFrame:CGRectMake(rect.size.width - self.size.width, 0, rect.size.width, rect.size.height)];
}
completion:^(BOOL finished)
{
scrollAnimationDelay = DEFAULT_ANIMATION_DELAY;
if(finished)
{
[self animateBackwards];
}
else
{
[self stopAnimating];
[self setNeedsLayout];
}
}];
}
else
{
[self stopAnimating];
[self setNeedsLayout];
}
}
- (void)animateBackwards
{
float distanceToTravel = [label1 frame].size.width - [self frame].size.width;
if (distanceToTravel > 0 && animating)
{
CGRect rect = [label1 frame];
[UIView animateWithDuration:distanceToTravel/speedInPixelsPerSecond
delay:scrollAnimationDelay
options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveLinear
animations:^(void)
{
[label1 setFrame:CGRectMake(0, 0, rect.size.width, rect.size.height)];
}
completion:^(BOOL finished)
{
if (finished)
{
[self animateForwards];
}
else
{
[self stopAnimating];
[self setNeedsLayout];
}
}];
}
else
{
[self stopAnimating];
[self setNeedsLayout];
}
}
- (BOOL) shouldAnimate
{
return [label1 frame].size.width > [self frame].size.width && [self frame] > 0.0;
}
@end
动画运行时除外(即当文本占用更多的空间比容器的观点是宽),如果你改变了文本到别的东西,也占用了更多的空间比容器的观点是不知何故,事情正在回归到某种状态,其中所有的动画以finish = NO结束(即使标签和父视图具有正确的大小),这当然又导致layoutSubviews被调用,反过来导致动画重新开始,并以finish = NO结束。 请注意,当文本实际符合父级的框架时,不会发生这种情况。
林几乎一无所知到为什么会发生;我可以很明显地猜出设置文本后没有正确设置,但我无法弄清楚是什么。 Asked in a more general form,但当然没有确凿的答案。