短视频app开发,点击视频进行全屏播放
短视频app开发,点击视频进行全屏播放的相关代码
1 | #import "VideoFullScreenController.h"<br>static CGFloat AnimationDuration = 0.3;//旋转动画执行时间<br>@interface VideoFullScreenController ()<br>@property (nonatomic, nullable, strong) UIView *playerView;//播放器视图<br>@property (nonatomic, nullable, strong) UIButton *btnFullScreen;<br>@property (nonatomic, nullable, strong) UIView *playerSuperView;//记录播放器父视图<br>@property (nonatomic, assign) CGRect playerFrame;//记录播放器原始frame<br>@property (nonatomic, assign) BOOL isFullScreen;//记录是否全屏<br>@property (nonatomic, assign) UIInterfaceOrientation lastInterfaceOrientation;<br>@property (nonatomic, nullable, strong) UIWindow *mainWindow;<br>@end<br>@implementation VideoFullScreenController<br>- (void)viewDidLoad {<br> [super viewDidLoad];<br> [self.playerView addSubview:self.btnFullScreen];<br> [self.view addSubview:self.playerView];<br> <br> if (@available(iOS 13.0, *)) {<br> _lastInterfaceOrientation = [UIApplication sharedApplication].windows.firstObject.windowScene.interfaceOrientation;<br> } else {<br> _lastInterfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;<br> }<br> //开启和监听 设备旋转的通知<br> if (![UIDevice currentDevice].generatesDeviceOrientationNotifications) {<br> [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];<br> }<br> [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(handleDeviceOrientationChange:)<br> name:UIDeviceOrientationDidChangeNotification object:nil];<br>}<br>//设备方向改变的处理<br>- (void)handleDeviceOrientationChange:(NSNotification *)notification{<br> UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;<br> switch (deviceOrientation) {<br> case UIDeviceOrientationFaceUp:<br> NSLog(@"屏幕朝上平躺");<br> break;<br> case UIDeviceOrientationFaceDown:<br> NSLog(@"屏幕朝下平躺");<br> break;<br> case UIDeviceOrientationUnknown:<br> NSLog(@"未知方向");<br> break;<br> case UIDeviceOrientationLandscapeLeft:<br> if (self.isFullScreen) {<br> [self interfaceOrientation:UIInterfaceOrientationLandscapeRight];<br> }<br> <br> NSLog(@"屏幕向左横置");<br> break;<br> case UIDeviceOrientationLandscapeRight:<br> if (self.isFullScreen) {<br> [self interfaceOrientation:UIInterfaceOrientationLandscapeLeft];<br> }<br> <br> NSLog(@"屏幕向右橫置");<br> break;<br> case UIDeviceOrientationPortrait:<br> NSLog(@"屏幕直立");<br> break;<br> case UIDeviceOrientationPortraitUpsideDown:<br> NSLog(@"屏幕直立,上下顛倒");<br> break;<br> default:<br> NSLog(@"无法辨识");<br> break;<br> }<br>}<br>//最后在dealloc中移除通知 和结束设备旋转的通知<br>- (void)dealloc{<br> [[NSNotificationCenter defaultCenter]removeObserver:self];<br> [[UIDevice currentDevice]endGeneratingDeviceOrientationNotifications];<br>}<br>- (BOOL)shouldAutorotate {<br> return NO;<br>}<br>- (BOOL)prefersStatusBarHidden {<br> if (@available(iOS 13.0, *)) {<br> return self.isFullScreen;<br> }<br> return NO;<br>}<br>- (UIInterfaceOrientationMask)supportedInterfaceOrientations {<br> <br> return UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskLandscapeLeft|UIInterfaceOrientationMaskLandscapeRight;<br>}<br>#pragma mark - private method<br>- (void)fullScreenAction:(UIButton *)sender {<br> <br> if (self.isFullScreen) {//如果是全屏,点击按钮进入小屏状态<br> [self changeToOriginalFrame];<br> } else {//不是全屏,点击按钮进入全屏状态<br> [self changeToFullScreen];<br> }<br> <br>}<br>- (void)changeToOriginalFrame {<br> <br> if (!self.isFullScreen) {<br> return;<br> }<br> [UIView animateWithDuration:AnimationDuration animations:^{<br> <br> <br> [self interfaceOrientation:UIInterfaceOrientationPortrait];<br> self.playerView.frame = self.playerFrame;<br> <br> } completion:^(BOOL finished) {<br> <br> [self.playerView removeFromSuperview];<br> <br> [self.playerSuperView addSubview:self.playerView];<br> self.isFullScreen = NO;<br> //调用以下方法后,系统会在合适的时间调用prefersStatusBarHidden方法,控制状态栏的显示和隐藏,可根据自己的产品控制显示逻辑<br> [self setNeedsStatusBarAppearanceUpdate];<br> }];<br> <br>}<br>- (void)changeToFullScreen {<br> if (self.isFullScreen) {<br> return;<br> }<br> <br> //记录播放器视图的父视图和原始frame值,在实际项目中,可能会嵌套子视图,所以播放器的superView有可能不是self.view,所以需要记录父视图<br> self.playerSuperView = self.playerView.superview;<br> self.playerFrame = self.playerView.frame;<br> <br> CGRect rectInWindow = [self.playerView convertRect:self.playerView.bounds toView:self.mainWindow];<br> [self.playerView removeFromSuperview];<br> <br> self.playerView.frame = rectInWindow;<br> [self.mainWindow addSubview:self.playerView];<br> <br> //执行旋转动画<br> [UIView animateWithDuration:AnimationDuration animations:^{<br> <br> UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;<br> if (orientation == UIDeviceOrientationLandscapeRight) {<br> [self interfaceOrientation:UIInterfaceOrientationLandscapeLeft];<br> } else {<br> [self interfaceOrientation:UIInterfaceOrientationLandscapeRight];<br> }<br> <br> self.playerView.bounds = CGRectMake(0, 0, CGRectGetHeight(self.mainWindow.bounds), CGRectGetWidth(self.mainWindow.bounds));<br> self.playerView.center = CGPointMake(CGRectGetMidX(self.mainWindow.bounds), CGRectGetMidY(self.mainWindow.bounds));<br> <br> } completion:^(BOOL finished) {<br> <br> self.isFullScreen = YES;<br> //调用以下方法后,系统会在合适的时间调用prefersStatusBarHidden方法,控制状态栏的显示和隐藏,可根据自己的产品控制显示逻辑<br> [self setNeedsStatusBarAppearanceUpdate];<br> }];<br>}<br>- (void)interfaceOrientation:(UIInterfaceOrientation)orientation {<br> if (orientation == UIInterfaceOrientationLandscapeRight || orientation == UIInterfaceOrientationLandscapeLeft) {<br> // 设置横屏<br> [self setOrientationLandscapeConstraint:orientation];<br> } else if (orientation == UIInterfaceOrientationPortrait) {<br> // 设置竖屏<br> [self setOrientationPortraitConstraint];<br> }<br>}<br>- (void)setOrientationLandscapeConstraint:(UIInterfaceOrientation)orientation {<br> <br> [self toOrientation:orientation];<br>}<br>- (void)setOrientationPortraitConstraint {<br> <br> [self toOrientation:UIInterfaceOrientationPortrait];<br>}<br>- (void)toOrientation:(UIInterfaceOrientation)orientation {<br> // 获取到当前状态条的方向------iOS13已经废弃,所以不能根据状态栏的方向判断是否旋转,手动记录最后一次的旋转方向<br>// UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation;<br> // 判断如果当前方向和要旋转的方向一致,那么不做任何操作<br> if (self.lastInterfaceOrientation == orientation) { return; }<br> <br> if (@available(iOS 13.0, *)) {<br> //iOS 13已经将setStatusBarOrientation废弃,调用此方法无效<br> } else {<br> [[UIApplication sharedApplication] setStatusBarOrientation:orientation animated:NO];<br> }<br> self.lastInterfaceOrientation = orientation;<br> <br> // 获取旋转状态条需要的时间:<br> <br> [UIView animateWithDuration:AnimationDuration animations:^{<br> // 更改了状态条的方向,但是设备方向UIInterfaceOrientation还是正方向的,这就要设置给你播放视频的视图的方向设置旋转<br> // 给你的播放视频的view视图设置旋转<br> self.playerView.transform = CGAffineTransformIdentity;<br> self.playerView.transform = [self getTransformRotationAngleWithOrientation:self.lastInterfaceOrientation];<br> // 开始旋转<br> } completion:^(BOOL finished) {<br> <br> }];<br>}<br>- (CGAffineTransform)getTransformRotationAngleWithOrientation:(UIInterfaceOrientation)orientation {<br> // 根据要进行旋转的方向来计算旋转的角度<br> if (orientation == UIInterfaceOrientationPortrait) {<br> return CGAffineTransformIdentity;<br> } else if (orientation == UIInterfaceOrientationLandscapeLeft){<br> return CGAffineTransformMakeRotation(-M_PI_2);<br> } else if(orientation == UIInterfaceOrientationLandscapeRight){<br> return CGAffineTransformMakeRotation(M_PI_2);<br> }<br> return CGAffineTransformIdentity;<br>}<br>#pragma mark - setter<br>- (void)setIsFullScreen:(BOOL)isFullScreen {<br> _isFullScreen = isFullScreen;<br> [self.btnFullScreen setTitle:isFullScreen?@"退出全屏":@"全屏" forState:UIControlStateNormal];<br>}<br>#pragma mark - getter<br>- (UIView *)playerView {<br> if (!_playerView) {<br> _playerView = [[UIView alloc]init];<br> _playerView.backgroundColor = [UIColor redColor];<br> <br> if (@available(iOS 11.0, *)) {<br> _playerView.frame = CGRectMake(0, self.view.safeAreaInsets.top, CGRectGetWidth(self.view.bounds), CGRectGetWidth(self.view.bounds) * 9 / 16.f);<br> } else {<br> _playerView.frame = CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), CGRectGetWidth(self.view.bounds) * 9 / 16.f);<br> }<br> <br> }<br> return _playerView;<br>}<br>- (UIButton *)btnFullScreen {<br> if (!_btnFullScreen) {<br> _btnFullScreen = [UIButton buttonWithType:UIButtonTypeCustom];<br> [_btnFullScreen setTitle:@"全屏" forState:UIControlStateNormal];<br> _btnFullScreen.backgroundColor = [UIColor orangeColor];<br> [_btnFullScreen addTarget:self action:@selector(fullScreenAction:) forControlEvents:UIControlEventTouchUpInside];<br> _btnFullScreen.frame = CGRectMake(50, 80, 150, 50);<br> }<br> return _btnFullScreen;<br>}<br>- (UIWindow *)mainWindow {<br> if (!_mainWindow) {<br> if (@available(iOS 13.0, *)) {<br> _mainWindow = [UIApplication sharedApplication].windows.firstObject;<br> } else {<br> _mainWindow = [UIApplication sharedApplication].keyWindow;<br> }<br> }<br> return _mainWindow;<br>}<br>@end |
结尾
如果你的rootViewController是UIViewController的话,那么用上面的代码实现全屏效果没有问题,如果你的rootViewController是UINavigationController或者UITabBarController的话,那么还要增加两个分类文件。文件内容如下:
一、定义分类UINavigationController+Rotation.h
1 | @implementation UINavigationController (Rotation)<br>- ( BOOL )shouldAutorotate {<br> return [self.topViewController shouldAutorotate];<br>}<br>- (UIInterfaceOrientationMask)supportedInterfaceOrientations {<br> return [self.topViewController supportedInterfaceOrientations];<br>}<br>- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {<br> return [self.topViewController preferredInterfaceOrientationForPresentation];<br>} |
二、定义分类UITabBarController+Rotation.h
1 | @implementation UITabBarController (Rotation)<br>- (BOOL)shouldAutorotate {<br> return [self.selectedViewController shouldAutorotate];<br>}<br>- (UIInterfaceOrientationMask)supportedInterfaceOrientations {<br> return [self.selectedViewController supportedInterfaceOrientations];<br>}<br>- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {<br> return [self.selectedViewController preferredInterfaceOrientationForPresentation];<br>} |
以上就是 短视频app开发,点击视频进行全屏播放的相关代码,更多内容欢迎关注之后的文章
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现