- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
secondVC *second = [[secondVC alloc] init];
[self presentViewController:second animated:YES completion:nil];
}
secondVC *second = [[secondVC alloc] init];
second.modalPresentationStyle = UIModalPresentationCustom;
second.transitioningDelegate = self;
[self presentViewController:second animated:YES completion:nil];
- (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source
{
return [[MYPresentationController alloc]initWithPresentedViewController:presented presentingViewController:presenting];
}
// MYPresentationController.h
@interface MYPresentationController : UIPresentationController
@end
// MYPresentationController.m
#import "MYPresentationController.h"
@implementation MYPresentationController
- (CGRect)frameOfPresentedViewInContainerView
{
return CGRectMake(100, 100, 150, 300); //设置modal出来控制器的frame
}
// 下面这几个方法,监听Modal控制器时的各种状态
- (void)presentationTransitionWillBegin
{
NSLog(@"presentationTransitionWillBegin");
}
- (void)presentationTransitionDidEnd:(BOOL)completed
{
NSLog(@"presentationTransitionDidEnd");
}
- (void)dismissalTransitionWillBegin
{
NSLog(@"presentationTransitionDidEnd");
}
- (void)dismissalTransitionDidEnd:(BOOL)completed
{
NSLog(@"dismissalTransitionDidEnd");
}
@end
要想实现自定义转场动画,可以考虑设置second.modalTransitionStyle,但是没有UIModalTransitionStyleCustom,是因为
只要设置了UIModalPresentationCustom,也就相当于设置了"UIModalTransitionStyleCustom",要想实现自定义转场动画,只要实现相应的代理方法即可
secondVC *second = [[secondVC alloc] init];
second.modalPresentationStyle = UIModalPresentationCustom;
second.transitioningDelegate = self;
second.modalTransitionStyle = UIModalTransitionStyleCoverVertical; // 要实现自定义转场动画,不是在这里设置
[self presentViewController:second animated:YES completion:nil];
#pragma mark - 自定义转场动画的代理方法,两个,分别控制显示和消失
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
return self; // 简单处理,返回self,只要self遵守<UIViewControllerAnimatedTransitioning>协议
}
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
return self;
}
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext{
return 0.3;
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
toView.y = -toView.height;
[UIView animateWithDuration:0.3 animations:^{
toView.y = 0;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES]; //这个必须写,否则程序 认为动画还在执行中,会导致展示完界面后,无法处理用户的点击事件
}];
}
这样就实现了modal出来的控制器,是从屏幕顶部下来的转场动画
// MYAnimatedTransition.h
@interface MYAnimatedTransition : NSObject<UIViewControllerAnimatedTransitioning>
@property (assign,nonatomic) BOOL show;
@end
// MYAnimatedTransition.m
@implementation MYAnimatedTransition
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return 0.3;
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
if (self.show == YES) { // 显示
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
toView.y = -toView.height;
[UIView animateWithDuration:0.3 animations:^{
toView.y = 0;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}else{ // 消失
UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
[UIView animateWithDuration:0.3 animations:^{
fromView.y = fromView.height;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
}
@end
#pragma mark - 自定义转场动画的代理方法,两个,分别控制显示和消失
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
MYAnimatedTransition *anima = [[MYAnimatedTransition alloc]init];
anima.show = YES;
return anima;
}
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
MYAnimatedTransition *anima = [[MYAnimatedTransition alloc]init];
anima.show = NO;
return anima;
}
- (void)presentationTransitionWillBegin{
NSLog(@"presentationTransitionWillBegin");
[self.containerView addSubview:self.presentedView]; // 因为是自定义转场动画,所以添加视图的工作也需要自行实现
}
而且下面这个方法作废了,程序是不会执行的,因为你是自定义转场动画,动画前后的Frame都已经在这个方法实现了: - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
- (CGRect)frameOfPresentedViewInContainerView
{
return CGRectMake(100, 100, 150, 300);
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
// toView.y = -toView.height;
toView.layer.transform = CATransform3DMakeRotation(M_PI_2, 0, 1, 0);
[UIView animateWithDuration:0.3 animations:^{
// toView.y = 0;
toView.layer.transform = CATransform3DIdentity;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}else{
UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
[UIView animateWithDuration:0.3 animations:^{
// fromView.y = fromView.height;
fromView.layer.transform = CATransform3DMakeRotation(M_PI_2, 0, 1, 0);
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
}
iOS 利用UIPresentationController自定义转场动画
原文:http://www.cnblogs.com/oumygade/p/4280512.html