4

を使用して片側からプッシュアニメーションを作成しようとしていCATransitionます。UIViewsこれは、背景用と前景用の2つを処理するメソッドで行います。アニメーションUIViewは前景になります。ただし、新しいコンテンツで古いコンテンツを置き換えたくないので、これを行うために、すべての古いコンテンツをフォアグラウンドからバックグラウンドに移動します。これは、一方の側からUIViewのプッシュトランジションをアニメーション化するだけUIViewで、代わりに古いものを置き換えますUIViewUIViews前景と背景UIViewsに適切なコンテンツが含まれている瞬間からの状態をロックするなど、私がやろうとしていることを実行する方法はありますか?

私のコードは次のようなものです:

UIView *newView = argView; // argView is the view passed as a parameter to the method
// move views from foreground to background
for (UIView *v in [fgView subviews]) {
    [v removeFromSuperview];
    [bgView addSubview:v];
}

// Slide animation
CATransition *transition = [CATransition animation];
transition.duration = 0.5;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
[fgView.layer addAnimation:transition forKey:nil];
[fgView addSubview:newView];

[編集] 私はいくつかの研究を行ってきました。どうやら(または私が起こっていると思うこと)は、背景のUIViewsの削除が暗黙のアニメーションを採用していることです。アニメーション化を停止する方法はありますか?

[編集] 回答:はい、実行できます(暗黙のアニメーションを無効にします)。次のコードで実行できます。

[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
for (UIView *v in [fgView subviews]) {
    [v removeFromSuperview];
    [bgView addSubview:v];
}
[CATransaction commit];

これは私がしたことであり、(アップルの開発者ポータルによると)機能するはずですが、機能しないので、質問はまだ開いています。

[編集] 多くのテストと読み取りを行った結果、ビューをスーパービューから削除すると、トランジションまたはアニメーションがこの変更を認識しないため、最新の変更が古くなって応答することが問題であることがわかりました。更新を強制したり、removeFromSuperviewまたはaddSubviewがいつ終了したかを確認する方法はありますか?

[編集] 私が正確に必要としているのはこれです:1)UIViewsの現在の状態は次のとおりです:影付きのUIViewまたはmidViewの背後にある古いビューを持つbgView(このビューはアニメーション化されるべきではありません)。決してアニメーション化されないmidView。現在のUIViewを備えたfgView。2)fgViewのコンテンツをbgView(アニメーション化されない)に移動し、fgViewに追加された新しいUIViewの外観をアニメーション化します(スライド、フェードイン/アウト、またはフリップアニメーションを使用)。

4

2 に答える 2

5

おそらく、古いコンテンツの「スクリーンショット」を作成し、そのスクリーンショットをUIImageViewとして追加してから、UIViewのコンテンツを新しいコンテンツに変更するのがより良い方法です。

この後、2つのビューにアニメーションを簡単に追加でき、古いコンテンツが変更されることを心配する必要はありません。

以下の2つのファイルをプロジェクトに追加し、呼び出すことでUIViewのスクリーンショットを取得できます。UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageWithUIView:view]];

UIImageViewなので、ビューの内容が変更されることを心配する必要はありません。

UIImage + ImagewithUIView.h

@interface UIImage (UIImage+ImagewithUIView)
+ (UIImage *)imageWithUIView:(UIView *)view;
@end

UIImage + ImagewithUIView.m

@implementation UIImage (UIImage+ImagewithUIView)
#pragma mark -
#pragma mark TakeScreenShot
static CGContextRef createBitmapContext(int pixelsWide, int pixelsHigh)
{
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = (kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
    CGContextRef bitmapContext = CGBitmapContextCreate(nil, pixelsWide, pixelsHigh, 8, 0, colorSpace, bitmapInfo);
    CGColorSpaceRelease(colorSpace);

    return bitmapContext;
}

+ (UIImage *)imageWithUIView:(UIView *)view
{
    CGSize screenShotSize = view.bounds.size;
    CGContextRef contextRef = createBitmapContext(screenShotSize.width, screenShotSize.height);
    CGContextTranslateCTM (contextRef, 0, screenShotSize.height);
    CGContextScaleCTM(contextRef, 1, -1);

    [view.layer renderInContext:contextRef];
    CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);
    CGContextRelease(contextRef);

    UIImage *img = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    // return the image
    return img;
}
@end
于 2011-08-29T17:00:45.910 に答える
3
UIView *newView = argView; // argView is the view passed as a parameter to the method
// move views from foreground to background
[fgView.layer removeAllAnimations]; // make sure all, if any, animations are removed.
for (UIView *v in [fgView subviews]) 
{
    // [v removeFromSuperview]; // this should not be needed addSubview does it for you
    [bgView addSubview:v];
}

// Slide animation
CATransition *transition = [CATransition animation];
transition.duration = 0.5;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
transition.removedOnCompletion = YES; // force removal of animation when completed.
[fgView addSubview:newView];
[fgView.layer addAnimation:transition forKey:nil];
于 2011-08-29T22:22:15.350 に答える