视频播放器播放器专题iOS开发笔记

浅谈iOS视频全屏播放、屏幕旋转与控制器转场动画,妈妈再也不用担

2017-10-19  本文已影响262人  嘴爷

来一波大神的写的https://github.com/DevLiYang/LYCustomTransition 这里有各种各样的转场动画(交互式、非交互式),微信的、酷狗的等等…

还有https://github.com/alanwangmodify/WXSTransition 这位大神挺狠,50种动画

全屏的实质

如果摒弃掉Apple不建议的方法,那么在IOS8之后,横屏全屏的实质是弹出一个控制器,控制器支持的方向为横屏即可。我们看到的视频旋转实际上是定义了一个控制器切换的转场动画

  • 竖屏切横屏:弹出一个横屏的控制器
  • 横屏返回竖屏:dismiss掉横屏控制器

需求

  • 可手动触发旋转
  • 可跟随手机屏幕旋转(不论设备是否开启屏幕旋转功能)

如下图

sp.gif hp.gif

准备阶段

一、我们在TARGET中经常会只保留一个方向,我建议三个都勾选上,控制器的方向我个人觉得控制器自己去控制就好。

plist.png

二、竖屏控制器 VerticallyVideoVC

控制器内要实现四个方法


-(BOOL)prefersStatusBarHidden{
    
    return NO;
}

-(BOOL)shouldAutorotate{
    
    return NO;
}

-(UIInterfaceOrientationMask)supportedInterfaceOrientations{
    
    return UIInterfaceOrientationMaskPortrait;
}

-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
    
    return UIInterfaceOrientationPortrait;
}

四个方法都比较好理解,不再赘述。

这里要注意一下的就是,如果这个控制器带有导航的,那么屏幕方向由导航去控制的,所以要在 NavigationController 中去控制,为了方便我们可以自定义一个导航,并实现上面的几个方法

- (BOOL)shouldAutorotate{
    
    return [[self.viewControllers lastObject] shouldAutorotate];
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
    
    return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    
    return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}

-(BOOL)prefersStatusBarHidden{
    
    return [[self.viewControllers lastObject] prefersStatusBarHidden];
}

其实就是把屏幕的方向交给了导航栈顶的控制器去控制。

三、横屏控制器 HorizontallyVideoVC

在这个控制器内同样也实现上面的几个方法


-(BOOL)prefersStatusBarHidden{
    
    return NO;
}

-(BOOL)shouldAutorotate{
    
    return NO;
}

-(UIStatusBarStyle)preferredStatusBarStyle{
    
    return UIStatusBarStyleDefault;
}

-(UIInterfaceOrientationMask)supportedInterfaceOrientations{
    
    return UIInterfaceOrientationMaskLandscapeRight;
}

-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{

    return UIInterfaceOrientationLandscapeRight;
}

到此为止,如果直接用竖屏控制区去present出横屏控制器的话就是我们需要的横屏到竖屏的效果,通过状态栏可以看出,所以状态栏目前都没有隐藏

但是发现没有动画啊,就解决了横屏到竖屏的转换。那么这里就需要定义一个动画,用来实现横竖屏的过渡,下面是第四个准备工作,负责转场动画的类。

四、转场动画控制 RotateAnimator

在控制器跳转前会找一个delegate去调用下跳转过渡的方法,如果你没有实现这个方法就默认用系统的方法,如果你实现了,就会按照你的方法执行。控制器有个transitioningDelegate属性,就是不管PUSH POP PRESENT DISMISS 任意一种方式跳转,都会让 transitioningDelegate 这个对象调用对应的协议方法去实现自定义的转场动画。

UIViewControllerTransitioningDelegate 这里需要指定一个转场动画的实现者,实现这要去实现UIViewControllerAnimatedTransitioning

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext;

方法,进而实现自定义的转场动画。

说的我自己都晕晕乎乎的,肯定没人愿意细看。针对视频旋转这种,我就给简化下:横屏控制器的transitioningDelegate 就是这个 RotateAnimator对象,然后只需要实现如下方法

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext;

大概画了一个图,如下原理

  • 调用系统的方法直接走上面的路径
  • 自定义转场动画要遵循下面的路径
zhuanchang.png

我把中间的两个给交给 RotateAnimator 去处理了

这个方法里做你需要的动画即可。具体动画可参照 git 上的 DEMO

五、设备旋转监听 UIDeviceOrientationDidChangeNotification

这个方法任何时候都适应,即使设备方向是锁定的

notification.object; 就是 UIDevice 对象,这里可以拿到屏幕的方向


UIDeviceOrientationPortrait,            // Device oriented vertically, home button on the bottom
UIDeviceOrientationPortraitUpsideDown,  // Device oriented vertically, home button on the top
UIDeviceOrientationLandscapeLeft,       // Device oriented horizontally, home button on the right
UIDeviceOrientationLandscapeRight,      // Device oriented horizontally, home button on the left
     

===

转场动画透漏的设计模式

MVC被很多人诟病可能主要的原因不是设计模式不好,而是C层成为了各种视图、业务逻辑的delegatetarget 等,从而把控制器变的很臃肿。

  • tableView.delegate = self
  • textView.delegate = self
  • collectionView.delegate = self
  • customView.delegate = self
  • manager.delegate = self
  • addTarget:self
  • addObserver:self
  • ...

然后就是mark了各种各样的delegate方法,所以各路大神就提出来给控制器减压,分离点东西给别人干,从此就很少能看到 delegate = self 这样的代码了。对于转场动画也是,Apple可以让你自己指定一个delegate 去完成转场之前的方法实现自定义转场动画。

其实在storyboard中一直也有这么个角色,那就是可以拖拽NSObject

NSObject.png

我们创建一个类继承NSObject,如果这个类遵守UIPickerViewDataSource, UIPickerViewDelegate 关联到这个NSObject上

picker.png pickerShow.png

那么我就可以把一堆协议方法分离到这个类里,去帮助我们控制器减压。其实有个更大的好处就是在复用的时候,我们可以直接使用,也让分离代码变得更容易。在转场动画这个示例里 RotateAnimator 就是这个NSObject对象。

同理这种思想可以应用到播放器的开发中,第一次接触的这种模式是参考百度视频的代码。大概就如下的结构,个人觉得优势在于可以随便替换视图或者是视频播放器,比如我不用百度的播放器了,UI上的任何东西都不用动,只动播放逻辑部分即可。不管播放器在控制器中,还是在cell中,都能够很多好的移植。

bdPlayer.png

感谢您阅读完毕,如有疑问,欢迎添加QQ:714387953(蜗牛上高速)。
github:https://github.com/yhl714387953/ScreenRotate
如果有错误,欢迎指正,一起切磋,共同进步
如果喜欢可以Follow、Star、Fork,都是给我最大的鼓励

上一篇 下一篇

猜你喜欢

热点阅读