IOs анимация Segue слева направо (по горизонтали)

Я почти новичок в Xcode 4. Есть ли способ добавить к segue пользовательскую переходную анимацию, которая не входит в число четырех, представленных интерфейсом Builder в управлении раскадрой? В частности, мне нужна анимация, похожая на обычную "вертикальную покровную", но горизонтальную. Я хочу, чтобы представление переходило к другому, перемещаясь слева направо (или справа налево), а не вверх, как это происходит при переходе "по вертикали". Я пробовал с жестом салфетки, но не фортуны: даже это переход из-за низа и в любом случае, я не понимаю, почему переход от defaul происходит донизу, когда по умолчанию переход всего приложения обычно прав налево или влево вправо, особенно в случае, если вы проведите пальцем по экрану...

Я пробовал также программный путь, но не фортуну даже в этом случае, используя этот код:

#import "JHCustomSegue.h"

@implementation JHCustomSegue
- (void) perform {
  UIViewController *src = (UIViewController *) self.sourceViewController;
  UIViewController *dst = (UIViewController *) self.destinationViewController;

  [UIView transitionWithView:src.navigationController.view duration:0.5 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{
        [src presentModalViewController:dst animated:NO];
    }
    completion:NULL];
}

@end

В конструкторе интерфейса я определил этот класс как класс моего segue. Используя точку останова, я увидел, что он входит в функцию, но... не выполняет! Я заблокировал приложение в портретном режиме (не знаю, если это проблема). Я попытался запустить приложение на реальном ipad и на смоделированном iphone. Та же проблема.

Ответ 1

Вы можете использовать CATransition в пользовательском Segue для достижения перехода слева направо. Добавьте этот #import "QuartzCore/QuartzCore.h" в свой пользовательский Segue

-(void)perform {

__block UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
__block UIViewController *destinationController = (UIViewController*)[self destinationViewController];                    

CATransition* transition = [CATransition animation];
transition.duration = .25;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
transition.subtype = kCATransitionFromLeft; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom



[sourceViewController.navigationController.view.layer addAnimation:transition
                                            forKey:kCATransition];

[sourceViewController.navigationController pushViewController:destinationController animated:NO];    


}

Ответ 2

Основываясь на представлении Zakir Hyder, вот такая же функциональность, переведенная в Swift:

override func perform() {

    var sourceViewController = self.sourceViewController as UIViewController
    var destinationViewController = self.destinationViewController as UIViewController

    var transition: CATransition = CATransition()

    transition.duration = 0.25
    transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    transition.type = kCATransitionPush; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
    transition.subtype = kCATransitionFromLeft; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom

    sourceViewController.navigationController?.view.layer.addAnimation(transition, forKey: "kCATransition")
    sourceViewController.navigationController?.pushViewController(destinationViewController, animated: false)     

}

Ответ 3

Вот рабочий код для пользовательской синхронизации при отсутствии контроллера навигации.

-(void)perform
{

UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
UIViewController *destinationController = (UIViewController*)[self destinationViewController];

CATransition* transition = [CATransition animation];
transition.duration = 0.25;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionMoveIn; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
transition.subtype = kCATransitionFromRight; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom

[destinationController.view.layer addAnimation:transition forKey:kCATransition];
[sourceViewController presentViewController:destinationController animated:NO completion:nil];
}

Ответ 4

Посмотрите этот пример на Github:

https://github.com/itinance/iOSCustomSegue

Он использует пользовательский segue справа налево в примере приложения явно без UINavigationController в качестве разработчика потока, в котором запрашивается.

Код в ответе Sahil не работал у меня в iOS 8. Поэтому мне пришлось исследовать немного больше по этой проблеме.

'UIView animateWithDuration' работает на iOS 8, а 'destinationController.view.layer addAnimation: transition' ничего не делает в сочетании с presentViewController.

Ответ 5

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

// get the view that currently showing
UIView *currentView = self.view;
// get the the underlying UIWindow, or the view containing the current view
UIView *theWindow = [currentView superview];

UIView *newView = aTwoViewController.view; 

// remove the current view and replace with myView1
[currentView removeFromSuperview];
[theWindow addSubview:newView];

// set up an animation for the transition between the views
CATransition *animation = [CATransition animation];
[animation setDuration:0.5];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromRight];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];

[[theWindow layer] addAnimation:animation forKey:@"SwitchToView2"];

Вы можете загрузить образец проекта здесь. Ура!