1

希望您能提供帮助或解释这里发生了什么,因为我不擅长UIGraphics上下文。

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

它由一个适合父视图中分配空间的滚动视图组成,并包含一个UILabel大小适合其文本的(子类)。(UILabel 是父滚动视图中的子视图)。

滚动视图提交一个动画,该动画将 UILabel 向左-> 向右滚动,然后当动画完成时,我触发委托'

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

这会重置一些数字并重新启动动画,将其反向滚动到右 -> 左

这真的很好用。

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

我尝试了以下方法来隔离动画的触发,但没有积极的结果。将视图上下文和标识符传递给 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];
    }
}
}

编辑:添加 28/5/14 @ 13: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];
}
4

1 回答 1

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];
}
于 2014-04-28T20:28:12.590 回答