-
Notifications
You must be signed in to change notification settings - Fork 473
旋转横屏和竖屏全屏
主要三个概念, 分别如下:
- 横屏旋转(
rotation
): 播放器可以从竖屏旋转至横屏, 也可以从横屏旋转至竖屏. - 竖屏全屏(
fitOnScreen
): 播放器从小屏直接撑满屏幕, 并不旋转. - 自动选择
rotation
和fitOnScreen
在实际应用中, 我们可能希望播放器能够如下自动选择:
当播放竖屏拍摄的视频时(Width < Height), 在点击全屏按钮之后, 选择竖屏全屏(fitOnScreen)而不触发旋转.
当播放横屏拍摄的视频时(Width > Height), 在点击全屏按钮之后, 选择横屏旋转(rotation).
我们将从介绍rotation
开始, 接着介绍fitOnScreen
, 最后介绍自动选择
(默认情况下为自动选择)
正常情况下播放器内部封装的旋转管理类将会随着设备方向改变而触发自动旋转. 配置好旋转后, 开发者在创建好播放器时, 无需进行其他操作即可自带旋转功能.
以下是自动旋转相关的自定义设置:
在触发自动旋转之前, 播放器内部已经判断了各种状态, 这足以应付大多数的使用场景. 不过在某些情况下, 我们可能需要加入自己的业务判断来决定是否可以触发旋转, 此时可如下进行操作:
__weak typeof(self) _self = self;
_player.shouldTriggerRotation = ^BOOL(__kindof SJBaseVideoPlayer * _Nonnull player) {
__strong typeof(_self) self = _self;
if ( !self ) return NO;
// 此处添加逻辑, 如果可以旋转, 则返回YES, 否之
// ...
// ...
return YES;
};
自动旋转默认为开启状态, 当需要禁止时, 可如下操作:
_player.rotationManager.disabledAutorotation = YES;
自动旋转支持的方向默认值为SJOrientationMaskAll
, 当需要指定时, 可以如下操作:
_player.rotationManager.autorotationSupportedOrientations = SJOrientationMaskAll;
//
// 可选值如下:
// typedef enum : NSUInteger {
// // 竖屏
// SJOrientationMaskPortrait = 1 << SJOrientation_Portrait,
// // 横屏, Home键在右侧
// SJOrientationMaskLandscapeLeft = 1 << SJOrientation_LandscapeLeft,
// // 横屏, Home键在左侧
// SJOrientationMaskLandscapeRight = 1 << SJOrientation_LandscapeRight,
// // 以上所有方向
// SJOrientationMaskAll = SJOrientationMaskPortrait | SJOrientationMaskLandscapeLeft | SJOrientationMaskLandscapeRight,
// } SJOrientationMask;
在UI层我们可能会添加旋转按钮, 当点击之后需要主动调用旋转, 此时可能遇到的场景如下:
- 旋转至当前的设备方向
- 旋转至指定方向
- 旋转至指定方向, 并设置完成后的回调
请看以下方法, 分别对应以上三点, 根据场景, 直接调用对应方法即可. 需要注意的是, 和自动旋转不同, 该方法为强制旋转, 调用之后播放器可能会强制修改设备方向, 并触发旋转, 不过它们同样受到_player.shouldTriggerRotation
的限制, 当返回NO时, 将不会触发旋转.
- (void)rotate;
- (void)rotate:(SJOrientation)orientation animated:(BOOL)animated;
- (void)rotate:(SJOrientation)orientation animated:(BOOL)animated completion:(void (^ _Nullable)(__kindof SJBaseVideoPlayer *player))block;
播放器提供了旋转之前和旋转完成之后的回调, 具体设置如下:
__weak typeof(self) _self = self;
_player.rotationObserver.onRotatingChanged = ^(id<SJRotationManager> _Nonnull mgr, BOOL isRotating) {
__strong typeof(_self) self = _self;
if ( !self ) return ;
// 可根据 mgr.isFullscreen 来判断是否将要旋转至横屏
if ( isRotating ) {
// 旋转开始
}
else {
// 旋转结束
}
};
这块功能比较简单, 主要接口如下:
///
/// 是否已充满屏幕
///
@property (nonatomic, getter=isFitOnScreen) BOOL fitOnScreen;
- (void)setFitOnScreen:(BOOL)fitOnScreen animated:(BOOL)animated;
- (void)setFitOnScreen:(BOOL)fitOnScreen animated:(BOOL)animated completionHandler:(nullable void(^)(id<SJFitOnScreenManager> mgr))completionHandler;
设置为NO, 即为恢复小屏; 设置为YES, 即为全屏, 整个过程并不会触发旋转:
_player.fitOnScreen = YES;
[_player setFitOnScreen:NO animated:NO];
[_player setFitOnScreen:YES animated:YES completionHandler:^(__kindof SJBaseVideoPlayer * _Nonnull player) {
/// ...
}];
播放器提供了设置之前和完成之后的回调, 具体设置如下:
// 设置之前
_player.fitOnScreenObserver.fitOnScreenWillBeginExeBlock = ^(id<SJFitOnScreenManager> _Nonnull mgr) {
// 可根据 mgr.isFitOnScreen 来判断是否将要全屏
};
// 完成之后
_player.rotationObserver.fitOnScreenDidEndExeBlock = ^(id<SJFitOnScreenManager> _Nonnull mgr) {
};
最后是自动选择. 在默认情况下, 播放器将会根据视频资源的宽高自动选择其中一种方式来管理. 也就是一开始介绍的.
这里需要注意的是, 由于默认为自动选择
, 当开发者仅仅只想使用旋转或竖屏全屏时, 要记得关闭自动选择.
- 如果仅使用旋转功能, 可如下设置:
_player.automaticallyPerformRotationOrFitOnScreen = NO;
该方法将会关闭自动选择, 仅使用竖屏相关功能.
_player.onlyFitOnScreen = YES;
重要的事情说三遍!
- 由于`默认为自动选择`, 当开发者仅仅只想使用旋转或竖屏全屏时, 要记得关闭自动选择.
- 由于`默认为自动选择`, 当开发者仅仅只想使用旋转或竖屏全屏时, 要记得关闭自动选择.
- 由于`默认为自动选择`, 当开发者仅仅只想使用旋转或竖屏全屏时, 要记得关闭自动选择.
_player.automaticallyPerformRotationOrFitOnScreen = NO;
如何先执行竖屏全屏, 待全屏后允许触发旋转?
// 1. 设置播放器需要先竖屏全屏;
_player.needsFitOnScreenFirst = YES;
// 2. 再设置竖屏全屏后, 允许播放器旋转;
_player.allowsRotationInFitOnScreen = YES;