私はUIGraphics
コンテキストが苦手なので、ここで何が起こっているのかを助けたり説明したりできることを願っています。
ビュー コントローラーのプライマリ ビューの指定されたスペースに対してラベル テキストが長すぎる場合に、フレーム内でラベルを自動的に前後にスクロールするクラスを定義しました。
親ビューに割り当てられたスペースに収まるスクロールビューで構成され、UILabel
テキストに合わせてサイズ変更された (サブクラス化された) が含まれています。(UILabel は親スクロールビューのサブビューです)。
scrollview は、UILabel を左 -> 右にスクロールするアニメーションをコミットし、アニメーションが終了したら、デリゲートを起動します '
(void)animationDidStop:animationID(NSString*)finished:(NSNumber *)finished context:(void *)context'
いくつかの数字をリセットし、逆方向にスクロールしてアニメーションを再開しました - >左
これは本当にうまく機能します。
ただし、この「スクロール ラベル」の別のインスタンスをビュー コントローラーのマスター ビューの別の場所に追加すると、アニメーションの 1 つが停止し、AnimationDidStop
デリゲートが起動されると、他の「スクロール」ラベル オブジェクトのアニメーションが最初から再起動されます。
アニメーションの発火を分離するために次のことを試みましたが、肯定的な結果は得られませんでした。ビューのコンテキストと識別子を beginAnimations に渡し、それらを(void)animationDidStop
メソッドにトラップします...違いはありませんでした。これは、メソッドがかからないように思われます
以下は、アニメーションを実行するコードと、アニメーションを別の方向に再起動するコードです。
私が言うように、それはそれ自体で非常にうまく機能しますが、同時に画面上に常駐するこのクラスの複数のインスタンスがある場合、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];
}