1

播放器的控制层有很多种, 例如在Cell上播放, 与在单一的视图上, 控制层显示的可能不一样. 有的小伙伴可能会在一个控制层中加上判断去显示不同的UI. 我在这里提供另外一种方法, 就是控制层切换器.

切换器的好处:

  • 模块化控制层
  • 控制层的复用(大家可以把写好的控制层push上来, 我集成到pod中)

图解

下图为SJVideoPlayer默认的控制层:

  • 默认的边缘控制层
  • 默认的边缘控制.gif
  • 默认的剪辑控制层
  • 默认的剪辑控制层.gif

在上图可以看到, 当点击边缘控制层的剪辑按钮后, 边缘控制层退出, 同时剪辑控制层出现(截屏/剪辑/GIF).

所以切换的思路就是每个控制层, 都默认实现一个入场和一个退出的方法. 在切换时, 通过调用控制层入场(new control layer)还是退出(old control layer)的方法进行切换. 不过, 这个功能需要两个前提条件

前提:

  • 基于SJVideoPlayer
  • 每个控制层需实现退出和进场方法

切换器的功能:

目前切换器的功能如下:

  • 能够 根据标识 添加/删除/切换 控制层
  • 控制层的标识可以自己扩展, 也可以通过相同的标识去替换一个原始存在的控制层
  • 扩展标识.png

相关类:

相关类分别是切换器(SJControlLayerSwitcher)和数据载体(SJControlLayerCarrier)
我们先预览一下代码, 看开头的的 init方法 就行:

#pragma mark - switcher 
@interface SJVideoPlayer : SJBaseVideoPlayer
/// 1. 控制层切换器
@property (nonatomic, strong, readonly) SJControlLayerSwitcher *switcher; 
// ...
@end
@implementation SJVideoPlayer
- (instancetype)init {
    self = [super init];
    if ( !self ) return nil;
    /// 2. 添加一个控制层
    [self.switcher addControlLayer:self.defaultEdgeCarrier];
    /// 3. 切换到添加的控制层
    [self.switcher switchControlLayerForIdentitfier:SJControlLayer_Edge toVideoPlayer:self];
    return self;
}
// ...
@end

/// 切换器
/// 1. 当前控制层标识
/// 2. 前一个控制层的标识
/// 3. 切换控制层
/// 4. 添加/删除/获取 控制层
#pragma mark - SJControlLayerSwitcher - 切换器
@interface SJControlLayerSwitcher : NSObject
- (instancetype)init;
/// 当前标识(控制层的标识)
@property (nonatomic, readonly) SJControlLayerIdentifier currentIdentifier;  
/// 前一个标识
@property (nonatomic, readonly) SJControlLayerIdentifier previousIdentifier; 

/// 切换控制层
/// 将当前的控制层切换为指定标识的控制层
- (void)switchControlLayerForIdentitfier:(SJControlLayerIdentifier)identifier
                           toVideoPlayer:(__kindof SJBaseVideoPlayer *)videoPlayer;
- (BOOL)switchToPreviousControlLayer; // 切换到之前的控制层

/// 添加一个控制层
- (void)addControlLayer:(SJControlLayerCarrier *)carrier;
/// 删除一个控制层
- (void)deleteControlLayerForIdentifier:(SJControlLayerIdentifier)identifier;
/// 根据标识获取一个控制层
- (nullable SJControlLayerCarrier *)controlLayerForIdentifier:(SJControlLayerIdentifier)identifier;
@end

/// 控制层数据载体
/// 1. 播放器的DataSource
/// 2. 播放器的Delegate
/// 3. 控制层退出执行的block
/// 4. 控制层入场执行的block
#pragma mark - SJControlLayerIdentifier & SJControlLayerCarrier
typedef long SJControlLayerIdentifier;

@interface SJControlLayerCarrier : NSObject
@property (nonatomic, strong, readonly) id <SJVideoPlayerControlLayerDataSource> dataSource;
@property (nonatomic, strong, readonly) id <SJVideoPlayerControlLayerDelegate> delegate;
@property (nonatomic, readonly) SJControlLayerIdentifier identifier;

@property (nonatomic, copy, readonly) void(^exitExeBlock)(SJControlLayerCarrier *carrier);
@property (nonatomic, copy, readonly) void(^restartExeBlock)(SJControlLayerCarrier *carrier);
@end

以上为切换器的源实现, 添加-删除-切换-查询 这些功能.

在init方法中, 我默认添加了一个边缘控制层, 并且通过切换器切换到了该控制层. 我写了一个 Demo在这里:
一个简单的实现.gif

尾巴

项目地址: https://github.com/changsanji...

我的邮箱: changsanjiang@gmail.com

如果您有什么建议, 望请联系我!


changsanjiang
14 声望2 粉丝