希望你能帮助或解释这里发生的事情,因为我对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];
}
答案 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];
}