3 回答

TA貢獻(xiàn)1794條經(jīng)驗 獲得超8個贊
要使用導(dǎo)航控制器(UINavigationController)進(jìn)行自定義轉(zhuǎn)換,您應(yīng)該:
定義您的視圖控制器以符合UINavigationControllerDelegate協(xié)議。例如,您可以在視圖控制器的.m文件中具有私有類擴(kuò)展名,該擴(kuò)展名指定對此協(xié)議的符合性:
@interface ViewController () <UINavigationControllerDelegate>
@end
確保您確實將視圖控制器指定為導(dǎo)航控制器的委托:
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationController.delegate = self;
}
實現(xiàn)animationControllerForOperation您的視圖控制器:
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController*)fromVC
toViewController:(UIViewController*)toVC
{
if (operation == UINavigationControllerOperationPush)
return [[PushAnimator alloc] init];
if (operation == UINavigationControllerOperationPop)
return [[PopAnimator alloc] init];
return nil;
}
實現(xiàn)用于推送和彈出動畫的動畫制作器,例如:
@interface PushAnimator : NSObject <UIViewControllerAnimatedTransitioning>
@end
@interface PopAnimator : NSObject <UIViewControllerAnimatedTransitioning>
@end
@implementation PushAnimator
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return 0.5;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
[[transitionContext containerView] addSubview:toViewController.view];
toViewController.view.alpha = 0.0;
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
toViewController.view.alpha = 1.0;
} completion:^(BOOL finished) {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end
@implementation PopAnimator
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return 0.5;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
[[transitionContext containerView] insertSubview:toViewController.view belowSubview:fromViewController.view];
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
fromViewController.view.alpha = 0.0;
} completion:^(BOOL finished) {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end
確實會出現(xiàn)淡入淡出的過渡,但是您應(yīng)該隨心所欲地自定義動畫。
如果您想處理交互式手勢(例如,從左向右滑動本機(jī)滑動之類的東西),則必須實現(xiàn)一個交互控制器:
定義交互控制器(符合的對象UIViewControllerInteractiveTransitioning)的屬性:
@property (nonatomic, strong) UIPercentDrivenInteractiveTransition *interactionController;
這UIPercentDrivenInteractiveTransition是一個不錯的對象,它會根據(jù)手勢的完成程度來繁瑣地更新自定義動畫。
將手勢識別器添加到視圖。在這里,我只是實現(xiàn)左手勢識別器來模擬彈出:
UIScreenEdgePanGestureRecognizer *edge = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFromLeftEdge:)];
edge.edges = UIRectEdgeLeft;
[view addGestureRecognizer:edge];
實現(xiàn)手勢識別處理程序:
/** Handle swipe from left edge
*
* This is the "action" selector that is called when a left screen edge gesture recognizer starts.
*
* This will instantiate a UIPercentDrivenInteractiveTransition when the gesture starts,
* update it as the gesture is "changed", and will finish and release it when the gesture
* ends.
*
* @param gesture The screen edge pan gesture recognizer.
*/
- (void)handleSwipeFromLeftEdge:(UIScreenEdgePanGestureRecognizer *)gesture {
CGPoint translate = [gesture translationInView:gesture.view];
CGFloat percent = translate.x / gesture.view.bounds.size.width;
if (gesture.state == UIGestureRecognizerStateBegan) {
self.interactionController = [[UIPercentDrivenInteractiveTransition alloc] init];
[self popViewControllerAnimated:TRUE];
} else if (gesture.state == UIGestureRecognizerStateChanged) {
[self.interactionController updateInteractiveTransition:percent];
} else if (gesture.state == UIGestureRecognizerStateEnded) {
CGPoint velocity = [gesture velocityInView:gesture.view];
if (percent > 0.5 || velocity.x > 0) {
[self.interactionController finishInteractiveTransition];
} else {
[self.interactionController cancelInteractiveTransition];
}
self.interactionController = nil;
}
}
在導(dǎo)航控制器委托中,還必須實現(xiàn)interactionControllerForAnimationController委托方法
- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController {
return self.interactionController;
}
如果您在Google上搜索“ UINavigationController自定義過渡教程”,那么您將獲得很多成功。或參閱WWDC 2013 Custom Transitions視頻。

TA貢獻(xiàn)1858條經(jīng)驗 獲得超8個贊
您可能想在之前添加以下代碼 addSubview
toViewController.view.frame = [transitionContext finalFrameForViewController:toViewController];
來自另一個問題,在iOS 9上使用navigationcontroller為推送動畫進(jìn)行自定義轉(zhuǎn)換
從Apple的finalFrameForViewController文檔中:
返回指定視圖控制器視圖的結(jié)束幀矩形。
此方法返回的矩形表示過渡結(jié)束時相應(yīng)視圖的大小。對于演示過程中涉及的視圖,此方法返回的值可能是CGRectZero,但也可能是有效的框架矩形。
- 3 回答
- 0 關(guān)注
- 562 瀏覽
添加回答
舉報