// - 声明
#import <UIKit/UIKit.h> #import "DYVideoPlayerView+Private.h" #pragma mark - 横屏的控制器 @interface DYVideoPlayerVC : UIViewController /** 初始化方法 */ - (instancetype)initWithVideoPlayerView:(UIView *)videoPlayerView preferredInterfaceOrientationForPresentation:(UIInterfaceOrientation)orientation; @end #pragma mark - 跳转横屏控制器的转场动画 typedef NS_ENUM(NSUInteger, DYVideoPlayerTransitionType){ DYVideoPlayerTransitionTypePresent = 0, DYVideoPlayerTransitionTypeDismiss, }; @interface DYVideoPlayerTransition : NSObject<UIViewControllerAnimatedTransitioning> +(instancetype)presentTransitionWithVideoPlayerView:(DYVideoPlayerView *)videoPlayerView; +(instancetype)dismissTransitionWithVideoPlayerView:(DYVideoPlayerView *)videoPlayerView; @end// - DYVideoPlayerView+Private.h
#import "DYVideoPlayerView.h" @interface DYVideoPlayerView () /** 全屏之前的父视图 */ @property (nonatomic, weak) UIView *originalSuperView; /** 全屏之前的 frame */ @property (nonatomic, assign) CGRect originalFrameInSuperView; /** 全屏之前的 frame */ @property (nonatomic, assign) CGRect originalFrameInWindow; @end// - 实现
#import "DYVideoPlayerVC.h" #pragma mark - 横屏的控制器 @interface DYVideoPlayerVC () /** 播放器 */ @property (nonatomic, assign) UIView *videoPlayerView; /** 跳转前播放器的父视图 */ @property (nonatomic, assign) UIView *videoPlayerViewOriginalSuperView; /** 跳转的控制器的方向 */ @property (nonatomic, assign) UIInterfaceOrientation orientation; @end @implementation DYVideoPlayerVC /** 初始化方法 */ - (instancetype)initWithVideoPlayerView:(UIView *)videoPlayerView preferredInterfaceOrientationForPresentation:(UIInterfaceOrientation)orientation { self = [super init]; if (self) { self.modalPresentationStyle = UIModalPresentationFullScreen; self.videoPlayerView = videoPlayerView; self.transitioningDelegate = self.videoPlayerView; self.videoPlayerViewOriginalSuperView = self.videoPlayerView .superview; self.orientation = orientation; } return self; } // - MARK: <-- 初始化设置的方法 --> - (void)viewDidLoad { [super viewDidLoad]; } -(void)viewWillAppear:(BOOL)animated{ [[UIApplication sharedApplication] setStatusBarHidden:NO]; } - (BOOL)shouldAutorotate{ return YES; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskLandscape; } -(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{ return self.orientation; } @end #pragma mark - 跳转横屏控制器的转场动画 @interface DYVideoPlayerTransition () /** 跳转类型 */ @property (nonatomic, assign)DYVideoPlayerTransitionType transitionType; /** present时候 originalRect->全屏, dismiss时候 : 全屏->originalRect*/ @property (nonatomic, weak) DYVideoPlayerView *videoPlayerView; @end @implementation DYVideoPlayerTransition // - MARK: <-- 生成present和dismiss的转场动画 --> +(instancetype)presentTransitionWithVideoPlayerView:(DYVideoPlayerView *)videoPlayerView{ videoPlayerView.originalSuperView = videoPlayerView.superview; videoPlayerView.originalFrameInSuperView = videoPlayerView.frame; videoPlayerView.originalFrameInWindow = [videoPlayerView.originalSuperView convertRect:videoPlayerView.originalFrameInSuperView toView:[UIApplication sharedApplication].keyWindow]; DYVideoPlayerTransition *transition = [[DYVideoPlayerTransition alloc] init]; transition.videoPlayerView = videoPlayerView; transition.transitionType = DYVideoPlayerTransitionTypePresent; return transition; } +(instancetype)dismissTransitionWithVideoPlayerView:(DYVideoPlayerView *)videoPlayerView{ DYVideoPlayerTransition *transition = [[DYVideoPlayerTransition alloc] init]; transition.videoPlayerView = videoPlayerView; transition.transitionType = DYVideoPlayerTransitionTypeDismiss; return transition; } // - MARK: <-- 转场动画代理方法 --> - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{ return 3; } - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{ if (_transitionType == DYVideoPlayerTransitionTypePresent) { [self presentAnimation:transitionContext]; }else{ [self dismissAnimation:transitionContext]; } } /** present 的动画*/ - (void)presentAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{ // - 跳转的vc DYVideoPlayerVC *toVC = (DYVideoPlayerVC *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; // - 跳转的vc的view UIView *containerView = [transitionContext containerView]; UIView *toView = toVC.view; [containerView addSubview:toView]; // - 设置原始的位置 CGRect originalRect; CGRect tmpRect = self.videoPlayerView.originalFrameInWindow; if (toVC.orientation == UIInterfaceOrientationLandscapeLeft) { toView.transform = CGAffineTransformMakeRotation(M_PI / 2); originalRect = CGRectMake( [UIApplication sharedApplication].keyWindow.frame.size.width - - tmpRect.size.height, tmpRect.origin.x, tmpRect.size.height, tmpRect.size.width); }else{ toView.transform = CGAffineTransformMakeRotation(-M_PI / 2); originalRect = CGRectMake(tmpRect.origin.y, tmpRect.origin.x, tmpRect.size.height, tmpRect.size.width); } // - 更换父视图并设置位置 [toView addSubview:self.videoPlayerView]; toView.frame = originalRect; self.videoPlayerView.frame = toView.bounds; [self.videoPlayerView mas_remakeConstraints:^(MASConstraintMaker *make) { make.left.right.top.bottom.equalTo(toView); }]; // - 跳转动画 NSTimeInterval duration = [self transitionDuration:transitionContext]; [UIView animateWithDuration:duration animations:^{ toView.transform = CGAffineTransformIdentity; toView.frame = [UIApplication sharedApplication].keyWindow.bounds; [toView layoutIfNeeded]; } completion:^(BOOL finished) { toView.transform = CGAffineTransformIdentity; toView.frame = [UIApplication sharedApplication].keyWindow.bounds; [transitionContext completeTransition:YES]; }]; } /** dismiss的动画 */ - (void)dismissAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{ // - 当前的vc DYVideoPlayerVC *fromVC = (DYVideoPlayerVC *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; // - 当前的view UIView *containerView = [transitionContext containerView]; UIView *fromView = fromVC.view; UIView *toView = toVC.view; [containerView addSubview:fromView]; toView.frame = [UIApplication sharedApplication].keyWindow.bounds; [containerView insertSubview:toView belowSubview:fromView]; // - 返回的动画 NSTimeInterval duration = [self transitionDuration:transitionContext]; [UIView animateWithDuration:duration animations:^{ fromView.transform = CGAffineTransformIdentity; fromView.frame = self.videoPlayerView.originalFrameInWindow; [fromView layoutIfNeeded]; } completion:^(BOOL finished) { fromView.transform = CGAffineTransformIdentity; fromView.frame = self.videoPlayerView.originalFrameInWindow; // - 更换父视图并设置位置 [fromVC.videoPlayerViewOriginalSuperView addSubview:fromVC.videoPlayerView]; fromView.frame = self.videoPlayerView.originalFrameInSuperView; [fromVC.videoPlayerView mas_remakeConstraints:^(MASConstraintMaker *make) { make.left.mas_equalTo(fromVC.videoPlayerViewOriginalSuperView).offset(self.videoPlayerView.originalFrameInSuperView.origin.x); make.top.mas_equalTo(fromVC.videoPlayerViewOriginalSuperView).offset(self.videoPlayerView.originalFrameInSuperView.origin.y); make.width.mas_equalTo(self.videoPlayerView.originalFrameInSuperView.size.width); make.height.mas_equalTo(self.videoPlayerView.originalFrameInSuperView.size.height); }]; [transitionContext completeTransition:YES]; }]; } @end// - 使用
// // DYVideoPlayerView.m // QEZB // // Created by 李超群 on 2018/4/23. //Copyright © 2018年 zhou. All rights reserved. // #pragma mark ************************************ 短视频的播放器的 view ************************************ #import "DYVideoPlayerView.h" #import "DYVideoPlayerVC.h" @interface DYVideoPlayerView () <UIViewControllerTransitioningDelegate> /** <#注释#> */ @property (nonatomic, weak) UIViewController *videoPlayerVC; @end @implementation DYVideoPlayerView -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ [self toRightScreenModel]; } - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarOrientationChange:) name:UIDeviceOrientationDidChangeNotification object:nil]; } return self; } - (void)statusBarOrientationChange:(NSNotification *)notification { UIDeviceOrientation orientation = [UIDevice currentDevice].orientation; if (orientation == UIDeviceOrientationLandscapeLeft ) { [self toLeftScreenModel]; }else if (orientation == UIDeviceOrientationLandscapeRight) { [self toRightScreenModel]; }else if (orientation == UIDeviceOrientationPortrait) { [self toSmallScreenModel]; } } -(void)toSmallScreenModel{ self.videoPlayerVC.transitioningDelegate = self; [self.videoPlayerVC dismissViewControllerAnimated:YES completion:nil]; self.videoPlayerVC = nil; } -(void)toLeftScreenModel{ // - 如果已经在全屏模式, 不操作 if (self.videoPlayerVC) return; // - 旋转到大屏回调 if ([self.delegate respondsToSelector:@selector(playerView:willRotateToFullScreen:)]) { [self.delegate playerView:self willRotateToFullScreen:YES]; } // - 跳转到大屏 DYVideoPlayerVC *videoPlayerVC = [[DYVideoPlayerVC alloc]initWithVideoPlayerView:self preferredInterfaceOrientationForPresentation:UIInterfaceOrientationLandscapeRight]; UIImageView *tempV = [[UIImageView alloc]initWithImage:[UIImage imageCaptureTheFullScreen]]; [[UIApplication sharedApplication].keyWindow.rootViewController.view addSubview:tempV]; [[ControllerTool getCurrentVC] presentViewController:videoPlayerVC animated:YES completion:^{ [tempV removeFromSuperview]; }]; self.videoPlayerVC = videoPlayerVC; } /** 旋转到大屏模式(右边) */ -(void)toRightScreenModel{ // - 如果已经在全屏模式, 不操作 if (self.videoPlayerVC) return; // - 旋转到大屏回调 if ([self.delegate respondsToSelector:@selector(playerView:willRotateToFullScreen:)]) { [self.delegate playerView:self willRotateToFullScreen:YES]; } // - 跳转到大屏 DYVideoPlayerVC *videoPlayerVC = [[DYVideoPlayerVC alloc]initWithVideoPlayerView:self preferredInterfaceOrientationForPresentation:UIInterfaceOrientationLandscapeLeft]; UIImageView *tempV = [[UIImageView alloc]initWithImage:[UIImage imageCaptureTheFullScreen]]; [[UIApplication sharedApplication].keyWindow.rootViewController.view addSubview:tempV]; [[ControllerTool getCurrentVC] presentViewController:videoPlayerVC animated:YES completion:^{ [tempV removeFromSuperview]; }]; self.videoPlayerVC = videoPlayerVC; } - (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{ return [DYVideoPlayerTransition presentTransitionWithVideoPlayerView:self]; } - (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed{ return [DYVideoPlayerTransition dismissTransitionWithVideoPlayerView:self]; } @end