/*
当在做视频播放器的时候
,
需要对播放视频的那个view进行旋转操作
,
当控制中心
(
上拉的那个菜单
)
开启旋转屏幕
,
点击全屏按钮或把手机横屏
视图都会全屏
,
全屏状态下
,
点击退出全屏按钮或将屏幕旋转到正方向
,
视图都会退出全屏
;
如果控制中心关闭旋转屏幕
,
旋转屏幕不再能用
,
但进入和退出全屏按钮都是能用的
在这期间
,
状态条也是要改变方向的
,
而且是一直显示的
,
现在专业做视频的
APP
都是这样的
,
下面是怎样实现的屏幕旋转的这一块
:
1.
方案
1 :
强制旋转屏幕
+ SizeClasses
这个需要调用私有
API(
审核可能被拒绝
),
而且现在私有
API
有的也不能用了
,
无法强制退出横屏
,
所以这个方案不可以
;
2.
方案
2 :
这就是我即将说的这个
,
主流视频
APP
都是这么做的
,
一开始我做播放器的时候先就差这一点没有解决
,
蛋疼了好几天
,
现在终于全都解决了
,
以后可能会发
AVPlayer
视频播放的博客
,
包括音量
.
亮度
.
手势等等
,
不过下一篇我还是会总结一些旋转屏幕时遇到的各种问题
;
(首先确定你的程序info.plist添加了要旋转的方向)
*/
@interface
LRLAVPlayerController
()
//用来播放视频的view
@property
(
nonatomic
,
strong
)
LRLAVPlayerView
* avplayerView;
//用来存储这个view的尺寸, 为了模拟存储视频信息的的model
@property
(
nonatomic
,
strong
)
AVPlayerModel
* avModel;
//view的高度
@property
(
nonatomic
,
assign
)
CGFloat
videoHeight;
@end
@implementation
LRLAVPlayerController
//
懒加载的方式来获取一个默认的
model,
用来模拟视频的尺寸
;
-(
AVPlayerModel
*)avModel{
if
(!
_avModel
) {
_avModel
= [[
AVPlayerModel
alloc
]
init
];
_avModel
.
videoSize
=
CGSizeMake
(
SCREEN_WIDTH
,
200
);
}
return
_avModel
;
}
//
实例化
,
一个模拟播放视频的view
-(
void
)initAVPlayerView{
self
.
avplayerView
= [[
NSBundle
mainBundle
]
loadNibNamed
:
@"LRLAVPlayerView"
owner
:
self
options
:
nil
].
lastObject
;
[
self
.
view
addSubview
:
self
.
avplayerView
];
self
.
videoHeight
=
SCREEN_WIDTH
* (
self
.
avModel
.
videoSize
.
height
/
self
.
avModel
.
videoSize
.
width
);
//
使用
masonry
给视图加限制
(autoLayout)
[
self
.
avplayerView
mas_makeConstraints
:^(
MASConstraintMaker
*make) {
make.
top
.
equalTo
(
self
.
view
).
with
.
offset
(
40
);
make.
left
.
equalTo
(
self
.
view
);
make.
right
.
equalTo
(
self
.
view
);
make.
height
.
equalTo
(
@(
self
.
videoHeight
)
);
}];
}
//
点击进入全屏按钮
- (
IBAction
)toLaunch:(
id
)sender {
[
self
toOrientation
:
UIInterfaceOrientationLandscapeLeft
];
}
//
点击退出全屏按钮
- (
IBAction
)toPra:(
id
)sender {
[
self
toOrientation
:
UIInterfaceOrientationPortrait
];
}
//
点击进入
,
退出全屏
,
或者监测到屏幕旋转去调用的方法
-(
void
)toOrientation:(
UIInterfaceOrientation
)orientation{
//
获取到当前状态条的方向
UIInterfaceOrientation
currentOrientation = [
UIApplication
sharedApplication
].
statusBarOrientation
;
//
判断如果当前方向和要旋转的方向一致
,
那么不做任何操作
if
(currentOrientation == orientation) {
return
;
}
//
根据要旋转的方向
,
使用
Masonry
重新修改限制
if
(orientation ==
UIInterfaceOrientationPortrait
) {
[
self
.
avplayerView
mas_remakeConstraints
:^(
MASConstraintMaker
*make) {
make.
top
.
equalTo
(
self
.
view
).
with
.
offset
(
40
);
make.
left
.
equalTo
(
self
.
view
);
make.
right
.
equalTo
(
self
.
view
);
make.
height
.
equalTo
(
@(
self
.
videoHeight
)
);
}];
}
else
{
//
这个地方加判断是为了从全屏的一侧
,
直接到全屏的另一侧不用修改限制
,
否则会出错
;
if
(currentOrientation ==
UIInterfaceOrientationPortrait
) {
[
self
.
avplayerView
mas_remakeConstraints
:^(
MASConstraintMaker
*make) {
make.
width
.
equalTo
(
@(
SCREEN_HEIGHT
)
);
make.
height
.
equalTo
(
@(
SCREEN_WIDTH
)
);
make.
center
.
equalTo
(
self
.
avplayerView
.
superview
);
}];
}
}
//iOS6.0
之后
,
设置状态条的方法能使用的前提是
shouldAutorotate
为
NO,
也就是说这个视图控制器内
,
旋转要关掉
;
//
也就是说在实现这个方法的时候
-(BOOL)shouldAutorotate
返回值要为
NO
[[
UIApplication
sharedApplication
]
setStatusBarOrientation
:orientation
animated
:
NO
];
//
获取旋转状态条需要的时间
:
CGFloat
duration = [
UIApplication
sharedApplication
].
statusBarOrientation
;
[
UIView
beginAnimations
:
nil
context
:
nil
];
//
更改了状态条的方向
,
但是设备方向
UIInterfaceOrientation
还是正方向的
,
这就要设置给你播放视频的视图的方向设置旋转
//
给你的播放视频的
view
视图设置旋转
self
.
avplayerView
.
transform
= [
self
getOrientation
];
[
UIView
setAnimationDuration
:duration];
//
开始旋转
[
UIView
commitAnimations
];
}
//
根据想要旋转的方向来设置旋转
-(
CGAffineTransform
)getOrientation{
//
状态条的方向已经设置过
,
所以这个就是你想要旋转的方向
UIInterfaceOrientation
orientation = [
UIApplication
sharedApplication
].
statusBarOrientation
;
//
根据要进行旋转的方向来计算旋转的角度
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
;
}
//
视图控制器实现的方法
-(
BOOL
)shouldAutorotate{
//iOS6.0
之后
,
要想让状态条可以旋转
,
必须设置视图不能自动旋转
return
NO
;
}
//
这就遇到一个问题
,
可以手动进行设置旋转的方向
,
但我们关掉了自动旋转的开关
,
那么如果我想要既可以手动操作又想自动旋转呢
,
可现在我已经把自动旋转关了呀
,
别急
,
系统提供了一个通知
,
即使不开启旋转也能监测到旋转
- (
void
)viewDidLoad {
[
super
viewDidLoad
];
self
.
view
.
backgroundColor
= [
UIColor
whiteColor
];
//
实例化播放视频的视图
,
实现在最上边
[
self
initAVPlayerView
];
//
获取设备旋转方向的通知
,
即使关闭了自动旋转
,
一样可以监测到设备的旋转方向
[[
UIDevice
currentDevice
]
beginGeneratingDeviceOrientationNotifications
];
[[
NSNotificationCenter
defaultCenter
]
addObserver
:
self
selector
:
@selector
(orientationChanged:)
name
:
UIDeviceOrientationDidChangeNotification
object
:
nil
];
}
//
获取设备的旋转方向
,
然后进行判断如何旋转
UI
-(
void
)orientationChanged:(
NSNotification
*)notification{
UIDeviceOrientation
orientation = [[
UIDevice
currentDevice
]
orientation
];
//
根据监测到的旋转方向
,
进行旋转
switch
(orientation) {
case
UIDeviceOrientationPortrait
:
[
self
toOrientation
:
UIInterfaceOrientationPortrait
];
break
;
case
UIDeviceOrientationLandscapeLeft
:
//UIDeviceOrientation
和
UIInterfaceOrientation
在左右方向上是翻着的
[
self
toOrientation
:
UIInterfaceOrientationLandscapeRight
];
break
;
case
UIDeviceOrientationLandscapeRight
:
[
self
toOrientation
:
UIInterfaceOrientationLandscapeLeft
];
break
;
default
:
break
;
}
}
@end