// // SwitchClientPresentationController.m // model // // Created by Drew on 2018/12/14. // Copyright © 2018 Mine. All rights reserved. // #import "SwitchClientPresentationController.h" @implementation SwitchClientPresentationController - (instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController presentingViewController:(UIViewController *)presentingViewController { self = [super initWithPresentedViewController:presentedViewController presentingViewController:presentingViewController]; if (self) { // 必须设置 presentedViewController 的 modalPresentationStyle // 在自定义动画效果的情况下,苹果强烈建议设置为 UIModalPresentationCustom presentedViewController.modalPresentationStyle = UIModalPresentationCustom; } return self; } // 呈现过渡即将开始的时候被调用的 // 可以在此方法创建和设置自定义动画所需的view - (void)presentationTransitionWillBegin { self.containerView.layer.cornerRadius = 14; // 背景遮罩 UIView *dimmingView = [[UIView alloc] initWithFrame:self.containerView.bounds]; dimmingView.backgroundColor = [UIColor blackColor]; dimmingView.opaque = NO; //是否透明 dimmingView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [dimmingView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dimmingViewTapped:)]]; self.dimmingView = dimmingView; [self.containerView addSubview:dimmingView]; // 添加到动画容器View中。 // 获取presentingViewController 的转换协调器,应该动画期间的一个类?上下文?之类的,负责动画的一个东西 id transitionCoordinator = self.presentingViewController.transitionCoordinator; // 动画期间,背景View的动画方式 self.dimmingView.alpha = 0.f; [transitionCoordinator animateAlongsideTransition:^(id context) { self.dimmingView.alpha = 0.4f; } completion:NULL]; } #pragma mark 点击了背景遮罩view - (void)dimmingViewTapped:(UITapGestureRecognizer*)sender { [self.presentingViewController dismissViewControllerAnimated:YES completion:NULL]; } // 在呈现过渡结束时被调用的,并且该方法提供一个布尔变量来判断过渡效果是否完成 - (void)presentationTransitionDidEnd:(BOOL)completed { // 在取消动画的情况下,可能为NO,这种情况下,应该取消视图的引用,防止视图没有释放 if (!completed) { self.dimmingView = nil; } } // 消失过渡即将开始的时候被调用的 - (void)dismissalTransitionWillBegin { id transitionCoordinator = self.presentingViewController.transitionCoordinator; [transitionCoordinator animateAlongsideTransition:^(id context) { self.dimmingView.alpha = 0.f; } completion:NULL]; } // 消失过渡完成之后调用,此时应该将视图移除,防止强引用 - (void)dismissalTransitionDidEnd:(BOOL)completed { if (completed == YES) { [self.dimmingView removeFromSuperview]; self.dimmingView = nil; } } // 返回目标控制器Viewframe - (CGRect)frameOfPresentedViewInContainerView { // 这里直接按照想要的大小写死,其实这样写不好,在第二个Demo里,我们将按照苹果官方Demo,写灵活的获取方式。 CGFloat height = 260.f; CGFloat width = 300.f; CGRect containerViewBounds = CGRectMake((self.containerView.bounds.size.width - width) / 2, (self.containerView.bounds.size.height - height) / 2, width, height); return containerViewBounds; } // 建议就这样重写就行,这个应该是控制器内容大小变化时,就会调用这个方法, 比如适配横竖屏幕时,翻转屏幕时 // 可以使用UIContentContainer的方法来调整任何子视图控制器的大小或位置。 - (void)preferredContentSizeDidChangeForChildContentContainer:(id)container { [super preferredContentSizeDidChangeForChildContentContainer:container]; if (container == self.presentedViewController) [self.containerView setNeedsLayout]; } - (void)containerViewWillLayoutSubviews { [super containerViewWillLayoutSubviews]; self.dimmingView.frame = self.containerView.bounds; } @end