Создать CATransition для UIView из текущего состояния - PullRequest
4 голосов
/ 20 августа 2011

Я пытаюсь сделать анимацию толчка с одной стороны, используя CATransition.Я делаю это в методе, который обрабатывает два UIViews, один для фона и другой для переднего плана.Анимированный UIView будет на переднем плане.Однако я не хочу, чтобы новый контент заменял старый, поэтому для этого я перемещаю весь старый контент с переднего плана на фон UIView, ожидая, что он просто оживит push-переход UIViewс одной стороны, но вместо этого он заменяет старый UIView.Есть ли способ сделать то, что я пытаюсь сделать, например, заблокировать состояние UIViews с того момента, когда передний план и фон 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];

Это то, что я сделал, и оно должно работать (согласно порталу разработчика Apple), но это не так, поэтому вопрос все еще открыт.

[править] После долгих испытаний и чтения я обнаружил, что проблема в том, что когда я удаляю представление из его суперпредставления, переход или анимация не распознают этоизменить позже, поэтому он реагирует устаревшими из последних изменений.Есть ли способ заставить обновление или проверить, когда removeFromSuperview или addSubview закончен?

[edit] Что мне нужно именно это: 1) текущее состояние UIViews: bgView со старыми представлениями за затененным UIView или midView (это представление не должно быть анимированным).MidView, который никогда не анимирован.FgView с текущим UIView.2) Я хочу переместить содержимое fgView в bgView (который не будет анимирован) и анимировать внешний вид нового UIView, который добавляется в fgView (с использованием анимации Slide, Fade in / out или Flip).

Ответы [ 2 ]

5 голосов
/ 29 августа 2011

Возможно, лучший способ - сделать «скриншот» вашего старого контента и добавить скриншот в качестве UIImageView, после чего вы можете изменить контент вашего UIView на новый.

После этого вы можете легкодобавьте анимацию к двум представлениям, и вам не нужно беспокоиться об изменении старого содержимого.

Вы можете добавить два файла ниже в свой проект и получить скриншот 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
3 голосов
/ 30 августа 2011
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];
...