Skip to content

Commit

Permalink
Update lightweightControlLayer
Browse files Browse the repository at this point in the history
  • Loading branch information
changsanjiang committed Mar 22, 2018
1 parent 2d8feb3 commit c3df914
Show file tree
Hide file tree
Showing 24 changed files with 367 additions and 79 deletions.
2 changes: 1 addition & 1 deletion SJVideoPlayer.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Pod::Spec.new do |s|
s.name = 'SJVideoPlayer'
s.version = '2.0.3.8'
s.version = '2.0.4'
s.summary = 'video player.'
s.description = 'https://github.com/changsanjiang/SJVideoPlayer/blob/master/README.md'
s.homepage = 'https://github.com/changsanjiang/SJVideoPlayer'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

NS_ASSUME_NONNULL_BEGIN

@class SJLightweightTopItem;

@interface SJLightweightTopControlModel : NSObject
@property (nonatomic) BOOL alwaysShowTitle;
@property (nonatomic) BOOL isPlayOnScrollView;
Expand All @@ -26,7 +28,9 @@ NS_ASSUME_NONNULL_BEGIN

@property (nonatomic, strong, readonly) SJLightweightTopControlModel *model;

- (void)needUpdateTitle;
- (void)needUpdateLayout;

@property (nonatomic, strong, nullable) NSArray<SJLightweightTopItem *> *topItems;

@property (nonatomic, strong, readonly) UIButton *backBtn;

Expand All @@ -37,5 +41,6 @@ NS_ASSUME_NONNULL_BEGIN
@optional
- (void)clickedBackBtnOnTopControlView:(SJLightweightTopControlView *)view;

- (void)topControlView:(SJLightweightTopControlView *)view clickedItem:(SJLightweightTopItem *)item;
@end
NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,48 @@
#import <Masonry/Masonry.h>
#import "UIView+SJVideoPlayerSetting.h"
#import <SJAttributesFactory/SJAttributeWorker.h>
#import "SJLightweightTopItem.h"
#import <objc/message.h>

NS_ASSUME_NONNULL_BEGIN
@interface SJLightweightTopTmp : NSObject

- (instancetype)initWithItem:(SJLightweightTopItem *)item;

@property (nonatomic, strong, readonly) SJLightweightTopItem *item;

@property (nonatomic, copy, nullable) void(^updatedExeBlock)(SJLightweightTopTmp *tmp);

@end

@implementation SJLightweightTopTmp

- (instancetype)initWithItem:(SJLightweightTopItem *)item {
self = [super init];
if ( !self ) return nil;
_item = item;
[item addObserver:self forKeyPath:kLightweightTopItemImageNameKeyPath options:NSKeyValueObservingOptionNew context:nil];
return self;
}

- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change context:(nullable void *)context {
if ( [keyPath isEqualToString:kLightweightTopItemImageNameKeyPath] ) {
if ( _updatedExeBlock ) _updatedExeBlock(self);
}
}

- (void)dealloc {
[_item removeObserver:self forKeyPath:kLightweightTopItemImageNameKeyPath];
}
@end

@interface SJLightweightTopControlView () {
SJLightweightTopControlModel *_model;
}

@property (nonatomic, strong, readonly) UILabel *titleLabel;
@property (nonatomic, strong, readonly) UIView *itemsContainerView;
@property (nonatomic, strong, readwrite, nullable) NSArray<SJLightweightTopTmp *> *observerItems;

@end

Expand Down Expand Up @@ -49,7 +84,57 @@ - (void)setIsFullscreen:(BOOL)isFullscreen {
[self invalidateIntrinsicContentSize];
}

- (void)needUpdateTitle {
- (void)setTopItems:(NSArray<SJLightweightTopItem *> * __nullable)topItems {
if ( topItems == _topItems ) return;
_observerItems = nil;

_topItems = topItems;

[_itemsContainerView.subviews enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
[obj removeFromSuperview];
}];

NSMutableArray<SJLightweightTopTmp *> *observerItemsM = [NSMutableArray array];
[topItems enumerateObjectsUsingBlock:^(SJLightweightTopItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
UIButton *btn = [SJUIButtonFactory buttonWithImageName:obj.imageName target:self sel:@selector(clickedTopItem:) tag:idx];
[_itemsContainerView addSubview:btn];
if ( idx == 0 ) {
[btn mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.bottom.offset(0);
make.size.offset(44);
}];
}
else {
UIButton *beforeBtn = _itemsContainerView.subviews[(int)idx - 1];
[btn mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.bottom.equalTo(beforeBtn);
make.leading.equalTo(beforeBtn.mas_trailing);
if ( idx == (int)topItems.count - 1 ) {
make.trailing.offset(0);
}
}];
}
// update image
SJLightweightTopTmp *observer = [[SJLightweightTopTmp alloc] initWithItem:obj];
observer.updatedExeBlock = ^(SJLightweightTopTmp * _Nonnull tmp) {
[btn setImage:[UIImage imageNamed:tmp.item.imageName] forState:UIControlStateNormal];
};
[observerItemsM addObject:observer];
}];

_observerItems = observerItemsM;
}

- (void)clickedTopItem:(UIButton *)btn {
if ( [self.delegate respondsToSelector:@selector(topControlView:clickedItem:)] ) {
[self.delegate topControlView:self clickedItem:_topItems[btn.tag]];
}
}

- (void)needUpdateLayout {

self.itemsContainerView.hidden = (!_isFullscreen && self.model.isPlayOnScrollView);

if ( self.isFullscreen ) {
self.titleLabel.hidden = NO;
}
Expand Down Expand Up @@ -156,3 +241,4 @@ - (UIView *)itemsContainerView {

@implementation SJLightweightTopControlModel
@end
NS_ASSUME_NONNULL_END
28 changes: 28 additions & 0 deletions SJVideoPlayer/Resource/SJLightweightTopItem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// SJLightweightTopItem.h
// SJVideoPlayerProject
//
// Created by BlueDancer on 2018/3/22.
// Copyright © 2018年 SanJiang. All rights reserved.
//

#import <UIKit/UIKit.h>

extern NSString *const kLightweightTopItemImageNameKeyPath;

@interface SJLightweightTopItem : NSObject

- (instancetype)initWithFlag:(NSInteger)flag imageName:(NSString *)imageName;

/**
Player will observe the change in this property.
Will do the appropriate update.
If you change the image of item, the player will also be updated.
readwrite.
*/
@property (nonatomic, copy) NSString *imageName;

@property (nonatomic, assign, readonly) NSInteger flag;

@end
22 changes: 22 additions & 0 deletions SJVideoPlayer/Resource/SJLightweightTopItem.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// SJLightweightTopItem.m
// SJVideoPlayerProject
//
// Created by BlueDancer on 2018/3/22.
// Copyright © 2018年 SanJiang. All rights reserved.
//

#import "SJLightweightTopItem.h"

NSString *const kLightweightTopItemImageNameKeyPath = @"imageName";

@implementation SJLightweightTopItem

- (instancetype)initWithFlag:(NSInteger)flag imageName:(NSString *)imageName {
self = [super init];
if ( !self ) return nil;
_flag = flag;
_imageName = imageName;
return self;
}
@end
73 changes: 45 additions & 28 deletions SJVideoPlayer/SJLightweightControlLayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ @interface SJLightweightControlLayer () <SJLightweightBottomControlViewDelegate,
@property (nonatomic, strong, readonly) SJVideoPlayerControlMaskView *bottomMaskView;
@property (nonatomic, strong, readonly) SJVideoPlayerDraggingProgressView *draggingProgressView;

@property (nonatomic, strong, nullable) SJVideoPlayer *videoPlayer;
@property (nonatomic, weak, nullable) SJVideoPlayer *videoPlayer; // need weak ref.
@property (nonatomic, strong, readonly) SJLoadingView *loadingView;
@property (nonatomic, strong, readonly) SJSlider *bottomSlider;
@property (nonatomic, strong, nullable) SJVideoPlayerSettings *settings;
Expand All @@ -68,6 +68,34 @@ - (instancetype)init {
return self;
}


- (void)videoPlayer:(SJVideoPlayer *)videoPlayer prepareToPlay:(SJVideoPlayerURLAsset *)asset {
// back btn
if ( videoPlayer.isPlayOnScrollView ) {
[_backBtn removeFromSuperview];
_backBtn = nil;
}
else {
if ( !_backBtn.superview ) {
[self.containerView addSubview:self.backBtn];
_backBtn.disappearType = SJDisappearType_Alpha;
[_backBtn mas_remakeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(_topControlView.backBtn);
}];
}
}
self.topControlView.topItems = videoPlayer.topControlItems;
self.topControlView.model.isPlayOnScrollView = videoPlayer.isPlayOnScrollView;
self.topControlView.model.alwaysShowTitle = asset.alwaysShowTitle;
self.topControlView.model.title = asset.title;
[self.topControlView needUpdateLayout];

self.bottomSlider.value = 0;
self.bottomControlView.progress = 0;
self.bottomControlView.bufferProgress = 0;
[self.bottomControlView setCurrentTimeStr:videoPlayer.currentTimeStr totalTimeStr:videoPlayer.totalTimeStr];
}

- (BOOL)controlLayerDisappearCondition {
return YES;
}
Expand All @@ -82,7 +110,8 @@ - (void)installedControlViewToVideoPlayer:(__kindof SJBaseVideoPlayer *)videoPla

- (void)controlLayerNeedAppear:(nonnull __kindof SJBaseVideoPlayer *)videoPlayer {
UIView_Animations(CommonAnimaDuration, ^{

if ( videoPlayer.isFullScreen ) [_backBtn appear];

if ( SJVideoPlayerPlayState_PlayFailed == videoPlayer.state ) {
[_centerControlView failedState];
[_centerControlView appear];
Expand Down Expand Up @@ -119,6 +148,8 @@ - (void)controlLayerNeedAppear:(nonnull __kindof SJBaseVideoPlayer *)videoPlayer

- (void)controlLayerNeedDisappear:(nonnull __kindof SJBaseVideoPlayer *)videoPlayer {
UIView_Animations(CommonAnimaDuration, ^{
if ( videoPlayer.isFullScreen ) [_backBtn disappear];

if ( SJVideoPlayerPlayState_PlayFailed != videoPlayer.state ) {
[_topControlView disappear];
[_bottomControlView disappear];
Expand Down Expand Up @@ -148,7 +179,7 @@ - (void)videoPlayer:(__kindof SJBaseVideoPlayer *)videoPlayer stateChanged:(SJVi
case SJVideoPlayerPlayState_Unknown: {
[videoPlayer controlLayerNeedDisappear];
self.topControlView.model.title = nil;
[self.topControlView needUpdateTitle];
[self.topControlView needUpdateLayout];
self.bottomSlider.value = 0;
self.bottomControlView.progress = 0;
self.bottomControlView.bufferProgress = 0;
Expand Down Expand Up @@ -187,30 +218,6 @@ - (void)videoPlayer:(__kindof SJBaseVideoPlayer *)videoPlayer stateChanged:(SJVi
}
}

- (void)videoPlayer:(SJVideoPlayer *)videoPlayer prepareToPlay:(SJVideoPlayerURLAsset *)asset {
self.backBtn.hidden = videoPlayer.isPlayOnScrollView;
if ( videoPlayer.isPlayOnScrollView ) {
[_backBtn removeFromSuperview];
}
else {
if ( !_backBtn.superview ) {
[self.containerView addSubview:self.backBtn];
[_backBtn mas_remakeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(_topControlView.backBtn);
}];
}
}
self.topControlView.model.isPlayOnScrollView = videoPlayer.isPlayOnScrollView;
self.topControlView.model.alwaysShowTitle = asset.alwaysShowTitle;
self.topControlView.model.title = asset.title;
[self.topControlView needUpdateTitle];

self.bottomSlider.value = 0;
self.bottomControlView.progress = 0;
self.bottomControlView.bufferProgress = 0;
[self.bottomControlView setCurrentTimeStr:videoPlayer.currentTimeStr totalTimeStr:videoPlayer.totalTimeStr];
}

- (void)videoPlayer:(SJVideoPlayer *)videoPlayer
currentTime:(NSTimeInterval)currentTime currentTimeStr:(NSString *)currentTimeStr
totalTime:(NSTimeInterval)totalTime totalTimeStr:(NSString *)totalTimeStr {
Expand All @@ -226,6 +233,13 @@ - (void)videoPlayer:(SJVideoPlayer *)videoPlayer loadedTimeProgress:(float)progr
}

- (void)videoPlayer:(__kindof SJBaseVideoPlayer *)videoPlayer willRotateView:(BOOL)isFull {
if ( _backBtn ) {
if ( videoPlayer.isFullScreen ) [_backBtn disappear];
else if ( !videoPlayer.isPlayOnScrollView ) [_backBtn appear];
else [_backBtn disappear];
}


if ( isFull && !videoPlayer.URLAsset.isM3u8 ) {
_draggingProgressView.style = SJVideoPlayerDraggingProgressViewStylePreviewProgress;
}
Expand All @@ -234,7 +248,7 @@ - (void)videoPlayer:(__kindof SJBaseVideoPlayer *)videoPlayer willRotateView:(BO
}

_topControlView.isFullscreen = isFull;
[_topControlView needUpdateTitle];
[_topControlView needUpdateLayout];

UIView_Animations(CommonAnimaDuration, ^{
[self.controlView layoutIfNeeded];
Expand Down Expand Up @@ -438,6 +452,9 @@ - (SJLightweightTopControlView *)topControlView {
_topControlView.delegate = self;
return _topControlView;
}
- (void)topControlView:(SJLightweightTopControlView *)view clickedItem:(SJLightweightTopItem *)item {
if ( _videoPlayer.clickedTopControlItemExeBlock ) _videoPlayer.clickedTopControlItemExeBlock(_videoPlayer, item);
}
- (void)clickedBackBtnOnTopControlView:(SJLightweightTopControlView *)view {
if ( _videoPlayer.isFullScreen ) {
SJSupportedRotateViewOrientation supported = _videoPlayer.supportedRotateViewOrientation;
Expand Down
14 changes: 13 additions & 1 deletion SJVideoPlayer/SJVideoPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#import "SJVideoPlayerURLAsset+SJControlAdd.h"
#import "SJVideoPlayerMoreSettingSecondary.h"
#import "SJFilmEditingResultShareItem.h"
#import "SJLightweightTopItem.h"

NS_ASSUME_NONNULL_BEGIN

Expand Down Expand Up @@ -64,7 +65,18 @@ NS_ASSUME_NONNULL_BEGIN
@end


#pragma mark - 配置`默认控制层`
#pragma mark - Setting lightweight control layer

@interface SJVideoPlayer (SettingLightweightControlLayer)

@property (nonatomic, copy, nullable) NSArray<SJLightweightTopItem *> *topControlItems;

@property (nonatomic, copy, nullable) void(^clickedTopControlItemExeBlock)(SJVideoPlayer *player, SJLightweightTopItem *item);

@end


#pragma mark - Setting default control layer

@interface SJVideoPlayer (SettingDefaultControlLayer)

Expand Down
24 changes: 23 additions & 1 deletion SJVideoPlayer/SJVideoPlayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,29 @@ - (instancetype)_init {
@end


#pragma mark - 默认控制层
#pragma mark -

@implementation SJVideoPlayer (SettingLightweightControlLayer)

- (void)setTopControlItems:(NSArray<SJLightweightTopItem *> *)topControlItems {
objc_setAssociatedObject(self, @selector(topControlItems), topControlItems, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSArray<SJLightweightTopItem *> *)topControlItems {
return objc_getAssociatedObject(self, _cmd);
}

- (void)setClickedTopControlItemExeBlock:(void (^)(SJVideoPlayer * _Nonnull, SJLightweightTopItem * _Nonnull))clickedTopControlItemExeBlock {
objc_setAssociatedObject(self, @selector(clickedTopControlItemExeBlock), clickedTopControlItemExeBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (void (^)(SJVideoPlayer * _Nonnull, SJLightweightTopItem * _Nonnull))clickedTopControlItemExeBlock {
return objc_getAssociatedObject(self, _cmd);
}
@end


#pragma mark -

@implementation SJVideoPlayer (SettingDefaultControlLayer)

Expand Down
Loading

0 comments on commit c3df914

Please sign in to comment.