短視頻app開發,點擊視頻進行全屏播放的相關代碼
#import "VideoFullScreenController.h"
static CGFloat AnimationDuration = 0.3;//旋轉動畫執行時間
@interface VideoFullScreenController ()
@property (nonatomic, nullable, strong) UIView *playerView;//播放器視圖
@property (nonatomic, nullable, strong) UIButton *btnFullScreen;
@property (nonatomic, nullable, strong) UIView *playerSuperView;//記錄播放器父視圖
@property (nonatomic, assign) CGRect playerFrame;//記錄播放器原始frame
@property (nonatomic, assign) BOOL isFullScreen;//記錄是否全屏
@property (nonatomic, assign) UIInterfaceOrientation lastInterfaceOrientation;
@property (nonatomic, nullable, strong) UIWindow *mainWindow;
@end
@implementation VideoFullScreenController
- (void)viewDidLoad {
[super viewDidLoad];
[self.playerView addSubview:self.btnFullScreen];
[self.view addSubview:self.playerView];
if (@available(iOS 13.0, *)) {
_lastInterfaceOrientation = [UIApplication sharedApplication].windows.firstObject.windowScene.interfaceOrientation;
} else {
_lastInterfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;
}
//開啟和監聽 設備旋轉的通知
if (![UIDevice currentDevice].generatesDeviceOrientationNotifications) {
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
}
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(handleDeviceOrientationChange:)
name:UIDeviceOrientationDidChangeNotification object:nil];
}
//設備方向改變的處理
- (void)handleDeviceOrientationChange:(NSNotification *)notification{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
switch (deviceOrientation) {
case UIDeviceOrientationFaceUp:
NSLog(@"屏幕朝上平躺");
break;
case UIDeviceOrientationFaceDown:
NSLog(@"屏幕朝下平躺");
break;
case UIDeviceOrientationUnknown:
NSLog(@"未知方向");
break;
case UIDeviceOrientationLandscapeLeft:
if (self.isFullScreen) {
[self interfaceOrientation:UIInterfaceOrientationLandscapeRight];
}
NSLog(@"屏幕向左橫置");
break;
case UIDeviceOrientationLandscapeRight:
if (self.isFullScreen) {
[self interfaceOrientation:UIInterfaceOrientationLandscapeLeft];
}
NSLog(@"屏幕向右橫置");
break;
case UIDeviceOrientationPortrait:
NSLog(@"屏幕直立");
break;
case UIDeviceOrientationPortraitUpsideDown:
NSLog(@"屏幕直立,上下顛倒");
break;
default:
NSLog(@"無法辨識");
break;
}
}
//最后在dealloc中移除通知 和結束設備旋轉的通知
- (void)dealloc{
[[NSNotificationCenter defaultCenter]removeObserver:self];
[[UIDevice currentDevice]endGeneratingDeviceOrientationNotifications];
}
- (BOOL)shouldAutorotate {
return NO;
}
- (BOOL)prefersStatusBarHidden {
if (@available(iOS 13.0, *)) {
return self.isFullScreen;
}
return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskLandscapeLeft|UIInterfaceOrientationMaskLandscapeRight;
}
#pragma mark - private method
- (void)fullScreenAction:(UIButton *)sender {
if (self.isFullScreen) {//如果是全屏,點擊按鈕進入小屏狀態
[self changeToOriginalFrame];
} else {//不是全屏,點擊按鈕進入全屏狀態
[self changeToFullScreen];
}
}
- (void)changeToOriginalFrame {
if (!self.isFullScreen) {
return;
}
[UIView animateWithDuration:AnimationDuration animations:^{
[self interfaceOrientation:UIInterfaceOrientationPortrait];
self.playerView.frame = self.playerFrame;
} completion:^(BOOL finished) {
[self.playerView removeFromSuperview];
[self.playerSuperView addSubview:self.playerView];
self.isFullScreen = NO;
//調用以下方法后,系統會在合適的時間調用prefersStatusBarHidden方法,控制狀態欄的顯示和隱藏,可根據自己的產品控制顯示邏輯
[self setNeedsStatusBarAppearanceUpdate];
}];
}
- (void)changeToFullScreen {
if (self.isFullScreen) {
return;
}
//記錄播放器視圖的父視圖和原始frame值,在實際項目中,可能會嵌套子視圖,所以播放器的superView有可能不是self.view,所以需要記錄父視圖
self.playerSuperView = self.playerView.superview;
self.playerFrame = self.playerView.frame;
CGRect rectInWindow = [self.playerView convertRect:self.playerView.bounds toView:self.mainWindow];
[self.playerView removeFromSuperview];
self.playerView.frame = rectInWindow;
[self.mainWindow addSubview:self.playerView];
//執行旋轉動畫
[UIView animateWithDuration:AnimationDuration animations:^{
UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
if (orientation == UIDeviceOrientationLandscapeRight) {
[self interfaceOrientation:UIInterfaceOrientationLandscapeLeft];
} else {
[self interfaceOrientation:UIInterfaceOrientationLandscapeRight];
}
self.playerView.bounds = CGRectMake(0, 0, CGRectGetHeight(self.mainWindow.bounds), CGRectGetWidth(self.mainWindow.bounds));
self.playerView.center = CGPointMake(CGRectGetMidX(self.mainWindow.bounds), CGRectGetMidY(self.mainWindow.bounds));
} completion:^(BOOL finished) {
self.isFullScreen = YES;
//調用以下方法后,系統會在合適的時間調用prefersStatusBarHidden方法,控制狀態欄的顯示和隱藏,可根據自己的產品控制顯示邏輯
[self setNeedsStatusBarAppearanceUpdate];
}];
}
- (void)interfaceOrientation:(UIInterfaceOrientation)orientation {
if (orientation == UIInterfaceOrientationLandscapeRight || orientation == UIInterfaceOrientationLandscapeLeft) {
// 設置橫屏
[self setOrientationLandscapeConstraint:orientation];
} else if (orientation == UIInterfaceOrientationPortrait) {
// 設置豎屏
[self setOrientationPortraitConstraint];
}
}
- (void)setOrientationLandscapeConstraint:(UIInterfaceOrientation)orientation {
[self toOrientation:orientation];
}
- (void)setOrientationPortraitConstraint {
[self toOrientation:UIInterfaceOrientationPortrait];
}
- (void)toOrientation:(UIInterfaceOrientation)orientation {
// 獲取到當前狀態條的方向------iOS13已經廢棄,所以不能根據狀態欄的方向判斷是否旋轉,手動記錄最后一次的旋轉方向
// UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation;
// 判斷如果當前方向和要旋轉的方向一致,那么不做任何操作
if (self.lastInterfaceOrientation == orientation) { return; }
if (@available(iOS 13.0, *)) {
//iOS 13已經將setStatusBarOrientation廢棄,調用此方法無效
} else {
[[UIApplication sharedApplication] setStatusBarOrientation:orientation animated:NO];
}
self.lastInterfaceOrientation = orientation;
// 獲取旋轉狀態條需要的時間:
[UIView animateWithDuration:AnimationDuration animations:^{
// 更改了狀態條的方向,但是設備方向UIInterfaceOrientation還是正方向的,這就要設置給你播放視頻的視圖的方向設置旋轉
// 給你的播放視頻的view視圖設置旋轉
self.playerView.transform = CGAffineTransformIdentity;
self.playerView.transform = [self getTransformRotationAngleWithOrientation:self.lastInterfaceOrientation];
// 開始旋轉
} completion:^(BOOL finished) {
}];
}
- (CGAffineTransform)getTransformRotationAngleWithOrientation:(UIInterfaceOrientation)orientation {
// 根據要進行旋轉的方向來計算旋轉的角度
if (orientation == UIInterfaceOrientationPortrait) {
return CGAffineTransformIdentity;
} else if (orientation == UIInterfaceOrientationLandscapeLeft){
return CGAffineTransformMakeRotation(-M_PI_2);
} else if(orientation == UIInterfaceOrientationLandscapeRight){
return CGAffineTransformMakeRotation(M_PI_2);
}
return CGAffineTransformIdentity;
}
#pragma mark - setter
- (void)setIsFullScreen:(BOOL)isFullScreen {
_isFullScreen = isFullScreen;
[self.btnFullScreen setTitle:isFullScreen?@"退出全屏":@"全屏" forState:UIControlStateNormal];
}
#pragma mark - getter
- (UIView *)playerView {
if (!_playerView) {
_playerView = [[UIView alloc]init];
_playerView.backgroundColor = [UIColor redColor];
if (@available(iOS 11.0, *)) {
_playerView.frame = CGRectMake(0, self.view.safeAreaInsets.top, CGRectGetWidth(self.view.bounds), CGRectGetWidth(self.view.bounds) * 9 / 16.f);
} else {
_playerView.frame = CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), CGRectGetWidth(self.view.bounds) * 9 / 16.f);
}
}
return _playerView;
}
- (UIButton *)btnFullScreen {
if (!_btnFullScreen) {
_btnFullScreen = [UIButton buttonWithType:UIButtonTypeCustom];
[_btnFullScreen setTitle:@"全屏" forState:UIControlStateNormal];
_btnFullScreen.backgroundColor = [UIColor orangeColor];
[_btnFullScreen addTarget:self action:@selector(fullScreenAction:) forControlEvents:UIControlEventTouchUpInside];
_btnFullScreen.frame = CGRectMake(50, 80, 150, 50);
}
return _btnFullScreen;
}
- (UIWindow *)mainWindow {
if (!_mainWindow) {
if (@available(iOS 13.0, *)) {
_mainWindow = [UIApplication sharedApplication].windows.firstObject;
} else {
_mainWindow = [UIApplication sharedApplication].keyWindow;
}
}
return _mainWindow;
}
@end
結尾
如果你的rootViewController是UIViewController的話,那么用上面的代碼實現全屏效果沒有問題,如果你的rootViewController是UINavigationController或者UITabBarController的話,那么還要增加兩個分類文件。文件內容如下:
一、定義分類UINavigationController+Rotation.h
@implementation UINavigationController (Rotation)
- (BOOL)shouldAutorotate {
return [self.topViewController shouldAutorotate];
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return [self.topViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
二、定義分類UITabBarController+Rotation.h
@implementation UITabBarController (Rotation)
- (BOOL)shouldAutorotate {
return [self.selectedViewController shouldAutorotate];
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return [self.selectedViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return [self.selectedViewController preferredInterfaceOrientationForPresentation];
}
以上就是 短視頻app開發,點擊視頻進行全屏播放的相關代碼,更多內容歡迎關注之后的文章
