Пользовательский переход между двумя UIViews - PullRequest
6 голосов
/ 01 апреля 2011

У меня есть два вида «А» и «Б».Плавающая в середине окна (это не полный экран).B, вид, который заменит A, является полноэкранным.Я хотел бы написать собственный переход, который переворачивает A, чтобы показать B на обратной стороне, но одновременно масштабирует переворачивающийся прямоугольник так, чтобы, когда переворот закончился, B был на весь экран.

Я пытался использовать переворачивающиеся переходы, доступные с transitionFromView: toView: duration: options: завершение, но я могу только заставить его перевернуть весь экран вместо того, чтобы начинать переворачивание с кадра A и заканчивать кадром B.

Я знаю, что могу делать 3D-подобные преобразования для слоев вида, но я не уверен, какой набор API анимации мне следует использовать для достижения этой цели.Одна вещь, которую я попытался, - это изменить свойства слоя представления в блоке анимации transitionWithView: duration: options: animations: завершение: но это не сработало, так как кажется, что только изменения свойств представления.

Может кто-тоуказать мне в правильном направлении?Я был бы очень признателен.

ОБНОВЛЕНИЕ: Вот мой код на данный момент для этого эффекта.Вы можете посмотреть видео о том, что он делает здесь: http://www.youtube.com/watch?v=-xNMD2fGRwg

</p> <pre><code>CGRect frame = [[UIApplication easybookDelegate] rootViewController].view.bounds ; float statusHeight = [UIApplication sharedApplication].statusBarFrame.size.height ; frame.origin.y = statusHeight ; frame.size.height -= statusHeight ; self.view.frame = frame ; // self.view is view "B" // Put the snapshot as thet topmost view of our view UIImageView *imageView = [[UIImageView alloc] initWithImage:image] ; // image is a snapshot of view "A" imageView.frame = self.view.bounds ; [self.view addSubview:imageView] ; [self.view bringSubviewToFront:imageView] ; // Pre-transform our view (s=target/current, d=target-current) CGAffineTransform transform = CGAffineTransformIdentity ; // Translate our view CGPoint center = CGPointMake(screenOrigin.x + (image.size.width/2.0), screenOrigin.y + (image.size.height/2.0)) ; float dX = center.x - self.view.center.x ; float dY = center.y - self.view.center.y ; NSLog( @"dx: %f, dy: %f" , dX, dY ) ; transform = CGAffineTransformTranslate(transform, dX, dY) ; // Scale our view float scaleWFactor = image.size.width / self.view.frame.size.width ; float scaleHFactor = image.size.height / self.view.frame.size.height ; transform = CGAffineTransformScale(transform,scaleWFactor, scaleHFactor) ; self.view.transform = transform ; [[[UIApplication easybookDelegate] rootViewController].view addSubview:self.view] ; // Perform the animation later since implicit animations don't seem to work due to // view "B" just being added above and hasn't had a chance to become visible. Right now // this is just on a timer for debugging purposes. It'll probably be moved elsewhere, probably // to view "B"'s -didMoveToSuperview double delayInSeconds = 0.3; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ [UIView transitionWithView:self.view duration:3 options:UIViewAnimationOptionTransitionFlipFromRight| UIViewAnimationOptionCurveEaseOut animations:^(void) { [imageView removeFromSuperview] ; self.view.transform = CGAffineTransformIdentity ; } completion:^(BOOL finished){ [self.view removeFromSuperview] ; [navController presentModalViewController:self animated:NO] ; }] ; }); [imageView release];

Ответы [ 6 ]

3 голосов
/ 12 апреля 2011

Я делал это раньше. Вот суть того, как я это сделал:

  1. Вид А на экране
  2. Создайте вид B, задайте ему кадр, который делает его полноэкранным, но пока не добавляйте его на экран
  3. Вид B имеет UIImageView, так как это самый верхний вид
  4. Снимите UIImage вида A и установите его в качестве изображения представления вида View B

    UIGraphicsBeginImageContext(view.bounds.size); 
    [viewA.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    viewB.imageView.image = image;
    
  5. Установите преобразование вида B (масштаб и перевод) так, чтобы оно было уменьшено до размера вида A и расположено там, где вид A находится на экране

  6. Добавить вид B на экран
  7. На данный момент пользователь не заметил каких-либо изменений, потому что представление B выглядит точно так же, как представление A
  8. Теперь запустите анимационный блок, в котором вы
    • Набор [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView:ViewB
    • установить преобразование View B в CGAffineTransformIdentity
    • удалить просмотр изображения View B из просмотра B

В результате получается анимация, которая выглядит так, будто представление A переворачивается и масштабируется, чтобы заполнить экран представлением B в качестве противоположной стороны.

1 голос
/ 12 апреля 2011

Это простой пример, который я сделал для вас :-) Начните с него ... Постарайтесь понять это ... Прочитайте документацию, и тогда вы сможете делать то, что хотите; -)

- (void)moveTable:(UITableView *)table toPoint:(CGPoint)point excursion:(CGFloat)excursion {

[UIView beginAnimations:nil context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.5];
[table setCenter:point];

// scaling
CABasicAnimation *scalingAnimation = (CABasicAnimation *)[table.layer animationForKey:@"scaling"];
if (!scalingAnimation)
{
    scalingAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
    scalingAnimation.duration=0.5/2.0f;
    scalingAnimation.autoreverses=YES;
    scalingAnimation.removedOnCompletion = YES;
    scalingAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    scalingAnimation.fromValue=[NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0.0, 0.0, 0.0)];
    scalingAnimation.toValue=[NSValue valueWithCATransform3D:CATransform3DMakeTranslation(excursion, 0.0, 0.0)];
}
[table.layer addAnimation:scalingAnimation forKey:@"scaling"];
[UIView commitAnimations];

}

1 голос
/ 08 апреля 2011

Оформить заказ в этом SVN-хранилище:

http://boondoggle.atomicwang.org/lemurflip/

Это переворачивает два представления.

0 голосов
/ 19 января 2012

Это немного грубо по краям, но вот что я сделал, используя блочную анимацию. Следующее переворачивает вид, центрирует его и переходит в полноэкранный режим:

// the view on the other side of the card
UIView* redView = [[UIView alloc]initWithFrame:CGRectMake(0.0, 0.0, viewToFlip.frame.size.width, viewToFlip.frame.size.height)];
redView.backgroundColor = [UIColor redColor];

// add a green square to the red view so we have something else to look at
UIView* greenSquare = [[UIView alloc]initWithFrame:CGRectMake(10.0, 10.0, 20.0, 20.0)];
greenSquare.backgroundColor = [UIColor greenColor];    
[redView addSubview:greenSquare];

// the flip animation
[UIView animateWithDuration:0.25
                      delay:0.0
                    options:UIViewAnimationCurveLinear
                 animations:^{

                     // rotate 90 degrees
                     [viewToFlip.layer setTransform: CATransform3DRotate(viewToFlip.layer.transform, -M_PI/2, 0.0, 1.0, 0.0)];

                 } 
                 completion:^(BOOL finished){

                     // now that we're 90 degrees, swap one view for the other
                     // but if we add it now, the view will be backwards, so flip the original view back
                     [viewToFlip.layer setTransform: CATransform3DRotate(viewToFlip.layer.transform, M_PI, 0.0, 1.0, 0.0)];
                     [viewToFlip addSubview:redView];

                     // now let's continue our rotation
                     [UIView animateWithDuration:0.25
                                           delay:0.0
                                         options:UIViewAnimationCurveLinear
                                      animations:^{

                                          // rotate the last 90 degrees
                                          [viewToFlip.layer setTransform: CATransform3DRotate(viewToFlip.layer.transform, -M_PI/2, 0.0, 1.0, 0.0)];

                                      } 
                                      completion:^(BOOL finished){

                                          [UIView animateWithDuration:0.25
                                                                delay:0.0
                                                              options:UIViewAnimationCurveLinear
                                                           animations:^{

                                                               // animate the views to the center of the screen and adjust their bounds to fill up the screen
                                                               [viewToFlip setCenter:CGPointMake(self.view.center.x, self.view.center.y)];
                                                               [viewToFlip setBounds:CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height)];
                                                               [redView setCenter:CGPointMake(self.view.center.x, self.view.center.y)];
                                                               [redView setBounds:CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height)];
                                                           }
                                                           completion:nil];


                                      }];

                 }];
0 голосов
/ 18 апреля 2011

Я предполагаю, что вы просто хотите изменить изображение представления изображения, пока вы переворачиваете и масштабируете его.Следующий код переворачивает представление изображения с использованием анимации по умолчанию, масштабирует его до кадра другого вида и устанавливает изображение:

[UIView beginAnimations:nil context:nil];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.imageViewA cache:NO];
[UIView setAnimationDuration:2];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationFinished:)];
self.imageViewA.frame = self.imageViewB.frame;
self.imageViewA.image = self.imageViewB.image;
[UIView commitAnimations];

, если вы хотите снова показать представление A в качестве крошечного плавающего представления с другим изображением, которое выможно просто установить его кадр и изображение без блока анимации в методе AnimationDidStopSelector, который можно установить

-(void)animationFinished:(id)context
{
    self.imageViewA.frame = tinyRect;
    self.imageViewA.image = [UIImage imageNamed:@"a.jpg"];
}

, где tinyRect - исходный кадр плавающего представления A.

0 голосов
/ 09 апреля 2011

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

[UIView beginAnimations:@"flipopen" context:nil];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self cache:TRUE];
[a addSubview:b];
a.frame = b.frame;
[UIView commitAnimations];
...