博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS 视频全屏功能 学习
阅读量:6478 次
发布时间:2019-06-23

本文共 7356 字,大约阅读时间需要 24 分钟。

项目中,也写过类似"视频全屏"的功能, 前一阵子读到今日头条 的一篇技术文章,详细介绍三种旋转方法差异优劣最终择取。文章从技术角度看写的非常好,从用户角度看,也用过多家有视频功能的app,今日头条的体验的确很优。特别值得学习特此参考写了一个视频全屏小功能

 实现方法:配合重写当前的ViewController的shouldAutorotate方法,返回NO 并且控制 状态栏的展示  然后 通过 animation旋转动画处理UI相对布局 

(1)组织类别方法 UINavigationController+Rotation 目的视频旋转 状态栏也要旋转

////  UINavigationController+Rotation.h//  SectionDemo////  Created by HF on 17/4/1.//  Copyright © 2017年 HF-Liqun. All rights reserved.//#import 
@interface UINavigationController (Rotation)@end//// UINavigationController+Rotation.m// SectionDemo//// Created by HF on 17/4/1.// Copyright © 2017年 HF-Liqun. All rights reserved.//#import "UINavigationController+Rotation.h"@implementation UINavigationController (Rotation)- (BOOL)shouldAutorotate{ return [[self.viewControllers lastObject] shouldAutorotate];}- (NSUInteger)supportedInterfaceOrientations{ return [[self.viewControllers lastObject] supportedInterfaceOrientations];}- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];}@end

(2)视频UI HFMovieView

////  HFMovieView.h//  SectionDemo////  Created by HF on 17/4/1.//  Copyright © 2017年 HF-Liqun. All rights reserved.//#import 
#import "HFPlayerView.h"typedef NS_ENUM(NSUInteger, MovieViewState) { MovieViewStateSmall, MovieViewStateAnimating, MovieViewStateFullscreen,};@interface HFMovieView : UIView/** 视频播放对象 */@property (nonatomic, strong)HFPlayerView *videoView;/** 记录小屏时的parentView */@property (nonatomic, weak) UIView *movieViewParentView;/** 记录小屏时的frame */@property (nonatomic, assign) CGRect movieViewFrame;@property (nonatomic, assign) MovieViewState state;@end
////  HFMovieView.m//  SectionDemo////  Created by HF on 17/4/1.//  Copyright © 2017年 HF-Liqun. All rights reserved.//#import "HFMovieView.h"@implementation HFMovieView- (instancetype)initWithFrame:(CGRect)frame{    self = [super initWithFrame:frame];    if (self) {                 //videoView        [self addSubview:self.videoView];                //others        UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];        [self.videoView addGestureRecognizer:tapGestureRecognizer];        }    return self;}#pragma mark - event- (void)handleTapGesture:(UITapGestureRecognizer *)sender{    if (sender.state == UIGestureRecognizerStateEnded)    {        if (self.state == MovieViewStateSmall) {            [self enterFullscreen];        }        else if (self.state == MovieViewStateFullscreen) {            [self exitFullscreen];        }    }}#pragma mark - private#pragma mark -- 全屏 animation- (void)enterFullscreen {        if (self.state != MovieViewStateSmall) {        return;    }        self.state = MovieViewStateAnimating;        /*     * 记录进入全屏前的parentView和frame     */    self.movieViewParentView = self.videoView.superview;    self.movieViewFrame = self.videoView.frame;        /*     * movieView移到window上     */    CGRect rectInWindow = [self convertRect:self.videoView.bounds toView:[UIApplication sharedApplication].keyWindow];    [self.videoView removeFromSuperview];    self.videoView.frame = rectInWindow;    [[UIApplication sharedApplication].keyWindow addSubview:self.videoView];        /*     * 执行动画     */    [UIView animateWithDuration:0.5 animations:^{        self.videoView.transform = CGAffineTransformMakeRotation(M_PI_2);        self.videoView.bounds = CGRectMake(0, 0, CGRectGetHeight(self.videoView.superview.bounds), CGRectGetWidth(self.videoView.superview.bounds));        self.videoView.center = CGPointMake(CGRectGetMidX(self.videoView.superview.bounds), CGRectGetMidY(self.videoView.superview.bounds));    } completion:^(BOOL finished) {        self.state = MovieViewStateFullscreen;    }];        [self refreshStatusBarOrientation:UIInterfaceOrientationLandscapeRight];}#pragma mark -- 退出全屏 animation- (void)exitFullscreen{    if (self.state != MovieViewStateFullscreen) {        return;    }        self.state = MovieViewStateAnimating;        CGRect frame = [self.movieViewParentView convertRect:self.movieViewFrame toView:[UIApplication sharedApplication].keyWindow];        [UIView animateWithDuration:0.5 animations:^{        self.videoView.transform = CGAffineTransformIdentity;        self.videoView.frame = frame;    } completion:^(BOOL finished) {        /*         * movieView回到小屏位置         */        [self.videoView removeFromSuperview];        self.videoView.frame = self.movieViewFrame;        [self.movieViewParentView addSubview:self.videoView];        self.state = MovieViewStateSmall;    }];        [self refreshStatusBarOrientation:UIInterfaceOrientationPortrait];}#pragma mark -- 更新状态栏方向- (void)refreshStatusBarOrientation:(UIInterfaceOrientation)interfaceOrientation {    [[UIApplication sharedApplication] setStatusBarOrientation:interfaceOrientation animated:YES];}#pragma mark - setter and getter- (HFPlayerView *)videoView{    if (!_videoView) {        _videoView = [[HFPlayerView alloc]initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];        _videoView.backgroundColor = [UIColor blackColor];    }    return _videoView;}@end

(3)视图控制器

////  MethodDetailViewController.h//  SectionDemo////  Created by HF on 17/4/1.//  Copyright © 2017年 HF-Liqun. All rights reserved.//#import 
#import "HFMovieView.h"@interface MethodDetailViewController : UIViewController@property (nonatomic, strong) HFMovieView *moviewView;@end//// MethodDetailViewController.m// SectionDemo//// Created by HF on 17/4/1.// Copyright © 2017年 HF-Liqun. All rights reserved.//#import "MethodDetailViewController.h"@interface MethodDetailViewController ()@property (nonatomic, strong) UITableView *tableView;@property (nonatomic, strong) UIView *headView;@end@implementation MethodDetailViewController- (void)viewDidLoad { [super viewDidLoad]; [self.view addSubview:self.tableView]; [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; self.tableView.tableHeaderView = self.headView; [self.headView addSubview:self.moviewView];}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}#pragma mark - 旋转配置- (BOOL)shouldAutorotate { return NO;}#pragma mark - setter/getter- (UITableView *)tableView{ if (!_tableView) { _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; _tableView.backgroundColor = [UIColor clearColor]; // _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; } return _tableView;}- (UIView *)headView{ if (!_headView) { _headView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 200)];; _headView.backgroundColor = [UIColor lightGrayColor]; } return _headView;}- (HFMovieView *)moviewView{ if (!_moviewView) { _moviewView = [[HFMovieView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 200)]; _moviewView.backgroundColor = [UIColor yellowColor]; } return _moviewView;}@end

效果图:

 (4)参考之前 写过视频播放的相关方法 优化架构分工 

  参考  

参考:

1. https://techblog.toutiao.com/2017/03/28/fullscreen/

2. 

3.

转载于:https://www.cnblogs.com/someonelikeyou/p/6890256.html

你可能感兴趣的文章
oracle11g dataguard 安装手册(转)
查看>>
java并发包分析之———Deque和LinkedBlockingDeque
查看>>
1. Two Sum - Easy - Leetcode解题报告
查看>>
多线程---同步函数的锁是this(转载)
查看>>
鱼C记事本V1.0(下)- 零基础入门学习Delphi28
查看>>
百练 2742 统计字符数 解题报告
查看>>
Ubuntu搜狗输入法候选词乱码
查看>>
js中回调函数写法
查看>>
React native android 最常见的10个问题
查看>>
数据结构和算法
查看>>
.Net 项目代码风格要求
查看>>
[pat]1045 Favorite Color Stripe
查看>>
Immutable学习及 React 中的实践
查看>>
【转】性能测试步骤
查看>>
OSI与TCP/IP各层的结构与功能,都有哪些协议
查看>>
Android实例-程序切换到后台及从后台切换到前台
查看>>
spring boot启动定时任务
查看>>
[转]html5 Canvas画图教程(6)—canvas里画曲线之arcTo方法
查看>>
算法 (二分查找算法)
查看>>
java Date 当天时间戳处理
查看>>