播放器横竖屏方案
程序员文章站
2022-06-15 12:38:46
类似现在主流app的横竖切换的方式原理 : 在播放器横屏时候, present一个新的视图控制器, 并在该新控制器中支持横竖屏. dismiss时候, 返回之前的播放器;源码 :// - 声明#import #pragma mark - 横屏的控制器@interface DYVideoPlayerVC : UIViewController/** 初始化方法 */- (instancetype)initWithVideoPlayerView:(...
类似现在主流app的横竖切换的方式
- 原理 : 在播放器横屏时候, present一个新的视图控制器, 并在该新控制器中支持横竖屏. dismiss时候, 返回之前的播放器;
- 源码 :
// - 声明
#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
本文地址:https://blog.csdn.net/qq_27074387/article/details/107133650
上一篇: Android七大布局
下一篇: python实现找出旋转数组的最小元素