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"];
Вы можете загрузить образец проекта здесь. Ура!