2013-07-12 2 views
2

В iPhone-приложении, как бы вы анимировали форму UIView, например, меняя прямоугольник на круг?Анимация формы UIView и ее содержимого

Я попытался с:

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"]; 
animation.duration = 20.0; 
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
animation.fromValue = (__bridge_transfer id)aPath; 
animation.toValue = (__bridge_transfer id)anotherPath; 
[myShapeLayer addAnimation:animation forKey:@"animatePath"]; 

где myShapeLayer является экземпляром CAShapeLayer и aPath и anotherPathCGMutablePathRef. Работает, но контент просмотра также не анимирован.

Мне нужно преобразовать вид в круг, а затем позволить ему сжиматься, пока он не исчезнет.

ответ

3

Попробуйте что-то вроде этого: Где animeView твой UIView

CABasicAnimation *anim1 = [CABasicAnimation animationWithKeyPath:@"cornerRadius"]; 
anim1.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 
anim1.fromValue = [NSNumber numberWithFloat:0.0f]; 
anim1.toValue = [NSNumber numberWithFloat:50.0f]; //Half the size of your UIView 
anim1.duration = 2.0; 
[animeView.layer addAnimation:anim1 forKey:@"cornerRadius"]; 

[UIView animateWithDuration:10.0 delay:2 options:UIViewAnimationOptionCurveEaseInOut animations:^{ 

    animeView.layer.cornerRadius = 50; //Half the size of your UIView 
    CGRect reduceRect = animeView.frame; 
    reduceRect.size.height = 0; 
    reduceRect.size.width = 0; 
    [animeView setFrame:reduceRect]; 
    animeView.alpha = 0; 
        } completion:nil]; 

может понадобиться твики для вас здесь и там ;-)

EDIT 1:

ИТАК как об использовании два UIView animations? Первый будет shrink, strech и move ваш вид. Второй будет shrink, slink и remove ваш вид.

[UIView animateWithDuration:2.0 delay:0.5 options:UIViewAnimationOptionCurveEaseIn animations:^{ 

    CGRect moveRect = animeView.frame; 
    moveRect.origin.x = 0; 
    moveRect.origin.y = (animeView.center.y -20); //Half the size of height reduction 
    moveRect.size.height = (animeView.bounds.size.height -40); // height reduction 
    moveRect.size.width = (animeView.bounds.size.width +20); 
    [animeView setFrame:moveRect]; 

} completion:^(BOOL finished){ 
    [UIView animateWithDuration:2.0 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{ 
     CGRect reduceRect = animeView.frame; 
     reduceRect.size.height = 0; 
     reduceRect.size.width = 0; 
     reduceRect.origin.x = -50; 
     reduceRect.origin.y = animeView.center.y; 
     animeView.alpha = 0; 
     [animeView setFrame:reduceRect]; 
    } completion:nil]; 

}]; 

EDIT 2:

ответ на свой вопрос в комментариях:

Вы можете выполнить анимацию одновременно, создавая CAAnimationGroup. Также я использую изображение для создания эффекта resize of content. Пример:

//Create a screenshot of your UIView... Still animeView in this example 
UIGraphicsBeginImageContext(animeView.bounds.size); 
CGContextRef context = UIGraphicsGetCurrentContext(); 
[animeView.layer renderInContext:context]; 
UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

//Add the image as subview: 
UIImageView * imageView = [[UIImageView alloc] initWithImage:screenShot]; 
[animeView addSubview:imageView]; 

//A cornerRadius animation: 
CABasicAnimation *radiusAni = [CABasicAnimation animationWithKeyPath:@"cornerRadius"]; 
radiusAni.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 
radiusAni.fromValue = [NSNumber numberWithFloat:0.0f]; 
radiusAni.toValue = [NSNumber numberWithFloat:50.0f]; 

//A stretch animation: 
CABasicAnimation *stretchAni = [CABasicAnimation animationWithKeyPath:@"transform.scale.x"]; 
stretchAni.fromValue = [NSNumber numberWithDouble:1]; 
stretchAni.toValue = [NSNumber numberWithDouble:(animeView.frame.size.width+100)/animeView.frame.size.width]; 

//A slide animation: 
CABasicAnimation *slideAni = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"]; 
slideAni.fromValue = [NSNumber numberWithDouble:0]; 
slideAni.toValue = [NSNumber numberWithDouble:-100]; 

//A opacity animation: 
CABasicAnimation *opacityAni = [CABasicAnimation animationWithKeyPath:@"opacity"]; 
opacityAni.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 
opacityAni.fromValue = [NSNumber numberWithFloat:1]; 
opacityAni.toValue = [NSNumber numberWithFloat:0]; 

//The animationgroup 
CAAnimationGroup *animGroup = [CAAnimationGroup animation]; 

//Add them to the group: 
[animGroup setAnimations:[NSArray arrayWithObjects:radiusAni, opacityAni, slideAni, stretchAni, nil]]; 
//Set the properties: 
[animGroup setDuration:3.0]; 
[animGroup setRemovedOnCompletion:NO]; 
[animGroup setFillMode:kCAFillModeForwards]; 

//Execute all the animations in the group: 
[animeView.layer addAnimation:animGroup forKey:nil]; 

Тогда вы будете иметь 4 анимации выполняющиеся в то же время и изменение размеров содержания при растяжении, усадка или все, что вы собираетесь делать ;-)

+0

Hi wkberg, благодарит за ваш быстрый ответ! На самом деле я упростил свою задачу слишком много, на самом деле анимация довольно сложна, а морфинг из прямоугольника в круг был просто (плохим) примером. Мне нужно смоделировать анимацию, где вид, который имеет форму стрелы, всасывается в отверстие. Чтобы достичь этого, я подумывал о создании набора кривых безье, которые представляют форму представления, а затем пусть кварц оживит друг от друга. Результат должен быть очень похож на растягивание, чтобы обновить анимацию, такую ​​как почта в iOS6, но, как сказано, что анимация вида имеет некоторое содержимое. – DAN

+0

Добро пожаловать ;-) Так на самом деле вы создаете дыру. протягивая стрелу к ней. Переместите его в отверстие как «всасывание», где оно «всасывается». Как в движении к отверстию, а затем удалены или просто не видно? – wkberg

+0

Я попытался набросать свою идею, вот результат: http://img59.imageshack.us/img59/8690/t6au.jpg Отверстия - это круги слева, а виды, которые нужно анимировать, - это стрелки справа. Надеюсь, это ясно :) – DAN

0

Если вы хотите анимировать изменения формы вы можете использовать CAShapeLayer. Это берет CGPath, который описывает форму, которую нужно нарисовать. Он может рисовать только один путь, и этот рисунок может использовать только один цвет линии и один цвет заливки. Вы не можете нарисовать некоторые строки в цвете 1 и другие строки в цвете 2 и т. Д.

После того, как у вас есть CAShapeLayer, вы можете анимировать изменения объекта CGPath, связанного с слоем фигуры. Уловка для его работы заключается в том, что начальный и конечный CGPath должен иметь одинаковое количество контрольных точек. Если вы используете путь с тремя связанными контурами безье, конечный путь должен также использовать 3 связанных пути безье, но вы можете перемещать точки вокруг столько, сколько хотите.

Я нашел в эксперименте, что вы не можете анимировать изменения дуг в кривых Безье. Причина в том, что внутри, система создает ряд кривых Безье для создания дуги, и есть больше сегментов безье, чем больше угол дуги.