UIView beginAnimations在类的一个实例中触发相同类的另一个实例中的beginAnimations

时间:2014-04-28 09:23:33

标签: ios objective-c animation uiview beginanimations

希望你能帮助或解释这里发生的事情,因为我对UIGraphics情境并不是很好。

我已经定义了一个类,当标签文本对于视图控制器主视图上的给定空间来说很长时,它会自动在其框架中来回滚动标签。

它包含一个适合父视图中已分配空间的scrollview,并包含一个UILabel(子类),其大小适合它的文本。 (UILabel是父卷轴视图中的子视图)。

scrollview提交一个向左滚动UILabel的动画 - >是的,然后当动画结束时,我解雇代表'

(void)animationDidStop:animationID(NSString*)finished:(NSNumber *)finished context:(void *)context' 

重置某些数字并重新启动动画,向右反向滚动 - >左

这非常好用。

但是,如果我添加此滚动标签的另一个实例'在视图控制器主视图中的其他位置,当其中一个动画停止并且AnimationDidStop委托被触发时,它会从头开始重新启动动画,以便其他人滚动#39;标签对象。

我已尝试以下方法来隔离动画的触发而没有正面结果。 将视图上下文和标识符传递给beginAnimations,然后在(void)animationDidStop方法中捕获它们......没有任何区别。 这让我觉得这个方法似乎没有采取

下面是执行动画的代码,以及在另一个方向上重新启动动画的代码。

正如我所说的那样,它在它自己的工作中表现得非常好,但是当屏幕上同时存在超过1个这个类的实例时,这两个实例的beginAnimations似乎都会触发。

希望你能解释原因。感谢。

- (void)beginAnimationWithOrgigin:(CGPoint)origin Terminus:(CGPoint)terminus {


NSLog (@"Message %@ in context %@",((UILabel*)_textLabel).text,_ctx);

CGFloat text_width = ((UILabel*)_textLabel).frame.size.width;
CGFloat display_width = self.frame.size.width;

if ( text_width > display_width ) {
    float duration = (text_width - display_width)/40;
    [self setContentOffset:origin];

    [UIView beginAnimations:((UILabel*)_textLabel).text context:_ctx];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    [UIView setAnimationDelay:1.0];
    [UIView setAnimationDuration:duration];
    [UIView setAnimationRepeatCount:1];
    [self setContentOffset:terminus];

    [UIView commitAnimations];

}
}


- (void)animationDidStop:(NSString *)animationID
            finished:(NSNumber *)finished
             context:(void *)context
{

NSLog(@"Animation Did stop context = %@",context);

if ([animationID isEqualToString:((UILabel*)_textLabel).text]){

    static BOOL forward = NO;
    if ([finished boolValue]) {

        CGPoint origin;
        CGPoint terminal_origin;

        if (forward){
            origin = CGPointMake(0, 0);
            terminal_origin = CGPointMake(((UILabel*)_textLabel).frame.size.width - self.frame.size.width, ((UILabel*)_textLabel).frame.origin.y);
        }else{

            terminal_origin = CGPointMake(0, 0);
            origin = CGPointMake(((UILabel*)_textLabel).frame.size.width - self.frame.size.width, ((UILabel*)_textLabel).frame.origin.y);
        }

        forward = !forward;
        [self beginAnimationWithOrgigin:origin Terminus:terminal_origin];
    }
}
}

编辑:2014年4月28日14:14添加 在A-Lives建议使用静力学之后...修改了代码,使用它的标签作为标志来提示滚动方向的改变。 这已经解决了问题

- (void)beginAnimationWithOrgigin:(CGPoint)origin Terminus:(CGPoint)terminus Direction:(NSString*)direction{

if (!direction)direction = @"FORWARD";

NSLog (@"Message %@ in context %@",((UILabel*)_textLabel).text,_ctx);

CGFloat text_width = ((UILabel*)_textLabel).frame.size.width;
CGFloat display_width = self.frame.size.width;

if ( text_width > display_width ) {
    float duration = (text_width - display_width)/40;
    [self setContentOffset:origin];

    [UIView beginAnimations:direction context:_ctx];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    [UIView setAnimationDelay:1.0];
    [UIView setAnimationDuration:duration];
    [UIView setAnimationRepeatCount:1];
    [self setContentOffset:terminus];

    [UIView commitAnimations];

}
}



- (void)animationDidStop:(NSString *)animationID
            finished:(NSNumber *)finished
             context:(void *)context
{

NSLog(@"Animation Did stop context = %@",context);
NSString *direction;
CGPoint origin;
CGPoint terminal_origin;

    if (![animationID isEqualToString:@"FORWARD"]){
        origin = CGPointMake(0, 0);
        terminal_origin = CGPointMake(((UILabel*)_textLabel).frame.size.width - self.frame.size.width, ((UILabel*)_textLabel).frame.origin.y);
        direction = @"FORWARD";
    }else{

        terminal_origin = CGPointMake(0, 0);
        origin = CGPointMake(((UILabel*)_textLabel).frame.size.width - self.frame.size.width, ((UILabel*)_textLabel).frame.origin.y);
        direction = @"BACKWARD";
        }

[self beginAnimationWithOrgigin:origin Terminus:terminal_origin Direction:direction];
}

1 个答案:

答案 0 :(得分:0)

问题在于忘记静态实际上只是普通的C静态变量,它们可以在整个应用程序中全局访问。 (即,没有封装在定义它们的范围内。)

同一个类的多个实例都在读取和写入同一个变量的值,从而导致不可预测的行为。

解决方案:传递实例级别消息以控制切换活动,您无法保证您的课程是单身人士。

修改后的工作代码:

- (void)beginAnimationWithOrgigin:(CGPoint)origin Terminus:(CGPoint)terminus Direction:(NSString*)direction{

    if (!direction)direction = @"FORWARD";

    NSLog (@"Message %@ in context %@",((UILabel*)_textLabel).text,_ctx);

    CGFloat text_width = ((UILabel*)_textLabel).frame.size.width;
    CGFloat display_width = self.frame.size.width;

    if ( text_width > display_width ) {
        float duration = (text_width - display_width)/40;
        [self setContentOffset:origin];

        [UIView beginAnimations:direction context:_ctx];
        [UIView setAnimationDelegate:self];
        [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
        [UIView setAnimationDelay:1.0];
        [UIView setAnimationDuration:duration];
        [UIView setAnimationRepeatCount:1];
        [self setContentOffset:terminus];

        [UIView commitAnimations];

    }
}



- (void)animationDidStop:(NSString *)animationID
        finished:(NSNumber *)finished
         context:(void *)context
{

    NSLog(@"Animation Did stop context = %@",context);
    NSString *direction;
    CGPoint origin;
    CGPoint terminal_origin;

    if (![animationID isEqualToString:@"FORWARD"]){
        origin = CGPointMake(0, 0);
        terminal_origin = CGPointMake(((UILabel*)_textLabel).frame.size.width - self.frame.size.width, ((UILabel*)_textLabel).frame.origin.y);
        direction = @"FORWARD";
    }else{

        terminal_origin = CGPointMake(0, 0);
        origin = CGPointMake(((UILabel*)_textLabel).frame.size.width - self.frame.size.width, ((UILabel*)_textLabel).frame.origin.y);
        direction = @"BACKWARD";
        }

    [self beginAnimationWithOrgigin:origin Terminus:terminal_origin Direction:direction];
}