diff --git a/SJVideoPlayer.podspec b/SJVideoPlayer.podspec index 05669490f..15e8a2dd9 100644 --- a/SJVideoPlayer.podspec +++ b/SJVideoPlayer.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = 'SJVideoPlayer' - s.version = '2.2.1.1' + s.version = '2.2.2' s.summary = 'video player.' s.description = 'https://github.com/changsanjiang/SJVideoPlayer/blob/master/README.md' s.homepage = 'https://github.com/changsanjiang/SJVideoPlayer' diff --git a/SJVideoPlayer/Adapters/Core/SJEdgeControlLayerItemAdapter.h b/SJVideoPlayer/Adapters/Core/SJEdgeControlLayerItemAdapter.h index bd0ba7303..4c76ff670 100644 --- a/SJVideoPlayer/Adapters/Core/SJEdgeControlLayerItemAdapter.h +++ b/SJVideoPlayer/Adapters/Core/SJEdgeControlLayerItemAdapter.h @@ -31,6 +31,7 @@ NS_ASSUME_NONNULL_BEGIN - (NSInteger)indexOfItemForTag:(SJEdgeControlButtonItemTag)tag; - (nullable NSArray *)itemsWithRange:(NSRange)range; - (BOOL)itemsIsHiddenWithRange:(NSRange)range; // 此范围的items是否已隐藏 +- (BOOL)itemContainsPoint:(CGPoint)point; // 某个点是否在item中 /// 添加 /// - 注意: 添加后, 记得调用刷新 @@ -47,6 +48,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)exchangeItemAtIndex:(NSInteger)idx1 withItemAtIndex:(NSInteger)idx2; - (void)exchangeItemForTag:(SJEdgeControlButtonItemTag)tag1 withItemForTag:(SJEdgeControlButtonItemTag)tag2; + @property (nonatomic, strong, readonly) UIView *view; @property (nonatomic, readonly) NSInteger itemCount; - (instancetype)init NS_UNAVAILABLE; diff --git a/SJVideoPlayer/Adapters/Core/SJEdgeControlLayerItemAdapter.m b/SJVideoPlayer/Adapters/Core/SJEdgeControlLayerItemAdapter.m index 590bf1369..c66d54208 100644 --- a/SJVideoPlayer/Adapters/Core/SJEdgeControlLayerItemAdapter.m +++ b/SJVideoPlayer/Adapters/Core/SJEdgeControlLayerItemAdapter.m @@ -16,7 +16,7 @@ @interface SJCollectionViewLayout : UICollectionViewLayout @end @implementation SJCollectionViewLayout { - @private NSMutableArray *_layoutAttributes; + @public NSMutableArray *_layoutAttributes; } - (instancetype)init { self = [super init]; @@ -284,6 +284,13 @@ - (BOOL)itemsIsHiddenWithRange:(NSRange)range { } return YES; } +- (BOOL)itemContainsPoint:(CGPoint)point { + for ( UICollectionViewLayoutAttributes *atr in _layout->_layoutAttributes ) { + if ( CGRectContainsPoint(atr.frame, point) ) + return YES; + } + return NO; +} #pragma mark - - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { diff --git a/SJVideoPlayer/SJEdgeControlLayer/SJEdgeControlLayer.m b/SJVideoPlayer/SJEdgeControlLayer/SJEdgeControlLayer.m index f4b45092b..83fb4817f 100644 --- a/SJVideoPlayer/SJEdgeControlLayer/SJEdgeControlLayer.m +++ b/SJVideoPlayer/SJEdgeControlLayer/SJEdgeControlLayer.m @@ -260,6 +260,14 @@ - (BOOL)_canDisappearFor_TopAdapter { return YES; } +- (BOOL)_canTriggerGesturesFor_TopAdapter:(CGPoint)location { + if ( CGRectContainsPoint(_topAdapter.view.frame, location) && + [_topAdapter itemContainsPoint:[self.controlView convertPoint:location toView:_topAdapter.view]] ) + return NO; + + return YES; +} + - (void)clickedBackItem:(SJEdgeControlButtonItem *)item { if ( _videoPlayer.useFitOnScreenAndDisableRotation ) { if ( _videoPlayer.isFitOnScreen ) { @@ -397,6 +405,14 @@ - (BOOL)_canDisappearFor_LeftAdapter { return YES; } +- (BOOL)_canTriggerGesturesFor_LeftAdapter:(CGPoint)location { + if ( CGRectContainsPoint(_leftAdapter.view.frame, location) && + [_leftAdapter itemContainsPoint:[self.controlView convertPoint:location toView:_leftAdapter.view]] ) + return NO; + + return YES; +} + /// item actions - (void)clickedLockItem:(SJEdgeControlButtonItem *)item { self.videoPlayer.lockedScreen = !self.videoPlayer.isLockedScreen; @@ -578,6 +594,14 @@ - (BOOL)_canDisappearFor_BottomAdapter { return !slider.isDragging; } +- (BOOL)_canTriggerGesturesFor_BottomAdapter:(CGPoint)location { + if ( CGRectContainsPoint(_bottomAdapter.view.frame, location) && + [_bottomAdapter itemContainsPoint:[self.controlView convertPoint:location toView:_bottomAdapter.view]] ) + return NO; + + return YES; +} + - (void)clickedPlayItem:(SJEdgeControlButtonItem *)item { if ( [self.videoPlayer playStatus_isPlaying] ) [self.videoPlayer pause]; else [self.videoPlayer play]; @@ -651,6 +675,13 @@ - (BOOL)_canDisapearFor_RightAdapter { return YES; } +- (BOOL)_canTriggerGesturesFor_RightAdapter:(CGPoint)location { + if ( CGRectContainsPoint(_rightAdapter.view.frame, location) && + [_rightAdapter itemContainsPoint:[self.controlView convertPoint:location toView:_rightAdapter.view]] ) + return NO; + + return YES; +} #pragma mark - center @synthesize replayButton = _replayButton; @@ -725,7 +756,7 @@ - (SJLoadingView *)loadingView { - (SJVideoPlayerDraggingProgressView *)draggingProgressView { if ( _draggingProgressView ) return _draggingProgressView; _draggingProgressView = [SJVideoPlayerDraggingProgressView new]; - [_draggingProgressView setPreviewImage:_videoPlayer.placeholder]; + [_draggingProgressView setPreviewImage:_videoPlayer.placeholderImageView.image]; [self.controlView addSubview:_draggingProgressView]; [self _hidden:_draggingProgressView animated:NO]; [_draggingProgressView mas_makeConstraints:^(MASConstraintMaker *make) { @@ -787,15 +818,21 @@ - (UIView *)controlView { return self; } +/// 是否可以触发播放器的手势 - (BOOL)triggerGesturesCondition:(CGPoint)location { - if ( CGRectContainsPoint( _topContainerView.frame, location ) || - CGRectContainsPoint( _leftContainerView.frame, location ) || - CGRectContainsPoint( _bottomContainerView.frame, location ) || - CGRectContainsPoint( _rightContainerView.frame, location ) || - CGRectContainsPoint( _previewView.frame, location) ) return NO; + if ( ![self _canTriggerGesturesFor_TopAdapter:location] || + ![self _canTriggerGesturesFor_LeftAdapter:location] || + ![self _canTriggerGesturesFor_BottomAdapter:location] || + ![self _canTriggerGesturesFor_RightAdapter:location] ) return NO; + + if ( CGRectContainsPoint( _previewView.frame, location) ) + return NO; + return YES; } +/// 当播放器尝试自动隐藏控制层时, 将会调用这个方法 +/// - 返回Yes, 将隐藏控制层 - (BOOL)controlLayerDisappearCondition { if ( [self _canDisappearFor_BottomAdapter] && [self _canDisappearFor_LeftAdapter] && diff --git a/SJVideoPlayer/SJVideoPlayer.m b/SJVideoPlayer/SJVideoPlayer.m index af17c0fea..d60c0c6dd 100644 --- a/SJVideoPlayer/SJVideoPlayer.m +++ b/SJVideoPlayer/SJVideoPlayer.m @@ -130,12 +130,17 @@ - (instancetype)_init { _recorder = [[SJVideoPlayerControlSettingRecorder alloc] initWithSettings:^(SJEdgeControlLayerSettings * _Nonnull setting) { __strong typeof(_self) self = _self; if ( !self ) return ; - if ( [SJVideoPlayerSettings commonSettings].placeholder ) self.placeholder = [SJVideoPlayerSettings commonSettings].placeholder; + [self _updateCommonProperties]; }]; - self.placeholder = [SJVideoPlayerSettings commonSettings].placeholder; + [self _updateCommonProperties]; return self; } +- (void)_updateCommonProperties { + if ( self.placeholderImageView.image != SJVideoPlayerSettings.commonSettings.placeholder ) + self.placeholderImageView.image = SJVideoPlayerSettings.commonSettings.placeholder; +} + @synthesize switcher = _switcher; - (SJControlLayerSwitcher *)switcher { if ( _switcher ) return _switcher; diff --git a/SJVideoPlayerProject/Pods/SJBaseVideoPlayer/SJBaseVideoPlayer/SJBaseVideoPlayer.h b/SJVideoPlayerProject/Pods/SJBaseVideoPlayer/SJBaseVideoPlayer/SJBaseVideoPlayer.h index a0bb93ff5..bd50968e9 100644 --- a/SJVideoPlayerProject/Pods/SJBaseVideoPlayer/SJBaseVideoPlayer/SJBaseVideoPlayer.h +++ b/SJVideoPlayerProject/Pods/SJBaseVideoPlayer/SJBaseVideoPlayer/SJBaseVideoPlayer.h @@ -95,14 +95,12 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, strong, readonly, nullable) NSError *error; - /** - The placeholder image when loading video. - 加载视频时的占位图. 加载视频初始化时, 会短暂黑屏, 建议设置一下占位图. - - readwrite. + This imageView will show up during the loading of the video(player.status is unknown or prepare). + - When initializing the loaded video, it may be a short black screen. It is recommended to set the placeholderImage. + - 初始化加载视频时, 可能会短暂黑屏, 建议设置一下占位图. */ -@property (nonatomic, strong, nullable) UIImage *placeholder; +@property (nonatomic, strong, readonly) UIImageView *placeholderImageView; /** default is `AVLayerVideoGravityResizeAspect`. @@ -714,6 +712,7 @@ typedef NS_ENUM(NSUInteger, SJDisablePlayerGestureTypes) { @property (nonatomic, copy, readwrite, nullable) void(^controlViewDisplayStatus)(__kindof SJBaseVideoPlayer *player, BOOL displayed) __deprecated_msg("use `controlLayerAppearStateChanged`"); @property (nonatomic, copy, nullable) void(^willRotateScreen)(__kindof SJBaseVideoPlayer *player, BOOL isFullScreen) __deprecated_msg("use `viewWillRotateExeBlock`"); @property (nonatomic, copy, nullable) void(^rotatedScreen)(__kindof SJBaseVideoPlayer *player, BOOL isFullScreen) __deprecated_msg("use `viewDidRotateExeBlock`"); +@property (nonatomic, strong, nullable) UIImage *placeholder __deprecated_msg("use `player.placeholderImageView`"); @end diff --git a/SJVideoPlayerProject/Pods/SJBaseVideoPlayer/SJBaseVideoPlayer/SJBaseVideoPlayer.m b/SJVideoPlayerProject/Pods/SJBaseVideoPlayer/SJBaseVideoPlayer/SJBaseVideoPlayer.m index 3fade30ed..27920eac1 100644 --- a/SJVideoPlayerProject/Pods/SJBaseVideoPlayer/SJBaseVideoPlayer/SJBaseVideoPlayer.m +++ b/SJVideoPlayerProject/Pods/SJBaseVideoPlayer/SJBaseVideoPlayer/SJBaseVideoPlayer.m @@ -266,7 +266,7 @@ + (instancetype)player { } + (NSString *)version { - return @"1.6.0"; + return @"1.6.1"; } - (nullable __kindof UIViewController *)atViewController { @@ -297,6 +297,7 @@ - (instancetype)init { [self gestureControl]; [self reachabilityObserver]; [self addInterceptTapGR]; + [self _considerShowOrHiddenPlaceholder]; return self; } @@ -460,13 +461,12 @@ - (void)_considerShowOrHiddenPlaceholder { } } -- (void)setPlaceholder:(nullable UIImage *)placeholder { - self.presentView.placeholder = placeholder; - [self _considerShowOrHiddenPlaceholder]; -} - -- (nullable UIImage *)placeholder { - return self.presentView.placeholder; +/// +/// Thanks @chjsun +/// https://github.com/changsanjiang/SJVideoPlayer/issues/42 +/// +- (UIImageView *)placeholderImageView { + return self.presentView.placeholderImageView; } - (void)setVideoGravity:(AVLayerVideoGravity)videoGravity { @@ -969,7 +969,7 @@ - (void)setDirection:(SJViewFlipTransition)direction animated:(BOOL)animated com } break; case SJViewFlipTransition_Horizontally: { - transform = CATransform3DConcat(CATransform3DMakeRotation(M_PI, 0, 1, 0), CATransform3DMakeTranslation(0, 0, -1000)); + transform = CATransform3DConcat(CATransform3DMakeRotation(M_PI, 0, 1, 0), CATransform3DMakeTranslation(0, 0, -10000)); } break; } @@ -983,6 +983,7 @@ - (void)setDirection:(SJViewFlipTransition)direction animated:(BOOL)animated com [_view.layer addAnimation:rotationAnimation forKey:nil]; _view.layer.transform = transform; _isFlipTransitioning = YES; + _completionHandler = completionHandler; } - (void)animationDidStart:(CAAnimation *)anim { @@ -2236,7 +2237,7 @@ - (SJTimerControl *)controlHiddenTimer { if ( !self.isEnabled ) return; // 如果控制层显示, 当达到隐藏的条件, `timer`将控制层隐藏. 否则, 清除`timer`. if ( self.controlLayerAppearedState && - self.videoPlayer.controlLayerDataSource.controlLayerDisappearCondition ) + self.videoPlayer.controlLayerDataSource.controlLayerDisappearCondition ) [self layerDisappear]; else [control clear]; }; @@ -2359,6 +2360,15 @@ - (void)setRotatedScreen:(nullable void (^)(__kindof SJBaseVideoPlayer * _Nonnul - (nullable void (^)(__kindof SJBaseVideoPlayer * _Nonnull, BOOL))rotatedScreen __deprecated_msg("use `viewDidRotateExeBlock`") { return self.viewDidRotateExeBlock; } + +- (void)setPlaceholder:(nullable UIImage *)placeholder __deprecated_msg("use `player.placeholderImageView`") { + self.placeholderImageView.image = placeholder; +} + +- (nullable UIImage *)placeholder __deprecated_msg("use `player.placeholderImageView`") { + return self.placeholderImageView.image; +} + @end diff --git a/SJVideoPlayerProject/Pods/SJBaseVideoPlayer/SJBaseVideoPlayer/Tool/SJVideoPlayerPresentView.h b/SJVideoPlayerProject/Pods/SJBaseVideoPlayer/SJBaseVideoPlayer/Tool/SJVideoPlayerPresentView.h index f74a4d7b4..456e97a4f 100755 --- a/SJVideoPlayerProject/Pods/SJBaseVideoPlayer/SJBaseVideoPlayer/Tool/SJVideoPlayerPresentView.h +++ b/SJVideoPlayerProject/Pods/SJBaseVideoPlayer/SJBaseVideoPlayer/Tool/SJVideoPlayerPresentView.h @@ -10,7 +10,8 @@ NS_ASSUME_NONNULL_BEGIN @interface SJVideoPlayerPresentView : UIView -@property (nonatomic, strong, nullable) UIImage *placeholder; +@property (nonatomic, strong, readonly) UIImageView *placeholderImageView; + - (void)showPlaceholder; - (void)hiddenPlaceholder; @end diff --git a/SJVideoPlayerProject/Pods/SJBaseVideoPlayer/SJBaseVideoPlayer/Tool/SJVideoPlayerPresentView.m b/SJVideoPlayerProject/Pods/SJBaseVideoPlayer/SJBaseVideoPlayer/Tool/SJVideoPlayerPresentView.m index 2237a1ba8..158afba8d 100755 --- a/SJVideoPlayerProject/Pods/SJBaseVideoPlayer/SJBaseVideoPlayer/Tool/SJVideoPlayerPresentView.m +++ b/SJVideoPlayerProject/Pods/SJBaseVideoPlayer/SJBaseVideoPlayer/Tool/SJVideoPlayerPresentView.m @@ -9,7 +9,6 @@ #import "SJVideoPlayerPresentView.h" NS_ASSUME_NONNULL_BEGIN @interface SJVideoPlayerPresentView () -@property (nonatomic, strong, readonly) UIImageView *placeholderImageView; @end @implementation SJVideoPlayerPresentView { @@ -40,12 +39,6 @@ - (void)hiddenPlaceholder { self.placeholderImageView.alpha = 0.001; } -- (void)setPlaceholder:(nullable UIImage *)placeholder { - if ( placeholder == _placeholder ) return; - _placeholder = placeholder; - _placeholderImageView.image = placeholder; -} - - (void)_presentSetupView { self.backgroundColor = [UIColor blackColor]; self.placeholderImageView.frame = self.bounds; diff --git a/SJVideoPlayerProject/SJVideoPlayer.xcworkspace/xcuserdata/bluedancer.xcuserdatad/UserInterfaceState.xcuserstate b/SJVideoPlayerProject/SJVideoPlayer.xcworkspace/xcuserdata/bluedancer.xcuserdatad/UserInterfaceState.xcuserstate index de16397a4..9628a019b 100644 Binary files a/SJVideoPlayerProject/SJVideoPlayer.xcworkspace/xcuserdata/bluedancer.xcuserdatad/UserInterfaceState.xcuserstate and b/SJVideoPlayerProject/SJVideoPlayer.xcworkspace/xcuserdata/bluedancer.xcuserdatad/UserInterfaceState.xcuserstate differ