8

単純な変換ベースのアニメーションを実行するアニメーション ブロックがあり、完了すると、問題のビューがスーパービューから削除されます。

UIView *msgView = [[UIView alloc] initWithFrame:CGRectMake(160, 120, 160, 100)];

// Do stuff to set up the subviews of msgView.

// Add the msgView to the superview (ViewController) that is going to display it.

CATransform3D transform = CATransform3DMakeScale(2.5, 2.5, 1.0);

[UIView animateWithDuration:5.0 
                 animations:^(void){msgView.layer.transform = transform;}
                 completion:^(BOOL finished){[msgView removeFromSuperview];}];

次に、Tech Q&A 1673 http://developer.apple.com/library/ios/#qa/qa1673/_index.htmlで詳しく説明されているコードを使用して 、アニメーションを一時停止します。

-(void)pauseLayer:(CALayer*)layer
{
    CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
    layer.speed = 0.0;
    layer.timeOffset = pausedTime;
}

-(void)resumeLayer:(CALayer*)layer
{
    CFTimeInterval pausedTime = [layer timeOffset];
    layer.speed = 1.0;
    layer.timeOffset = 0.0;
    layer.beginTime = 0.0;
    CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
    layer.beginTime = timeSincePause;
}

ただし、このコードは完了コードの実行を妨げません。したがって、コードが実行されないようにするために、完了のコードを次のように変更します。

completion:^(BOOL finished){if(finished == TRUE)[msgView removeFromSuperview];};

finished == TRUE をチェックしている間、アニメーション ブロックが一時停止している間、完了コードが実行されるのを防ぎます。アニメーションを「一時停止解除」する前に継続時間を超えた場合、完了コードは実行されません。つまり、この場合、msgView はスーパービューに残ります。

完了コードに関連付けられたアニメーションとタイマーの両方を一時停止/一時停止解除する方法はありますか (それが起こっている場合)?

4

1 に答える 1

5

上記のコメントで述べたように、問題はないようです。以下は、iOS 5.1 および 6.1 でテストされています。

と で絵コンテを作成しUIImageView *transViewますUIButton *trigger。クラスは次のとおりです。

TSTViewController.h:

@property (weak, nonatomic) IBOutlet UIImageView *transView;
@property (weak, nonatomic) IBOutlet UIButton *trigger;
@property (nonatomic) NSUInteger bState;

- (IBAction)didPressTrigger:(id)sender;

TSTViewController.m:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.bState = 0;    // 0 is initial state
                        // 1 is transform being animated
                        // 2 is transform paused
                        // 3 is transform ended
}

- (IBAction)didPressTrigger:(id)sender {
    switch (self.bState) {
        case 0:
        {
            CATransform3D transform = CATransform3DMakeScale(2.5, 2.5, 1.0);
            self.bState++;
            [UIView animateWithDuration:5.0
                             animations:^(void){self.transView.layer.transform = transform;}
                             completion:^(BOOL finished){
                                 self.bState = 3;
                                 NSLog(@"Done");
                             }];
            break;
        }
        case 1:
        {
            self.bState++;
            [self pauseLayer:self.transView.layer];
            break;
        }
        case 2:
        {
            self.bState = 1;
            [self resumeLayer:self.transView.layer];
            break;
        }
        case 3:
        {
            [UIView animateWithDuration:0 animations:^(void){self.transView.layer.transform = CATransform3DIdentity;}
                             completion:^(BOOL finished) {
                                 self.bState = 0;
                                 NSLog(@"Reset");
                             }];
            break;
        }
        default:
            break;
    }
}

-(void)pauseLayer:(CALayer*)layer
{
    CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
    layer.speed = 0.0;
    layer.timeOffset = pausedTime;
}

-(void)resumeLayer:(CALayer*)layer
{
    CFTimeInterval pausedTime = [layer timeOffset];
    layer.speed = 1.0;
    layer.timeOffset = 0.0;
    layer.beginTime = 0.0;
    CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
    layer.beginTime = timeSincePause;
}

トリガーボタンを押すとアニメーションが始まります。もう一度押すと、アニメーションが停止します。10 秒待ってから、もう一度ボタンを押します。アニメーションは継続して終了し、「完了」と記録されます。

于 2013-03-01T06:58:12.003 に答える