林建設某種滾動標籤,這基本上是一個包含我的動畫標記一個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,但當然沒有確鑿的答案。