DDZFPlayerKit_Private update
This commit is contained in:
244
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/UIScrollView+ZFPlayer.h
generated
Normal file
244
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/UIScrollView+ZFPlayer.h
generated
Normal file
@@ -0,0 +1,244 @@
|
||||
//
|
||||
// UIScrollView+ZFPlayer.h
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*
|
||||
* The scroll direction of scrollView.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, ZFPlayerScrollDirection) {
|
||||
ZFPlayerScrollDirectionNone,
|
||||
ZFPlayerScrollDirectionUp, // Scroll up
|
||||
ZFPlayerScrollDirectionDown, // Scroll Down
|
||||
ZFPlayerScrollDirectionLeft, // Scroll left
|
||||
ZFPlayerScrollDirectionRight // Scroll right
|
||||
};
|
||||
|
||||
/*
|
||||
* The scrollView direction.
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, ZFPlayerScrollViewDirection) {
|
||||
ZFPlayerScrollViewDirectionVertical,
|
||||
ZFPlayerScrollViewDirectionHorizontal
|
||||
};
|
||||
|
||||
/*
|
||||
* The player container type
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, ZFPlayerContainerType) {
|
||||
ZFPlayerContainerTypeView,
|
||||
ZFPlayerContainerTypeCell
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger , ZFPlayerScrollViewScrollPosition) {
|
||||
ZFPlayerScrollViewScrollPositionNone,
|
||||
/// Apply to UITableView and UICollectionViewDirection is vertical scrolling.
|
||||
ZFPlayerScrollViewScrollPositionTop,
|
||||
ZFPlayerScrollViewScrollPositionCenteredVertically,
|
||||
ZFPlayerScrollViewScrollPositionBottom,
|
||||
|
||||
/// Only apply to UICollectionViewDirection is horizontal scrolling.
|
||||
ZFPlayerScrollViewScrollPositionLeft,
|
||||
ZFPlayerScrollViewScrollPositionCenteredHorizontally,
|
||||
ZFPlayerScrollViewScrollPositionRight
|
||||
};
|
||||
|
||||
@interface UIScrollView (ZFPlayer)
|
||||
|
||||
/// When the ZFPlayerScrollViewDirection is ZFPlayerScrollViewDirectionVertical,the property has value.
|
||||
@property (nonatomic, readonly) CGFloat zf_lastOffsetY;
|
||||
|
||||
/// When the ZFPlayerScrollViewDirection is ZFPlayerScrollViewDirectionHorizontal,the property has value.
|
||||
@property (nonatomic, readonly) CGFloat zf_lastOffsetX;
|
||||
|
||||
/// The scrollView scroll direction, default is ZFPlayerScrollViewDirectionVertical.
|
||||
@property (nonatomic) ZFPlayerScrollViewDirection zf_scrollViewDirection;
|
||||
|
||||
/// The scroll direction of scrollView while scrolling.
|
||||
/// When the ZFPlayerScrollViewDirection is ZFPlayerScrollViewDirectionVertical,this value can only be ZFPlayerScrollDirectionUp or ZFPlayerScrollDirectionDown.
|
||||
/// When the ZFPlayerScrollViewDirection is ZFPlayerScrollViewDirectionHorizontal,this value can only be ZFPlayerScrollDirectionLeft or ZFPlayerScrollDirectionRight.
|
||||
@property (nonatomic, readonly) ZFPlayerScrollDirection zf_scrollDirection;
|
||||
|
||||
/// Get the cell according to indexPath.
|
||||
- (UIView *)zf_getCellForIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
/// Get the indexPath for cell.
|
||||
- (NSIndexPath *)zf_getIndexPathForCell:(UIView *)cell;
|
||||
|
||||
/**
|
||||
Scroll to indexPath with position.
|
||||
|
||||
@param indexPath scroll the indexPath.
|
||||
@param scrollPosition scrollView scroll position.
|
||||
@param animated animate.
|
||||
@param completionHandler Scroll completion callback.
|
||||
*/
|
||||
- (void)zf_scrollToRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
atScrollPosition:(ZFPlayerScrollViewScrollPosition)scrollPosition
|
||||
animated:(BOOL)animated
|
||||
completionHandler:(void (^ __nullable)(void))completionHandler;
|
||||
|
||||
/**
|
||||
Scroll to indexPath with position.
|
||||
|
||||
@param indexPath scroll the indexPath.
|
||||
@param scrollPosition scrollView scroll position.
|
||||
@param duration animate duration.
|
||||
@param completionHandler Scroll completion callback.
|
||||
*/
|
||||
- (void)zf_scrollToRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
atScrollPosition:(ZFPlayerScrollViewScrollPosition)scrollPosition
|
||||
animateDuration:(NSTimeInterval)duration
|
||||
completionHandler:(void (^ __nullable)(void))completionHandler;
|
||||
|
||||
///------------------------------------
|
||||
/// The following method must be implemented in UIScrollViewDelegate.
|
||||
///------------------------------------
|
||||
|
||||
- (void)zf_scrollViewDidEndDecelerating;
|
||||
|
||||
- (void)zf_scrollViewDidEndDraggingWillDecelerate:(BOOL)decelerate;
|
||||
|
||||
- (void)zf_scrollViewDidScrollToTop;
|
||||
|
||||
- (void)zf_scrollViewDidScroll;
|
||||
|
||||
- (void)zf_scrollViewWillBeginDragging;
|
||||
|
||||
///------------------------------------
|
||||
/// end
|
||||
///------------------------------------
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@interface UIScrollView (ZFPlayerCannotCalled)
|
||||
|
||||
/// The block invoked When the player appearing.
|
||||
@property (nonatomic, copy, nullable) void(^zf_playerAppearingInScrollView)(NSIndexPath *indexPath, CGFloat playerApperaPercent);
|
||||
|
||||
/// The block invoked When the player disappearing.
|
||||
@property (nonatomic, copy, nullable) void(^zf_playerDisappearingInScrollView)(NSIndexPath *indexPath, CGFloat playerDisapperaPercent);
|
||||
|
||||
/// The block invoked When the player will appeared.
|
||||
@property (nonatomic, copy, nullable) void(^zf_playerWillAppearInScrollView)(NSIndexPath *indexPath);
|
||||
|
||||
/// The block invoked When the player did appeared.
|
||||
@property (nonatomic, copy, nullable) void(^zf_playerDidAppearInScrollView)(NSIndexPath *indexPath);
|
||||
|
||||
/// The block invoked When the player will disappear.
|
||||
@property (nonatomic, copy, nullable) void(^zf_playerWillDisappearInScrollView)(NSIndexPath *indexPath);
|
||||
|
||||
/// The block invoked When the player did disappeared.
|
||||
@property (nonatomic, copy, nullable) void(^zf_playerDidDisappearInScrollView)(NSIndexPath *indexPath);
|
||||
|
||||
/// The block invoked When the player did stop scroll.
|
||||
@property (nonatomic, copy, nullable) void(^zf_scrollViewDidEndScrollingCallback)(NSIndexPath *indexPath);
|
||||
|
||||
/// The block invoked When the player did scroll.
|
||||
@property (nonatomic, copy, nullable) void(^zf_scrollViewDidScrollCallback)(NSIndexPath *indexPath);
|
||||
|
||||
/// The block invoked When the player should play.
|
||||
@property (nonatomic, copy, nullable) void(^zf_playerShouldPlayInScrollView)(NSIndexPath *indexPath);
|
||||
|
||||
/// The current player scroll slides off the screen percent.
|
||||
/// the property used when the `stopWhileNotVisible` is YES, stop the current playing player.
|
||||
/// the property used when the `stopWhileNotVisible` is NO, the current playing player add to small container view.
|
||||
/// 0.0~1.0, defalut is 0.5.
|
||||
/// 0.0 is the player will disappear.
|
||||
/// 1.0 is the player did disappear.
|
||||
@property (nonatomic) CGFloat zf_playerDisapperaPercent;
|
||||
|
||||
/// The current player scroll to the screen percent to play the video.
|
||||
/// 0.0~1.0, defalut is 0.0.
|
||||
/// 0.0 is the player will appear.
|
||||
/// 1.0 is the player did appear.
|
||||
@property (nonatomic) CGFloat zf_playerApperaPercent;
|
||||
|
||||
/// The current player controller is disappear, not dealloc
|
||||
@property (nonatomic) BOOL zf_viewControllerDisappear;
|
||||
|
||||
/// Has stopped playing
|
||||
@property (nonatomic, assign) BOOL zf_stopPlay;
|
||||
|
||||
/// The currently playing cell stop playing when the cell has out off the screen,defalut is YES.
|
||||
@property (nonatomic, assign) BOOL zf_stopWhileNotVisible;
|
||||
|
||||
/// The indexPath is playing.
|
||||
@property (nonatomic, nullable) NSIndexPath *zf_playingIndexPath;
|
||||
|
||||
/// The indexPath should be play while scrolling.
|
||||
@property (nonatomic, nullable) NSIndexPath *zf_shouldPlayIndexPath;
|
||||
|
||||
/// WWANA networks play automatically,default NO.
|
||||
@property (nonatomic, getter=zf_isWWANAutoPlay) BOOL zf_WWANAutoPlay;
|
||||
|
||||
/// The player should auto player,default is YES.
|
||||
@property (nonatomic) BOOL zf_shouldAutoPlay;
|
||||
|
||||
/// The view tag that the player display in scrollView.
|
||||
@property (nonatomic) NSInteger zf_containerViewTag;
|
||||
|
||||
/// The video contrainerView in normal model.
|
||||
@property (nonatomic, strong) UIView *zf_containerView;
|
||||
|
||||
/// The video contrainerView type.
|
||||
@property (nonatomic, assign) ZFPlayerContainerType zf_containerType;
|
||||
|
||||
/// Filter the cell that should be played when the scroll is stopped (to play when the scroll is stopped).
|
||||
- (void)zf_filterShouldPlayCellWhileScrolled:(void (^ __nullable)(NSIndexPath *indexPath))handler;
|
||||
|
||||
/// Filter the cell that should be played while scrolling (you can use this to filter the highlighted cell).
|
||||
- (void)zf_filterShouldPlayCellWhileScrolling:(void (^ __nullable)(NSIndexPath *indexPath))handler;
|
||||
|
||||
@end
|
||||
|
||||
@interface UIScrollView (ZFPlayerDeprecated)
|
||||
|
||||
/// The block invoked When the player did stop scroll.
|
||||
@property (nonatomic, copy, nullable) void(^zf_scrollViewDidStopScrollCallback)(NSIndexPath *indexPath) __attribute__((deprecated("use `ZFPlayerController.zf_scrollViewDidEndScrollingCallback` instead.")));
|
||||
|
||||
/// The block invoked When the player should play.
|
||||
@property (nonatomic, copy, nullable) void(^zf_shouldPlayIndexPathCallback)(NSIndexPath *indexPath) __attribute__((deprecated("use `ZFPlayerController.zf_playerShouldPlayInScrollView` instead.")));
|
||||
|
||||
|
||||
/// Scroll to indexPath position `ZFPlayerScrollViewScrollPositionTop` with animations.
|
||||
- (void)zf_scrollToRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
completionHandler:(void (^ __nullable)(void))completionHandler __attribute__((deprecated("use `zf_scrollToRowAtIndexPath:atScrollPosition:animated:completionHandler:` instead.")));
|
||||
|
||||
/// Scroll to indexPath position `ZFPlayerScrollViewScrollPositionTop` with animations.
|
||||
- (void)zf_scrollToRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
animated:(BOOL)animated
|
||||
completionHandler:(void (^ __nullable)(void))completionHandler __attribute__((deprecated("use `zf_scrollToRowAtIndexPath:atScrollPosition:animated:completionHandler:` instead.")));
|
||||
|
||||
/// Scroll to indexPath position `ZFPlayerScrollViewScrollPositionTop` with animations.
|
||||
- (void)zf_scrollToRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
animateWithDuration:(NSTimeInterval)duration
|
||||
completionHandler:(void (^ __nullable)(void))completionHandler __attribute__((deprecated("use `zf_scrollToRowAtIndexPath:atScrollPosition:animateDuration:completionHandler:` instead.")));
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
915
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/UIScrollView+ZFPlayer.m
generated
Normal file
915
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/UIScrollView+ZFPlayer.m
generated
Normal file
@@ -0,0 +1,915 @@
|
||||
//
|
||||
// UIScrollView+ZFPlayer.m
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "UIScrollView+ZFPlayer.h"
|
||||
#import <objc/runtime.h>
|
||||
#import "ZFReachabilityManager.h"
|
||||
#import "ZFPlayerConst.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored"-Wdeprecated-declarations"
|
||||
|
||||
@interface UIScrollView ()
|
||||
|
||||
@property (nonatomic) CGFloat zf_lastOffsetY;
|
||||
@property (nonatomic) CGFloat zf_lastOffsetX;
|
||||
@property (nonatomic) ZFPlayerScrollDirection zf_scrollDirection;
|
||||
|
||||
@end
|
||||
|
||||
@implementation UIScrollView (ZFPlayer)
|
||||
|
||||
#pragma mark - public method
|
||||
|
||||
- (UIView *)zf_getCellForIndexPath:(NSIndexPath *)indexPath {
|
||||
if ([self _isTableView]) {
|
||||
UITableView *tableView = (UITableView *)self;
|
||||
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
|
||||
return cell;
|
||||
} else if ([self _isCollectionView]) {
|
||||
UICollectionView *collectionView = (UICollectionView *)self;
|
||||
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
|
||||
return cell;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSIndexPath *)zf_getIndexPathForCell:(UIView *)cell {
|
||||
if ([self _isTableView]) {
|
||||
UITableView *tableView = (UITableView *)self;
|
||||
NSIndexPath *indexPath = [tableView indexPathForCell:(UITableViewCell *)cell];
|
||||
return indexPath;
|
||||
} else if ([self _isCollectionView]) {
|
||||
UICollectionView *collectionView = (UICollectionView *)self;
|
||||
NSIndexPath *indexPath = [collectionView indexPathForCell:(UICollectionViewCell *)cell];
|
||||
return indexPath;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
/**
|
||||
Scroll to indexPath with position.
|
||||
|
||||
@param indexPath scroll the indexPath.
|
||||
@param scrollPosition scrollView scroll position.
|
||||
@param animated animate.
|
||||
@param completionHandler Scroll completion callback.
|
||||
*/
|
||||
- (void)zf_scrollToRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
atScrollPosition:(ZFPlayerScrollViewScrollPosition)scrollPosition
|
||||
animated:(BOOL)animated
|
||||
completionHandler:(void (^ __nullable)(void))completionHandler {
|
||||
[self zf_scrollToRowAtIndexPath:indexPath atScrollPosition:scrollPosition animateDuration:animated ? 0.4 : 0.0 completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
- (void)zf_scrollToRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
atScrollPosition:(ZFPlayerScrollViewScrollPosition)scrollPosition
|
||||
animateDuration:(NSTimeInterval)duration
|
||||
completionHandler:(void (^ __nullable)(void))completionHandler {
|
||||
BOOL animated = duration > 0.0;
|
||||
if ([self _isTableView]) {
|
||||
UITableView *tableView = (UITableView *)self;
|
||||
UITableViewScrollPosition tableScrollPosition = UITableViewScrollPositionNone;
|
||||
if (scrollPosition <= ZFPlayerScrollViewScrollPositionBottom) {
|
||||
tableScrollPosition = (UITableViewScrollPosition)scrollPosition;
|
||||
}
|
||||
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:tableScrollPosition animated:animated];
|
||||
} else if ([self _isCollectionView]) {
|
||||
UICollectionView *collectionView = (UICollectionView *)self;
|
||||
if (self.zf_scrollViewDirection == ZFPlayerScrollViewDirectionVertical) {
|
||||
UICollectionViewScrollPosition collectionScrollPosition = UICollectionViewScrollPositionNone;
|
||||
switch (scrollPosition) {
|
||||
case ZFPlayerScrollViewScrollPositionNone:
|
||||
collectionScrollPosition = UICollectionViewScrollPositionNone;
|
||||
break;
|
||||
case ZFPlayerScrollViewScrollPositionTop:
|
||||
collectionScrollPosition = UICollectionViewScrollPositionTop;
|
||||
break;
|
||||
case ZFPlayerScrollViewScrollPositionCenteredVertically:
|
||||
collectionScrollPosition = UICollectionViewScrollPositionCenteredVertically;
|
||||
break;
|
||||
case ZFPlayerScrollViewScrollPositionBottom:
|
||||
collectionScrollPosition = UICollectionViewScrollPositionBottom;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
[collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:collectionScrollPosition animated:animated];
|
||||
} else if (self.zf_scrollViewDirection == ZFPlayerScrollViewDirectionHorizontal) {
|
||||
UICollectionViewScrollPosition collectionScrollPosition = UICollectionViewScrollPositionNone;
|
||||
switch (scrollPosition) {
|
||||
case ZFPlayerScrollViewScrollPositionNone:
|
||||
collectionScrollPosition = UICollectionViewScrollPositionNone;
|
||||
break;
|
||||
case ZFPlayerScrollViewScrollPositionLeft:
|
||||
collectionScrollPosition = UICollectionViewScrollPositionLeft;
|
||||
break;
|
||||
case ZFPlayerScrollViewScrollPositionCenteredHorizontally:
|
||||
collectionScrollPosition = UICollectionViewScrollPositionCenteredHorizontally;
|
||||
break;
|
||||
case ZFPlayerScrollViewScrollPositionRight:
|
||||
collectionScrollPosition = UICollectionViewScrollPositionRight;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
[collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:collectionScrollPosition animated:animated];
|
||||
}
|
||||
}
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
if (completionHandler) completionHandler();
|
||||
});
|
||||
}
|
||||
|
||||
- (void)zf_scrollViewDidEndDecelerating {
|
||||
BOOL scrollToScrollStop = !self.tracking && !self.dragging && !self.decelerating;
|
||||
if (scrollToScrollStop) {
|
||||
[self _scrollViewDidStopScroll];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)zf_scrollViewDidEndDraggingWillDecelerate:(BOOL)decelerate {
|
||||
if (!decelerate) {
|
||||
BOOL dragToDragStop = self.tracking && !self.dragging && !self.decelerating;
|
||||
if (dragToDragStop) {
|
||||
[self _scrollViewDidStopScroll];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)zf_scrollViewDidScrollToTop {
|
||||
[self _scrollViewDidStopScroll];
|
||||
}
|
||||
|
||||
- (void)zf_scrollViewDidScroll {
|
||||
if (self.zf_scrollViewDirection == ZFPlayerScrollViewDirectionVertical) {
|
||||
[self _findCorrectCellWhenScrollViewDirectionVertical:nil];
|
||||
[self _scrollViewScrollingDirectionVertical];
|
||||
} else {
|
||||
[self _findCorrectCellWhenScrollViewDirectionHorizontal:nil];
|
||||
[self _scrollViewScrollingDirectionHorizontal];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)zf_scrollViewWillBeginDragging {
|
||||
[self _scrollViewBeginDragging];
|
||||
}
|
||||
|
||||
#pragma mark - private method
|
||||
|
||||
- (void)_scrollViewDidStopScroll {
|
||||
self.zf_scrollDirection = ZFPlayerScrollDirectionNone;
|
||||
@zf_weakify(self)
|
||||
[self zf_filterShouldPlayCellWhileScrolled:^(NSIndexPath * _Nonnull indexPath) {
|
||||
@zf_strongify(self)
|
||||
if (self.zf_scrollViewDidStopScrollCallback) self.zf_scrollViewDidStopScrollCallback(indexPath);
|
||||
if (self.zf_scrollViewDidEndScrollingCallback) self.zf_scrollViewDidEndScrollingCallback(indexPath);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)_scrollViewBeginDragging {
|
||||
if (self.zf_scrollViewDirection == ZFPlayerScrollViewDirectionVertical) {
|
||||
self.zf_lastOffsetY = self.contentOffset.y;
|
||||
} else {
|
||||
self.zf_lastOffsetX = self.contentOffset.x;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
The percentage of scrolling processed in vertical scrolling.
|
||||
*/
|
||||
- (void)_scrollViewScrollingDirectionVertical {
|
||||
CGFloat offsetY = self.contentOffset.y;
|
||||
self.zf_scrollDirection = (offsetY - self.zf_lastOffsetY > 0) ? ZFPlayerScrollDirectionUp : ZFPlayerScrollDirectionDown;
|
||||
self.zf_lastOffsetY = offsetY;
|
||||
if (self.zf_stopPlay) return;
|
||||
|
||||
UIView *playerView;
|
||||
if (self.zf_containerType == ZFPlayerContainerTypeCell) {
|
||||
// Avoid being paused the first time you play it.
|
||||
if (self.contentOffset.y < 0) return;
|
||||
if (!self.zf_playingIndexPath) return;
|
||||
|
||||
UIView *cell = [self zf_getCellForIndexPath:self.zf_playingIndexPath];
|
||||
if (!cell) {
|
||||
if (self.zf_playerDidDisappearInScrollView) self.zf_playerDidDisappearInScrollView(self.zf_playingIndexPath);
|
||||
return;
|
||||
}
|
||||
playerView = [cell viewWithTag:self.zf_containerViewTag];
|
||||
} else if (self.zf_containerType == ZFPlayerContainerTypeView) {
|
||||
if (!self.zf_containerView) return;
|
||||
playerView = self.zf_containerView;
|
||||
}
|
||||
|
||||
CGRect rect1 = [playerView convertRect:playerView.frame toView:self];
|
||||
CGRect rect = [self convertRect:rect1 toView:self.superview];
|
||||
/// playerView top to scrollView top space.
|
||||
CGFloat topSpacing = CGRectGetMinY(rect) - CGRectGetMinY(self.frame) - CGRectGetMinY(playerView.frame);
|
||||
/// playerView bottom to scrollView bottom space.
|
||||
CGFloat bottomSpacing = CGRectGetMaxY(self.frame) - CGRectGetMaxY(rect) + CGRectGetMinY(playerView.frame);
|
||||
/// The height of the content area.
|
||||
CGFloat contentInsetHeight = CGRectGetMaxY(self.frame) - CGRectGetMinY(self.frame);
|
||||
|
||||
CGFloat playerDisapperaPercent = 0;
|
||||
CGFloat playerApperaPercent = 0;
|
||||
|
||||
if (self.zf_scrollDirection == ZFPlayerScrollDirectionUp) { /// Scroll up
|
||||
/// Player is disappearing.
|
||||
if (topSpacing <= 0 && CGRectGetHeight(rect) != 0) {
|
||||
playerDisapperaPercent = -topSpacing/CGRectGetHeight(rect);
|
||||
if (playerDisapperaPercent > 1.0) playerDisapperaPercent = 1.0;
|
||||
if (self.zf_playerDisappearingInScrollView) self.zf_playerDisappearingInScrollView(self.zf_playingIndexPath, playerDisapperaPercent);
|
||||
}
|
||||
|
||||
/// Top area
|
||||
if (topSpacing <= 0 && topSpacing > -CGRectGetHeight(rect)/2) {
|
||||
/// When the player will disappear.
|
||||
if (self.zf_playerWillDisappearInScrollView) self.zf_playerWillDisappearInScrollView(self.zf_playingIndexPath);
|
||||
} else if (topSpacing <= -CGRectGetHeight(rect)) {
|
||||
/// When the player did disappeared.
|
||||
if (self.zf_playerDidDisappearInScrollView) self.zf_playerDidDisappearInScrollView(self.zf_playingIndexPath);
|
||||
} else if (topSpacing > 0 && topSpacing <= contentInsetHeight) {
|
||||
/// Player is appearing.
|
||||
if (CGRectGetHeight(rect) != 0) {
|
||||
playerApperaPercent = -(topSpacing-contentInsetHeight)/CGRectGetHeight(rect);
|
||||
if (playerApperaPercent > 1.0) playerApperaPercent = 1.0;
|
||||
if (self.zf_playerAppearingInScrollView) self.zf_playerAppearingInScrollView(self.zf_playingIndexPath, playerApperaPercent);
|
||||
}
|
||||
/// In visable area
|
||||
if (topSpacing <= contentInsetHeight && topSpacing > contentInsetHeight-CGRectGetHeight(rect)/2) {
|
||||
/// When the player will appear.
|
||||
if (self.zf_playerWillAppearInScrollView) self.zf_playerWillAppearInScrollView(self.zf_playingIndexPath);
|
||||
} else {
|
||||
/// When the player did appeared.
|
||||
if (self.zf_playerDidAppearInScrollView) self.zf_playerDidAppearInScrollView(self.zf_playingIndexPath);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (self.zf_scrollDirection == ZFPlayerScrollDirectionDown) { /// Scroll Down
|
||||
/// Player is disappearing.
|
||||
if (bottomSpacing <= 0 && CGRectGetHeight(rect) != 0) {
|
||||
playerDisapperaPercent = -bottomSpacing/CGRectGetHeight(rect);
|
||||
if (playerDisapperaPercent > 1.0) playerDisapperaPercent = 1.0;
|
||||
if (self.zf_playerDisappearingInScrollView) self.zf_playerDisappearingInScrollView(self.zf_playingIndexPath, playerDisapperaPercent);
|
||||
}
|
||||
|
||||
/// Bottom area
|
||||
if (bottomSpacing <= 0 && bottomSpacing > -CGRectGetHeight(rect)/2) {
|
||||
/// When the player will disappear.
|
||||
if (self.zf_playerWillDisappearInScrollView) self.zf_playerWillDisappearInScrollView(self.zf_playingIndexPath);
|
||||
} else if (bottomSpacing <= -CGRectGetHeight(rect)) {
|
||||
/// When the player did disappeared.
|
||||
if (self.zf_playerDidDisappearInScrollView) self.zf_playerDidDisappearInScrollView(self.zf_playingIndexPath);
|
||||
} else if (bottomSpacing > 0 && bottomSpacing <= contentInsetHeight) {
|
||||
/// Player is appearing.
|
||||
if (CGRectGetHeight(rect) != 0) {
|
||||
playerApperaPercent = -(bottomSpacing-contentInsetHeight)/CGRectGetHeight(rect);
|
||||
if (playerApperaPercent > 1.0) playerApperaPercent = 1.0;
|
||||
if (self.zf_playerAppearingInScrollView) self.zf_playerAppearingInScrollView(self.zf_playingIndexPath, playerApperaPercent);
|
||||
}
|
||||
/// In visable area
|
||||
if (bottomSpacing <= contentInsetHeight && bottomSpacing > contentInsetHeight-CGRectGetHeight(rect)/2) {
|
||||
/// When the player will appear.
|
||||
if (self.zf_playerWillAppearInScrollView) self.zf_playerWillAppearInScrollView(self.zf_playingIndexPath);
|
||||
} else {
|
||||
/// When the player did appeared.
|
||||
if (self.zf_playerDidAppearInScrollView) self.zf_playerDidAppearInScrollView(self.zf_playingIndexPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
The percentage of scrolling processed in horizontal scrolling.
|
||||
*/
|
||||
- (void)_scrollViewScrollingDirectionHorizontal {
|
||||
CGFloat offsetX = self.contentOffset.x;
|
||||
self.zf_scrollDirection = (offsetX - self.zf_lastOffsetX > 0) ? ZFPlayerScrollDirectionLeft : ZFPlayerScrollDirectionRight;
|
||||
self.zf_lastOffsetX = offsetX;
|
||||
if (self.zf_stopPlay) return;
|
||||
|
||||
UIView *playerView;
|
||||
if (self.zf_containerType == ZFPlayerContainerTypeCell) {
|
||||
// Avoid being paused the first time you play it.
|
||||
if (self.contentOffset.x < 0) return;
|
||||
if (!self.zf_playingIndexPath) return;
|
||||
|
||||
UIView *cell = [self zf_getCellForIndexPath:self.zf_playingIndexPath];
|
||||
if (!cell) {
|
||||
if (self.zf_playerDidDisappearInScrollView) self.zf_playerDidDisappearInScrollView(self.zf_playingIndexPath);
|
||||
return;
|
||||
}
|
||||
playerView = [cell viewWithTag:self.zf_containerViewTag];
|
||||
} else if (self.zf_containerType == ZFPlayerContainerTypeView) {
|
||||
if (!self.zf_containerView) return;
|
||||
playerView = self.zf_containerView;
|
||||
}
|
||||
|
||||
CGRect rect1 = [playerView convertRect:playerView.frame toView:self];
|
||||
CGRect rect = [self convertRect:rect1 toView:self.superview];
|
||||
/// playerView left to scrollView left space.
|
||||
CGFloat leftSpacing = CGRectGetMinX(rect) - CGRectGetMinX(self.frame) - CGRectGetMinX(playerView.frame);
|
||||
/// playerView bottom to scrollView right space.
|
||||
CGFloat rightSpacing = CGRectGetMaxX(self.frame) - CGRectGetMaxX(rect) + CGRectGetMinX(playerView.frame);
|
||||
/// The height of the content area.
|
||||
CGFloat contentInsetWidth = CGRectGetMaxX(self.frame) - CGRectGetMinX(self.frame);
|
||||
|
||||
CGFloat playerDisapperaPercent = 0;
|
||||
CGFloat playerApperaPercent = 0;
|
||||
|
||||
if (self.zf_scrollDirection == ZFPlayerScrollDirectionLeft) { /// Scroll left
|
||||
/// Player is disappearing.
|
||||
if (leftSpacing <= 0 && CGRectGetWidth(rect) != 0) {
|
||||
playerDisapperaPercent = -leftSpacing/CGRectGetWidth(rect);
|
||||
if (playerDisapperaPercent > 1.0) playerDisapperaPercent = 1.0;
|
||||
if (self.zf_playerDisappearingInScrollView) self.zf_playerDisappearingInScrollView(self.zf_playingIndexPath, playerDisapperaPercent);
|
||||
}
|
||||
|
||||
/// Top area
|
||||
if (leftSpacing <= 0 && leftSpacing > -CGRectGetWidth(rect)/2) {
|
||||
/// When the player will disappear.
|
||||
if (self.zf_playerWillDisappearInScrollView) self.zf_playerWillDisappearInScrollView(self.zf_playingIndexPath);
|
||||
} else if (leftSpacing <= -CGRectGetWidth(rect)) {
|
||||
/// When the player did disappeared.
|
||||
if (self.zf_playerDidDisappearInScrollView) self.zf_playerDidDisappearInScrollView(self.zf_playingIndexPath);
|
||||
} else if (leftSpacing > 0 && leftSpacing <= contentInsetWidth) {
|
||||
/// Player is appearing.
|
||||
if (CGRectGetWidth(rect) != 0) {
|
||||
playerApperaPercent = -(leftSpacing-contentInsetWidth)/CGRectGetWidth(rect);
|
||||
if (playerApperaPercent > 1.0) playerApperaPercent = 1.0;
|
||||
if (self.zf_playerAppearingInScrollView) self.zf_playerAppearingInScrollView(self.zf_playingIndexPath, playerApperaPercent);
|
||||
}
|
||||
/// In visable area
|
||||
if (leftSpacing <= contentInsetWidth && leftSpacing > contentInsetWidth-CGRectGetWidth(rect)/2) {
|
||||
/// When the player will appear.
|
||||
if (self.zf_playerWillAppearInScrollView) self.zf_playerWillAppearInScrollView(self.zf_playingIndexPath);
|
||||
} else {
|
||||
/// When the player did appeared.
|
||||
if (self.zf_playerDidAppearInScrollView) self.zf_playerDidAppearInScrollView(self.zf_playingIndexPath);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (self.zf_scrollDirection == ZFPlayerScrollDirectionRight) { /// Scroll right
|
||||
/// Player is disappearing.
|
||||
if (rightSpacing <= 0 && CGRectGetWidth(rect) != 0) {
|
||||
playerDisapperaPercent = -rightSpacing/CGRectGetWidth(rect);
|
||||
if (playerDisapperaPercent > 1.0) playerDisapperaPercent = 1.0;
|
||||
if (self.zf_playerDisappearingInScrollView) self.zf_playerDisappearingInScrollView(self.zf_playingIndexPath, playerDisapperaPercent);
|
||||
}
|
||||
|
||||
/// Bottom area
|
||||
if (rightSpacing <= 0 && rightSpacing > -CGRectGetWidth(rect)/2) {
|
||||
/// When the player will disappear.
|
||||
if (self.zf_playerWillDisappearInScrollView) self.zf_playerWillDisappearInScrollView(self.zf_playingIndexPath);
|
||||
} else if (rightSpacing <= -CGRectGetWidth(rect)) {
|
||||
/// When the player did disappeared.
|
||||
if (self.zf_playerDidDisappearInScrollView) self.zf_playerDidDisappearInScrollView(self.zf_playingIndexPath);
|
||||
} else if (rightSpacing > 0 && rightSpacing <= contentInsetWidth) {
|
||||
/// Player is appearing.
|
||||
if (CGRectGetWidth(rect) != 0) {
|
||||
playerApperaPercent = -(rightSpacing-contentInsetWidth)/CGRectGetWidth(rect);
|
||||
if (playerApperaPercent > 1.0) playerApperaPercent = 1.0;
|
||||
if (self.zf_playerAppearingInScrollView) self.zf_playerAppearingInScrollView(self.zf_playingIndexPath, playerApperaPercent);
|
||||
}
|
||||
/// In visable area
|
||||
if (rightSpacing <= contentInsetWidth && rightSpacing > contentInsetWidth-CGRectGetWidth(rect)/2) {
|
||||
/// When the player will appear.
|
||||
if (self.zf_playerWillAppearInScrollView) self.zf_playerWillAppearInScrollView(self.zf_playingIndexPath);
|
||||
} else {
|
||||
/// When the player did appeared.
|
||||
if (self.zf_playerDidAppearInScrollView) self.zf_playerDidAppearInScrollView(self.zf_playingIndexPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Find the playing cell while the scrollDirection is vertical.
|
||||
*/
|
||||
- (void)_findCorrectCellWhenScrollViewDirectionVertical:(void (^ __nullable)(NSIndexPath *indexPath))handler {
|
||||
if (!self.zf_shouldAutoPlay) return;
|
||||
if (self.zf_containerType == ZFPlayerContainerTypeView) return;
|
||||
|
||||
if (!self.zf_stopWhileNotVisible) {
|
||||
/// If you have a cell that is playing, stop the traversal.
|
||||
if (self.zf_playingIndexPath) {
|
||||
NSIndexPath *finalIndexPath = self.zf_playingIndexPath;
|
||||
if (self.zf_scrollViewDidScrollCallback) self.zf_scrollViewDidScrollCallback(finalIndexPath);
|
||||
if (handler) handler(finalIndexPath);
|
||||
self.zf_shouldPlayIndexPath = finalIndexPath;
|
||||
return;
|
||||
}
|
||||
}
|
||||
NSArray *visiableCells = nil;
|
||||
NSIndexPath *indexPath = nil;
|
||||
BOOL isLast = self.contentOffset.y + self.frame.size.height >= self.contentSize.height;
|
||||
if ([self _isTableView]) {
|
||||
UITableView *tableView = (UITableView *)self;
|
||||
visiableCells = [tableView visibleCells];
|
||||
// First visible cell indexPath
|
||||
indexPath = tableView.indexPathsForVisibleRows.firstObject;
|
||||
if ((self.contentOffset.y <= 0 || isLast) && (!self.zf_playingIndexPath || [indexPath compare:self.zf_playingIndexPath] == NSOrderedSame)) {
|
||||
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
|
||||
UIView *playerView = [cell viewWithTag:self.zf_containerViewTag];
|
||||
if (playerView && !playerView.hidden && playerView.alpha > 0.01) {
|
||||
if (self.zf_scrollViewDidScrollCallback) self.zf_scrollViewDidScrollCallback(indexPath);
|
||||
if (handler) handler(indexPath);
|
||||
self.zf_shouldPlayIndexPath = indexPath;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if ([self _isCollectionView]) {
|
||||
UICollectionView *collectionView = (UICollectionView *)self;
|
||||
visiableCells = [collectionView visibleCells];
|
||||
NSArray *sortedIndexPaths = [collectionView.indexPathsForVisibleItems sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
|
||||
return [obj1 compare:obj2];
|
||||
}];
|
||||
|
||||
visiableCells = [visiableCells sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
|
||||
NSIndexPath *path1 = (NSIndexPath *)[collectionView indexPathForCell:obj1];
|
||||
NSIndexPath *path2 = (NSIndexPath *)[collectionView indexPathForCell:obj2];
|
||||
return [path1 compare:path2];
|
||||
}];
|
||||
|
||||
// First visible cell indexPath
|
||||
indexPath = sortedIndexPaths.firstObject;
|
||||
if ((self.contentOffset.y <= 0 || isLast) && (!self.zf_playingIndexPath || [indexPath compare:self.zf_playingIndexPath] == NSOrderedSame)) {
|
||||
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
|
||||
UIView *playerView = [cell viewWithTag:self.zf_containerViewTag];
|
||||
if (playerView && !playerView.hidden && playerView.alpha > 0.01) {
|
||||
if (self.zf_scrollViewDidScrollCallback) self.zf_scrollViewDidScrollCallback(indexPath);
|
||||
if (handler) handler(indexPath);
|
||||
self.zf_shouldPlayIndexPath = indexPath;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSArray *cells = nil;
|
||||
if (self.zf_scrollDirection == ZFPlayerScrollDirectionUp) {
|
||||
cells = visiableCells;
|
||||
} else {
|
||||
cells = [visiableCells reverseObjectEnumerator].allObjects;
|
||||
}
|
||||
|
||||
/// Mid line.
|
||||
CGFloat scrollViewMidY = CGRectGetHeight(self.frame)/2;
|
||||
/// The final playing indexPath.
|
||||
__block NSIndexPath *finalIndexPath = nil;
|
||||
/// The final distance from the center line.
|
||||
__block CGFloat finalSpace = 0;
|
||||
@zf_weakify(self)
|
||||
[cells enumerateObjectsUsingBlock:^(UIView *cell, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
@zf_strongify(self)
|
||||
UIView *playerView = [cell viewWithTag:self.zf_containerViewTag];
|
||||
if (!playerView || playerView.hidden || playerView.alpha <= 0.01) return;
|
||||
CGRect rect1 = [playerView convertRect:playerView.frame toView:self];
|
||||
CGRect rect = [self convertRect:rect1 toView:self.superview];
|
||||
/// playerView top to scrollView top space.
|
||||
CGFloat topSpacing = CGRectGetMinY(rect) - CGRectGetMinY(self.frame) - CGRectGetMinY(playerView.frame);
|
||||
/// playerView bottom to scrollView bottom space.
|
||||
CGFloat bottomSpacing = CGRectGetMaxY(self.frame) - CGRectGetMaxY(rect) + CGRectGetMinY(playerView.frame);
|
||||
CGFloat centerSpacing = ABS(scrollViewMidY - CGRectGetMidY(rect));
|
||||
NSIndexPath *indexPath = [self zf_getIndexPathForCell:cell];
|
||||
|
||||
/// Play when the video playback section is visible.
|
||||
if ((topSpacing >= -(1 - self.zf_playerApperaPercent) * CGRectGetHeight(rect)) && (bottomSpacing >= -(1 - self.zf_playerApperaPercent) * CGRectGetHeight(rect))) {
|
||||
if (!finalIndexPath || centerSpacing < finalSpace) {
|
||||
finalIndexPath = indexPath;
|
||||
finalSpace = centerSpacing;
|
||||
}
|
||||
}
|
||||
}];
|
||||
/// if find the playing indexPath.
|
||||
if (finalIndexPath) {
|
||||
if (self.zf_scrollViewDidScrollCallback) self.zf_scrollViewDidScrollCallback(indexPath);
|
||||
if (handler) handler(finalIndexPath);
|
||||
}
|
||||
self.zf_shouldPlayIndexPath = finalIndexPath;
|
||||
}
|
||||
|
||||
/**
|
||||
Find the playing cell while the scrollDirection is horizontal.
|
||||
*/
|
||||
- (void)_findCorrectCellWhenScrollViewDirectionHorizontal:(void (^ __nullable)(NSIndexPath *indexPath))handler {
|
||||
if (!self.zf_shouldAutoPlay) return;
|
||||
if (self.zf_containerType == ZFPlayerContainerTypeView) return;
|
||||
if (!self.zf_stopWhileNotVisible) {
|
||||
/// If you have a cell that is playing, stop the traversal.
|
||||
if (self.zf_playingIndexPath) {
|
||||
NSIndexPath *finalIndexPath = self.zf_playingIndexPath;
|
||||
if (self.zf_scrollViewDidScrollCallback) self.zf_scrollViewDidScrollCallback(finalIndexPath);
|
||||
if (handler) handler(finalIndexPath);
|
||||
self.zf_shouldPlayIndexPath = finalIndexPath;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
NSArray *visiableCells = nil;
|
||||
NSIndexPath *indexPath = nil;
|
||||
BOOL isLast = self.contentOffset.x + self.frame.size.width >= self.contentSize.width;
|
||||
if ([self _isTableView]) {
|
||||
UITableView *tableView = (UITableView *)self;
|
||||
visiableCells = [tableView visibleCells];
|
||||
// First visible cell indexPath
|
||||
indexPath = tableView.indexPathsForVisibleRows.firstObject;
|
||||
if ((self.contentOffset.x <= 0 || isLast) && (!self.zf_playingIndexPath || [indexPath compare:self.zf_playingIndexPath] == NSOrderedSame)) {
|
||||
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
|
||||
UIView *playerView = [cell viewWithTag:self.zf_containerViewTag];
|
||||
if (playerView && !playerView.hidden && playerView.alpha > 0.01) {
|
||||
if (self.zf_scrollViewDidScrollCallback) self.zf_scrollViewDidScrollCallback(indexPath);
|
||||
if (handler) handler(indexPath);
|
||||
self.zf_shouldPlayIndexPath = indexPath;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if ([self _isCollectionView]) {
|
||||
UICollectionView *collectionView = (UICollectionView *)self;
|
||||
visiableCells = [collectionView visibleCells];
|
||||
NSArray *sortedIndexPaths = [collectionView.indexPathsForVisibleItems sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
|
||||
return [obj1 compare:obj2];
|
||||
}];
|
||||
|
||||
visiableCells = [visiableCells sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
|
||||
NSIndexPath *path1 = (NSIndexPath *)[collectionView indexPathForCell:obj1];
|
||||
NSIndexPath *path2 = (NSIndexPath *)[collectionView indexPathForCell:obj2];
|
||||
return [path1 compare:path2];
|
||||
}];
|
||||
|
||||
// First visible cell indexPath
|
||||
indexPath = sortedIndexPaths.firstObject;
|
||||
if ((self.contentOffset.x <= 0 || isLast) && (!self.zf_playingIndexPath || [indexPath compare:self.zf_playingIndexPath] == NSOrderedSame)) {
|
||||
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
|
||||
UIView *playerView = [cell viewWithTag:self.zf_containerViewTag];
|
||||
if (playerView && !playerView.hidden && playerView.alpha > 0.01) {
|
||||
if (self.zf_scrollViewDidScrollCallback) self.zf_scrollViewDidScrollCallback(indexPath);
|
||||
if (handler) handler(indexPath);
|
||||
self.zf_shouldPlayIndexPath = indexPath;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSArray *cells = nil;
|
||||
if (self.zf_scrollDirection == ZFPlayerScrollDirectionUp) {
|
||||
cells = visiableCells;
|
||||
} else {
|
||||
cells = [visiableCells reverseObjectEnumerator].allObjects;
|
||||
}
|
||||
|
||||
/// Mid line.
|
||||
CGFloat scrollViewMidX = CGRectGetWidth(self.frame)/2;
|
||||
/// The final playing indexPath.
|
||||
__block NSIndexPath *finalIndexPath = nil;
|
||||
/// The final distance from the center line.
|
||||
__block CGFloat finalSpace = 0;
|
||||
@zf_weakify(self)
|
||||
[cells enumerateObjectsUsingBlock:^(UIView *cell, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
@zf_strongify(self)
|
||||
UIView *playerView = [cell viewWithTag:self.zf_containerViewTag];
|
||||
if (!playerView || playerView.hidden || playerView.alpha <= 0.01) return;
|
||||
CGRect rect1 = [playerView convertRect:playerView.frame toView:self];
|
||||
CGRect rect = [self convertRect:rect1 toView:self.superview];
|
||||
/// playerView left to scrollView top space.
|
||||
CGFloat leftSpacing = CGRectGetMinX(rect) - CGRectGetMinX(self.frame) - CGRectGetMinX(playerView.frame);
|
||||
/// playerView right to scrollView top space.
|
||||
CGFloat rightSpacing = CGRectGetMaxX(self.frame) - CGRectGetMaxX(rect) + CGRectGetMinX(playerView.frame);
|
||||
CGFloat centerSpacing = ABS(scrollViewMidX - CGRectGetMidX(rect));
|
||||
NSIndexPath *indexPath = [self zf_getIndexPathForCell:cell];
|
||||
|
||||
/// Play when the video playback section is visible.
|
||||
if ((leftSpacing >= -(1 - self.zf_playerApperaPercent) * CGRectGetWidth(rect)) && (rightSpacing >= -(1 - self.zf_playerApperaPercent) * CGRectGetWidth(rect))) {
|
||||
if (!finalIndexPath || centerSpacing < finalSpace) {
|
||||
finalIndexPath = indexPath;
|
||||
finalSpace = centerSpacing;
|
||||
}
|
||||
}
|
||||
}];
|
||||
/// if find the playing indexPath.
|
||||
if (finalIndexPath) {
|
||||
if (self.zf_scrollViewDidScrollCallback) self.zf_scrollViewDidScrollCallback(indexPath);
|
||||
if (handler) handler(finalIndexPath);
|
||||
self.zf_shouldPlayIndexPath = finalIndexPath;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)_isTableView {
|
||||
return [self isKindOfClass:[UITableView class]];
|
||||
}
|
||||
|
||||
- (BOOL)_isCollectionView {
|
||||
return [self isKindOfClass:[UICollectionView class]];
|
||||
}
|
||||
|
||||
#pragma mark - getter
|
||||
|
||||
- (ZFPlayerScrollDirection)zf_scrollDirection {
|
||||
return [objc_getAssociatedObject(self, _cmd) integerValue];
|
||||
}
|
||||
|
||||
- (ZFPlayerScrollViewDirection)zf_scrollViewDirection {
|
||||
return [objc_getAssociatedObject(self, _cmd) integerValue];
|
||||
}
|
||||
|
||||
- (CGFloat)zf_lastOffsetY {
|
||||
return [objc_getAssociatedObject(self, _cmd) floatValue];
|
||||
}
|
||||
|
||||
- (CGFloat)zf_lastOffsetX {
|
||||
return [objc_getAssociatedObject(self, _cmd) floatValue];
|
||||
}
|
||||
|
||||
#pragma mark - setter
|
||||
|
||||
- (void)setZf_scrollDirection:(ZFPlayerScrollDirection)zf_scrollDirection {
|
||||
objc_setAssociatedObject(self, @selector(zf_scrollDirection), @(zf_scrollDirection), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_scrollViewDirection:(ZFPlayerScrollViewDirection)zf_scrollViewDirection {
|
||||
objc_setAssociatedObject(self, @selector(zf_scrollViewDirection), @(zf_scrollViewDirection), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_lastOffsetY:(CGFloat)zf_lastOffsetY {
|
||||
objc_setAssociatedObject(self, @selector(zf_lastOffsetY), @(zf_lastOffsetY), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_lastOffsetX:(CGFloat)zf_lastOffsetX {
|
||||
objc_setAssociatedObject(self, @selector(zf_lastOffsetX), @(zf_lastOffsetX), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation UIScrollView (ZFPlayerCannotCalled)
|
||||
|
||||
- (void)zf_filterShouldPlayCellWhileScrolling:(void (^ __nullable)(NSIndexPath *indexPath))handler {
|
||||
if (self.zf_scrollViewDirection == ZFPlayerScrollViewDirectionVertical) {
|
||||
[self _findCorrectCellWhenScrollViewDirectionVertical:handler];
|
||||
} else {
|
||||
[self _findCorrectCellWhenScrollViewDirectionHorizontal:handler];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)zf_filterShouldPlayCellWhileScrolled:(void (^ __nullable)(NSIndexPath *indexPath))handler {
|
||||
if (!self.zf_shouldAutoPlay) return;
|
||||
@zf_weakify(self)
|
||||
[self zf_filterShouldPlayCellWhileScrolling:^(NSIndexPath *indexPath) {
|
||||
@zf_strongify(self)
|
||||
/// 如果当前控制器已经消失,直接return
|
||||
if (self.zf_viewControllerDisappear) return;
|
||||
if ([ZFReachabilityManager sharedManager].isReachableViaWWAN && !self.zf_WWANAutoPlay) {
|
||||
/// 移动网络
|
||||
self.zf_shouldPlayIndexPath = indexPath;
|
||||
return;
|
||||
}
|
||||
if (handler) handler(indexPath);
|
||||
self.zf_playingIndexPath = indexPath;
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - getter
|
||||
|
||||
- (void (^)(NSIndexPath * _Nonnull, CGFloat))zf_playerDisappearingInScrollView {
|
||||
return objc_getAssociatedObject(self, _cmd);
|
||||
}
|
||||
|
||||
- (void (^)(NSIndexPath * _Nonnull, CGFloat))zf_playerAppearingInScrollView {
|
||||
return objc_getAssociatedObject(self, _cmd);
|
||||
}
|
||||
|
||||
- (void (^)(NSIndexPath * _Nonnull))zf_playerDidAppearInScrollView {
|
||||
return objc_getAssociatedObject(self, _cmd);
|
||||
}
|
||||
|
||||
- (void (^)(NSIndexPath * _Nonnull))zf_playerWillDisappearInScrollView {
|
||||
return objc_getAssociatedObject(self, _cmd);
|
||||
}
|
||||
|
||||
- (void (^)(NSIndexPath * _Nonnull))zf_playerWillAppearInScrollView {
|
||||
return objc_getAssociatedObject(self, _cmd);
|
||||
}
|
||||
|
||||
- (void (^)(NSIndexPath * _Nonnull))zf_playerDidDisappearInScrollView {
|
||||
return objc_getAssociatedObject(self, _cmd);
|
||||
}
|
||||
|
||||
- (void (^)(NSIndexPath * _Nonnull))zf_scrollViewDidEndScrollingCallback {
|
||||
return objc_getAssociatedObject(self, _cmd);
|
||||
}
|
||||
|
||||
- (void (^)(NSIndexPath * _Nonnull))zf_scrollViewDidScrollCallback {
|
||||
return objc_getAssociatedObject(self, _cmd);
|
||||
}
|
||||
|
||||
- (void (^)(NSIndexPath * _Nonnull))zf_playerShouldPlayInScrollView {
|
||||
return objc_getAssociatedObject(self, _cmd);
|
||||
}
|
||||
|
||||
- (CGFloat)zf_playerApperaPercent {
|
||||
return [objc_getAssociatedObject(self, _cmd) floatValue];
|
||||
}
|
||||
|
||||
- (CGFloat)zf_playerDisapperaPercent {
|
||||
return [objc_getAssociatedObject(self, _cmd) floatValue];
|
||||
}
|
||||
|
||||
- (BOOL)zf_viewControllerDisappear {
|
||||
return [objc_getAssociatedObject(self, _cmd) boolValue];
|
||||
}
|
||||
|
||||
- (BOOL)zf_stopPlay {
|
||||
NSNumber *number = objc_getAssociatedObject(self, _cmd);
|
||||
if (number) return number.boolValue;
|
||||
self.zf_stopPlay = YES;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)zf_stopWhileNotVisible {
|
||||
return [objc_getAssociatedObject(self, _cmd) boolValue];
|
||||
}
|
||||
|
||||
- (NSIndexPath *)zf_playingIndexPath {
|
||||
return objc_getAssociatedObject(self, _cmd);
|
||||
}
|
||||
|
||||
- (NSIndexPath *)zf_shouldPlayIndexPath {
|
||||
return objc_getAssociatedObject(self, _cmd);
|
||||
}
|
||||
|
||||
- (NSInteger)zf_containerViewTag {
|
||||
return [objc_getAssociatedObject(self, _cmd) integerValue];
|
||||
}
|
||||
|
||||
- (BOOL)zf_isWWANAutoPlay {
|
||||
return [objc_getAssociatedObject(self, _cmd) boolValue];
|
||||
}
|
||||
|
||||
- (BOOL)zf_shouldAutoPlay {
|
||||
NSNumber *number = objc_getAssociatedObject(self, _cmd);
|
||||
if (number) return number.boolValue;
|
||||
self.zf_shouldAutoPlay = YES;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (ZFPlayerContainerType)zf_containerType {
|
||||
return [objc_getAssociatedObject(self, _cmd) integerValue];
|
||||
}
|
||||
|
||||
- (UIView *)zf_containerView {
|
||||
return objc_getAssociatedObject(self, _cmd);
|
||||
}
|
||||
|
||||
#pragma mark - setter
|
||||
|
||||
- (void)setZf_playerDisappearingInScrollView:(void (^)(NSIndexPath * _Nonnull, CGFloat))zf_playerDisappearingInScrollView {
|
||||
objc_setAssociatedObject(self, @selector(zf_playerDisappearingInScrollView), zf_playerDisappearingInScrollView, OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_playerAppearingInScrollView:(void (^)(NSIndexPath * _Nonnull, CGFloat))zf_playerAppearingInScrollView {
|
||||
objc_setAssociatedObject(self, @selector(zf_playerAppearingInScrollView), zf_playerAppearingInScrollView, OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_playerDidAppearInScrollView:(void (^)(NSIndexPath * _Nonnull))zf_playerDidAppearInScrollView {
|
||||
objc_setAssociatedObject(self, @selector(zf_playerDidAppearInScrollView), zf_playerDidAppearInScrollView, OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_playerWillDisappearInScrollView:(void (^)(NSIndexPath * _Nonnull))zf_playerWillDisappearInScrollView {
|
||||
objc_setAssociatedObject(self, @selector(zf_playerWillDisappearInScrollView), zf_playerWillDisappearInScrollView, OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_playerWillAppearInScrollView:(void (^)(NSIndexPath * _Nonnull))zf_playerWillAppearInScrollView {
|
||||
objc_setAssociatedObject(self, @selector(zf_playerWillAppearInScrollView), zf_playerWillAppearInScrollView, OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_playerDidDisappearInScrollView:(void (^)(NSIndexPath * _Nonnull))zf_playerDidDisappearInScrollView {
|
||||
objc_setAssociatedObject(self, @selector(zf_playerDidDisappearInScrollView), zf_playerDidDisappearInScrollView, OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_scrollViewDidEndScrollingCallback:(void (^)(NSIndexPath * _Nonnull))zf_scrollViewDidEndScrollingCallback {
|
||||
objc_setAssociatedObject(self, @selector(zf_scrollViewDidEndScrollingCallback), zf_scrollViewDidEndScrollingCallback, OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_scrollViewDidScrollCallback:(void (^)(NSIndexPath * _Nonnull))zf_scrollViewDidScrollCallback {
|
||||
objc_setAssociatedObject(self, @selector(zf_scrollViewDidScrollCallback), zf_scrollViewDidScrollCallback, OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_playerShouldPlayInScrollView:(void (^)(NSIndexPath * _Nonnull))zf_playerShouldPlayInScrollView {
|
||||
objc_setAssociatedObject(self, @selector(zf_playerShouldPlayInScrollView), zf_playerShouldPlayInScrollView, OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_playerApperaPercent:(CGFloat)zf_playerApperaPercent {
|
||||
objc_setAssociatedObject(self, @selector(zf_playerApperaPercent), @(zf_playerApperaPercent), OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_playerDisapperaPercent:(CGFloat)zf_playerDisapperaPercent {
|
||||
objc_setAssociatedObject(self, @selector(zf_playerDisapperaPercent), @(zf_playerDisapperaPercent), OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_viewControllerDisappear:(BOOL)zf_viewControllerDisappear {
|
||||
objc_setAssociatedObject(self, @selector(zf_viewControllerDisappear), @(zf_viewControllerDisappear), OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_stopPlay:(BOOL)zf_stopPlay {
|
||||
objc_setAssociatedObject(self, @selector(zf_stopPlay), @(zf_stopPlay), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_stopWhileNotVisible:(BOOL)zf_stopWhileNotVisible {
|
||||
objc_setAssociatedObject(self, @selector(zf_stopWhileNotVisible), @(zf_stopWhileNotVisible), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_playingIndexPath:(NSIndexPath *)zf_playingIndexPath {
|
||||
objc_setAssociatedObject(self, @selector(zf_playingIndexPath), zf_playingIndexPath, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
if (zf_playingIndexPath && [zf_playingIndexPath compare:self.zf_shouldPlayIndexPath] != NSOrderedSame) {
|
||||
self.zf_shouldPlayIndexPath = zf_playingIndexPath;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setZf_shouldPlayIndexPath:(NSIndexPath *)zf_shouldPlayIndexPath {
|
||||
if (self.zf_playerShouldPlayInScrollView) self.zf_playerShouldPlayInScrollView(zf_shouldPlayIndexPath);
|
||||
if (self.zf_shouldPlayIndexPathCallback) self.zf_shouldPlayIndexPathCallback(zf_shouldPlayIndexPath);
|
||||
objc_setAssociatedObject(self, @selector(zf_shouldPlayIndexPath), zf_shouldPlayIndexPath, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_containerViewTag:(NSInteger)zf_containerViewTag {
|
||||
objc_setAssociatedObject(self, @selector(zf_containerViewTag), @(zf_containerViewTag), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_containerType:(ZFPlayerContainerType)zf_containerType {
|
||||
objc_setAssociatedObject(self, @selector(zf_containerType), @(zf_containerType), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_containerView:(UIView *)zf_containerView {
|
||||
objc_setAssociatedObject(self, @selector(zf_containerView), zf_containerView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_shouldAutoPlay:(BOOL)zf_shouldAutoPlay {
|
||||
objc_setAssociatedObject(self, @selector(zf_shouldAutoPlay), @(zf_shouldAutoPlay), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_WWANAutoPlay:(BOOL)zf_WWANAutoPlay {
|
||||
objc_setAssociatedObject(self, @selector(zf_isWWANAutoPlay), @(zf_WWANAutoPlay), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation UIScrollView (ZFPlayerDeprecated)
|
||||
|
||||
#pragma mark - getter
|
||||
|
||||
- (void (^)(NSIndexPath * _Nonnull))zf_scrollViewDidStopScrollCallback {
|
||||
return objc_getAssociatedObject(self, _cmd);
|
||||
}
|
||||
|
||||
- (void (^)(NSIndexPath * _Nonnull))zf_shouldPlayIndexPathCallback {
|
||||
return objc_getAssociatedObject(self, _cmd);
|
||||
}
|
||||
|
||||
#pragma mark - setter
|
||||
|
||||
- (void)setZf_scrollViewDidStopScrollCallback:(void (^)(NSIndexPath * _Nonnull))zf_scrollViewDidStopScrollCallback {
|
||||
objc_setAssociatedObject(self, @selector(zf_scrollViewDidStopScrollCallback), zf_scrollViewDidStopScrollCallback, OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)setZf_shouldPlayIndexPathCallback:(void (^)(NSIndexPath * _Nonnull))zf_shouldPlayIndexPathCallback {
|
||||
objc_setAssociatedObject(self, @selector(zf_shouldPlayIndexPathCallback), zf_shouldPlayIndexPathCallback, OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
}
|
||||
|
||||
#pragma mark - method
|
||||
|
||||
- (void)zf_scrollToRowAtIndexPath:(NSIndexPath *)indexPath completionHandler:(void (^ __nullable)(void))completionHandler {
|
||||
[self zf_scrollToRowAtIndexPath:indexPath animated:YES completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
- (void)zf_scrollToRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated completionHandler:(void (^ __nullable)(void))completionHandler {
|
||||
[self zf_scrollToRowAtIndexPath:indexPath animateWithDuration:animated ? 0.4 : 0.0 completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
/// Scroll to indexPath with animations duration.
|
||||
- (void)zf_scrollToRowAtIndexPath:(NSIndexPath *)indexPath animateWithDuration:(NSTimeInterval)duration completionHandler:(void (^ __nullable)(void))completionHandler {
|
||||
[self zf_scrollToRowAtIndexPath:indexPath atScrollPosition:ZFPlayerScrollViewScrollPositionTop animateDuration:duration completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
120
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/UIViewController+ZFPlayerRotation.m
generated
Normal file
120
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/UIViewController+ZFPlayerRotation.m
generated
Normal file
@@ -0,0 +1,120 @@
|
||||
//
|
||||
// UIViewController+ZFPlayerRotation.m
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <objc/runtime.h>
|
||||
|
||||
@implementation UITabBarController (ZFPlayerRotation)
|
||||
|
||||
+ (void)initialize {
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
SEL selectors[] = {
|
||||
@selector(selectedIndex)
|
||||
};
|
||||
|
||||
for (NSUInteger index = 0; index < sizeof(selectors) / sizeof(SEL); ++index) {
|
||||
SEL originalSelector = selectors[index];
|
||||
SEL swizzledSelector = NSSelectorFromString([@"zf_" stringByAppendingString:NSStringFromSelector(originalSelector)]);
|
||||
Method originalMethod = class_getInstanceMethod(self, originalSelector);
|
||||
Method swizzledMethod = class_getInstanceMethod(self, swizzledSelector);
|
||||
if (class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))) {
|
||||
class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
|
||||
} else {
|
||||
method_exchangeImplementations(originalMethod, swizzledMethod);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (NSInteger)zf_selectedIndex {
|
||||
NSInteger index = [self zf_selectedIndex];
|
||||
if (index > self.viewControllers.count) return 0;
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the root view of the window is a UINavigationController, you call this Category first, and then UIViewController called.
|
||||
* All you need to do is revisit the following three methods on a page that supports directions other than portrait.
|
||||
*/
|
||||
|
||||
// Whether automatic screen rotation is supported.
|
||||
- (BOOL)shouldAutorotate {
|
||||
return [[self viewControllerRotation] shouldAutorotate];
|
||||
}
|
||||
|
||||
// Which screen directions are supported.
|
||||
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
|
||||
return [[self viewControllerRotation] supportedInterfaceOrientations];
|
||||
}
|
||||
|
||||
// The default screen direction (the current ViewController must be represented by a modal UIViewController (which is not valid with modal navigation) to call this method).
|
||||
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
|
||||
return [[self viewControllerRotation] preferredInterfaceOrientationForPresentation];
|
||||
}
|
||||
|
||||
// Return ViewController which decide rotation,if selected in UITabBarController is UINavigationController,return topViewController
|
||||
- (UIViewController *)viewControllerRotation {
|
||||
UIViewController *vc = self.viewControllers[self.selectedIndex];
|
||||
if ([vc isKindOfClass:[UINavigationController class]]) {
|
||||
UINavigationController *nav = (UINavigationController *)vc;
|
||||
return nav.topViewController;
|
||||
} else {
|
||||
return vc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@implementation UINavigationController (ZFPlayerRotation)
|
||||
|
||||
/**
|
||||
* If the root view of the window is a UINavigationController, you call this Category first, and then UIViewController called.
|
||||
* All you need to do is revisit the following three methods on a page that supports directions other than portrait.
|
||||
*/
|
||||
|
||||
// Whether automatic screen rotation is supported
|
||||
- (BOOL)shouldAutorotate {
|
||||
return [self.topViewController shouldAutorotate];
|
||||
}
|
||||
|
||||
// Which screen directions are supported
|
||||
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
|
||||
return [self.topViewController supportedInterfaceOrientations];
|
||||
}
|
||||
|
||||
// The default screen direction (the current ViewController must be represented by a modal UIViewController (which is not valid with modal navigation) to call this method).
|
||||
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
|
||||
return [self.topViewController preferredInterfaceOrientationForPresentation];
|
||||
}
|
||||
|
||||
- (UIViewController *)childViewControllerForStatusBarStyle {
|
||||
return self.topViewController;
|
||||
}
|
||||
|
||||
- (UIViewController *)childViewControllerForStatusBarHidden {
|
||||
return self.topViewController;
|
||||
}
|
||||
|
||||
@end
|
||||
35
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFFloatView.h
generated
Executable file
35
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFFloatView.h
generated
Executable file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// ZFFloatView.h
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface ZFFloatView : UIView
|
||||
|
||||
/// The parent View
|
||||
@property(nonatomic, weak) UIView *parentView;
|
||||
|
||||
/// Safe margins, mainly for those with Navbar and tabbar
|
||||
@property(nonatomic, assign) UIEdgeInsets safeInsets;
|
||||
|
||||
@end
|
||||
85
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFFloatView.m
generated
Executable file
85
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFFloatView.m
generated
Executable file
@@ -0,0 +1,85 @@
|
||||
//
|
||||
// ZFFloatView.m
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "ZFFloatView.h"
|
||||
|
||||
@implementation ZFFloatView
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
[self initilize];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
|
||||
self = [super initWithCoder:aDecoder];
|
||||
if (self) {
|
||||
[self initilize];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)initilize {
|
||||
self.safeInsets = UIEdgeInsetsMake(0, 0, 0, 0);
|
||||
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(doMoveAction:)];
|
||||
[self addGestureRecognizer:panGestureRecognizer];
|
||||
}
|
||||
|
||||
- (void)setParentView:(UIView *)parentView {
|
||||
_parentView = parentView;
|
||||
[parentView addSubview:self];
|
||||
}
|
||||
|
||||
#pragma mark - Action
|
||||
|
||||
- (void)doMoveAction:(UIPanGestureRecognizer *)recognizer {
|
||||
/// The position where the gesture is moving in the self.view.
|
||||
CGPoint translation = [recognizer translationInView:self.parentView];
|
||||
CGPoint newCenter = CGPointMake(recognizer.view.center.x + translation.x,
|
||||
recognizer.view.center.y + translation.y);
|
||||
|
||||
// Limited screen range:
|
||||
// Top margin limit.
|
||||
newCenter.y = MAX(recognizer.view.frame.size.height/2 + self.safeInsets.top, newCenter.y);
|
||||
|
||||
// Bottom margin limit.
|
||||
newCenter.y = MIN(self.parentView.frame.size.height - self.safeInsets.bottom - recognizer.view.frame.size.height/2, newCenter.y);
|
||||
|
||||
// Left margin limit.
|
||||
newCenter.x = MAX(recognizer.view.frame.size.width/2, newCenter.x);
|
||||
|
||||
// Right margin limit.
|
||||
newCenter.x = MIN(self.parentView.frame.size.width - recognizer.view.frame.size.width/2,newCenter.x);
|
||||
|
||||
// Set the center point.
|
||||
recognizer.view.center = newCenter;
|
||||
|
||||
// Set the gesture coordinates to 0, otherwise it will add up.
|
||||
[recognizer setTranslation:CGPointZero inView:self.parentView];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
40
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFKVOController.h
generated
Normal file
40
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFKVOController.h
generated
Normal file
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// UIScrollView+ZFPlayer.m
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface ZFKVOController : NSObject
|
||||
|
||||
- (instancetype)initWithTarget:(NSObject *)target;
|
||||
|
||||
- (void)safelyAddObserver:(NSObject *)observer
|
||||
forKeyPath:(NSString *)keyPath
|
||||
options:(NSKeyValueObservingOptions)options
|
||||
context:(void *)context;
|
||||
- (void)safelyRemoveObserver:(NSObject *)observer
|
||||
forKeyPath:(NSString *)keyPath;
|
||||
|
||||
- (void)safelyRemoveAllObservers;
|
||||
|
||||
@end
|
||||
130
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFKVOController.m
generated
Normal file
130
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFKVOController.m
generated
Normal file
@@ -0,0 +1,130 @@
|
||||
//
|
||||
// UIScrollView+ZFPlayer.m
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "ZFKVOController.h"
|
||||
|
||||
@interface ZFKVOEntry : NSObject
|
||||
@property (nonatomic, weak) NSObject *observer;
|
||||
@property (nonatomic, copy) NSString *keyPath;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ZFKVOEntry
|
||||
|
||||
@end
|
||||
|
||||
@interface ZFKVOController ()
|
||||
@property (nonatomic, weak) NSObject *target;
|
||||
@property (nonatomic, strong) NSMutableArray *observerArray;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ZFKVOController
|
||||
|
||||
- (instancetype)initWithTarget:(NSObject *)target {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_target = target;
|
||||
_observerArray = [[NSMutableArray alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)safelyAddObserver:(NSObject *)observer
|
||||
forKeyPath:(NSString *)keyPath
|
||||
options:(NSKeyValueObservingOptions)options
|
||||
context:(void *)context {
|
||||
if (_target == nil) return;
|
||||
|
||||
NSInteger indexEntry = [self indexEntryOfObserver:observer forKeyPath:keyPath];
|
||||
if (indexEntry != NSNotFound) {
|
||||
// duplicated register
|
||||
NSLog(@"duplicated observer");
|
||||
} else {
|
||||
@try {
|
||||
[_target addObserver:observer
|
||||
forKeyPath:keyPath
|
||||
options:options
|
||||
context:context];
|
||||
|
||||
ZFKVOEntry *entry = [[ZFKVOEntry alloc] init];
|
||||
entry.observer = observer;
|
||||
entry.keyPath = keyPath;
|
||||
[_observerArray addObject:entry];
|
||||
} @catch (NSException *e) {
|
||||
NSLog(@"ZFKVO: failed to add observer for %@\n", keyPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)safelyRemoveObserver:(NSObject *)observer
|
||||
forKeyPath:(NSString *)keyPath {
|
||||
if (_target == nil) return;
|
||||
|
||||
NSInteger indexEntry = [self indexEntryOfObserver:observer forKeyPath:keyPath];
|
||||
if (indexEntry == NSNotFound) {
|
||||
// duplicated register
|
||||
NSLog(@"duplicated observer");
|
||||
} else {
|
||||
[_observerArray removeObjectAtIndex:indexEntry];
|
||||
@try {
|
||||
[_target removeObserver:observer
|
||||
forKeyPath:keyPath];
|
||||
} @catch (NSException *e) {
|
||||
NSLog(@"ZFKVO: failed to remove observer for %@\n", keyPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)safelyRemoveAllObservers {
|
||||
if (_target == nil) return;
|
||||
[_observerArray enumerateObjectsUsingBlock:^(ZFKVOEntry *entry, NSUInteger idx, BOOL *stop) {
|
||||
if (entry == nil) return;
|
||||
NSObject *observer = entry.observer;
|
||||
if (observer == nil) return;
|
||||
@try {
|
||||
[_target removeObserver:observer
|
||||
forKeyPath:entry.keyPath];
|
||||
} @catch (NSException *e) {
|
||||
NSLog(@"ZFKVO: failed to remove observer for %@\n", entry.keyPath);
|
||||
}
|
||||
}];
|
||||
|
||||
[_observerArray removeAllObjects];
|
||||
}
|
||||
|
||||
- (NSInteger)indexEntryOfObserver:(NSObject *)observer
|
||||
forKeyPath:(NSString *)keyPath {
|
||||
__block NSInteger foundIndex = NSNotFound;
|
||||
[_observerArray enumerateObjectsUsingBlock:^(ZFKVOEntry *entry, NSUInteger idx, BOOL *stop) {
|
||||
if (entry.observer == observer &&
|
||||
[entry.keyPath isEqualToString:keyPath]) {
|
||||
foundIndex = idx;
|
||||
*stop = YES;
|
||||
}
|
||||
}];
|
||||
return foundIndex;
|
||||
}
|
||||
|
||||
@end
|
||||
65
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFLandscapeViewController.h
generated
Normal file
65
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFLandscapeViewController.h
generated
Normal file
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// ZFFullscreenViewController.h
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
@class ZFLandscapeViewController;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol ZFLandscapeViewControllerDelegate <NSObject>
|
||||
|
||||
- (BOOL)ls_shouldAutorotate;
|
||||
- (void)ls_willRotateToOrientation:(UIInterfaceOrientation)orientation;
|
||||
- (void)ls_didRotateFromOrientation:(UIInterfaceOrientation)orientation;
|
||||
- (CGRect)ls_targetRect;
|
||||
|
||||
@end
|
||||
|
||||
@interface ZFLandscapeViewController : UIViewController
|
||||
|
||||
@property (nonatomic, weak) UIView *contentView;
|
||||
|
||||
@property (nonatomic, weak) UIView *containerView;
|
||||
|
||||
@property (nonatomic, assign) CGRect targetRect;
|
||||
|
||||
@property (nonatomic, weak, nullable) id<ZFLandscapeViewControllerDelegate> delegate;
|
||||
|
||||
@property (nonatomic, readonly) BOOL isFullscreen;
|
||||
|
||||
@property (nonatomic, getter=isRotating) BOOL rotating;
|
||||
|
||||
@property (nonatomic, assign) BOOL disableAnimations;
|
||||
|
||||
@property (nonatomic, assign) BOOL statusBarHidden;
|
||||
/// default is UIStatusBarStyleLightContent.
|
||||
@property (nonatomic, assign) UIStatusBarStyle statusBarStyle;
|
||||
/// defalut is UIStatusBarAnimationSlide.
|
||||
@property (nonatomic, assign) UIStatusBarAnimation statusBarAnimation;
|
||||
|
||||
@property (nonatomic, copy) void(^rotatingCompleted)(void);
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
140
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFLandscapeViewController.m
generated
Normal file
140
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFLandscapeViewController.m
generated
Normal file
@@ -0,0 +1,140 @@
|
||||
//
|
||||
// ZFFullScreenViewController.m
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "ZFLandscapeViewController.h"
|
||||
|
||||
@interface ZFLandscapeViewController ()
|
||||
|
||||
@property (nonatomic, assign) UIInterfaceOrientation currentOrientation;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ZFLandscapeViewController
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_currentOrientation = UIInterfaceOrientationPortrait;
|
||||
_statusBarStyle = UIStatusBarStyleLightContent;
|
||||
_statusBarAnimation = UIStatusBarAnimationSlide;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
|
||||
self.rotating = YES;
|
||||
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
||||
if (!UIDeviceOrientationIsValidInterfaceOrientation([UIDevice currentDevice].orientation)) {
|
||||
return;
|
||||
}
|
||||
UIInterfaceOrientation newOrientation = (UIInterfaceOrientation)[UIDevice currentDevice].orientation;
|
||||
UIInterfaceOrientation oldOrientation = _currentOrientation;
|
||||
if (UIInterfaceOrientationIsLandscape(newOrientation)) {
|
||||
if (self.contentView.superview != self.view) {
|
||||
[self.view addSubview:self.contentView];
|
||||
}
|
||||
}
|
||||
|
||||
if (oldOrientation == UIInterfaceOrientationPortrait) {
|
||||
self.contentView.frame = [self.delegate ls_targetRect];
|
||||
[self.contentView layoutIfNeeded];
|
||||
}
|
||||
self.currentOrientation = newOrientation;
|
||||
|
||||
[self.delegate ls_willRotateToOrientation:self.currentOrientation];
|
||||
BOOL isFullscreen = size.width > size.height;
|
||||
if (self.disableAnimations) {
|
||||
[CATransaction begin];
|
||||
[CATransaction setDisableActions:YES];
|
||||
}
|
||||
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
||||
if (isFullscreen) {
|
||||
self.contentView.frame = CGRectMake(0, 0, size.width, size.height);
|
||||
} else {
|
||||
self.contentView.frame = [self.delegate ls_targetRect];
|
||||
}
|
||||
[self.contentView layoutIfNeeded];
|
||||
} completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
||||
if (self.disableAnimations) {
|
||||
[CATransaction commit];
|
||||
}
|
||||
[self.delegate ls_didRotateFromOrientation:self.currentOrientation];
|
||||
if (!isFullscreen) {
|
||||
self.contentView.frame = self.containerView.bounds;
|
||||
[self.contentView layoutIfNeeded];
|
||||
}
|
||||
self.disableAnimations = NO;
|
||||
self.rotating = NO;
|
||||
}];
|
||||
}
|
||||
|
||||
- (BOOL)isFullscreen {
|
||||
return UIInterfaceOrientationIsLandscape(_currentOrientation);
|
||||
}
|
||||
|
||||
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
|
||||
return UIInterfaceOrientationPortrait;
|
||||
}
|
||||
|
||||
- (BOOL)shouldAutorotate {
|
||||
return [self.delegate ls_shouldAutorotate];
|
||||
}
|
||||
|
||||
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
|
||||
UIInterfaceOrientation currentOrientation = (UIInterfaceOrientation)[UIDevice currentDevice].orientation;
|
||||
if (UIInterfaceOrientationIsLandscape(currentOrientation)) {
|
||||
return UIInterfaceOrientationMaskLandscape;
|
||||
}
|
||||
return UIInterfaceOrientationMaskAll;
|
||||
}
|
||||
|
||||
- (BOOL)prefersHomeIndicatorAutoHidden {
|
||||
UIInterfaceOrientation currentOrientation = (UIInterfaceOrientation)[UIDevice currentDevice].orientation;
|
||||
if (UIInterfaceOrientationIsLandscape(currentOrientation)) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)prefersStatusBarHidden {
|
||||
return self.statusBarHidden;
|
||||
}
|
||||
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle {
|
||||
return self.statusBarStyle;
|
||||
}
|
||||
|
||||
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
|
||||
return self.statusBarAnimation;
|
||||
}
|
||||
|
||||
- (void)setRotating:(BOOL)rotating {
|
||||
_rotating = rotating;
|
||||
if (!rotating && self.rotatingCompleted) {
|
||||
self.rotatingCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
36
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFLandscapeWindow.h
generated
Normal file
36
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFLandscapeWindow.h
generated
Normal file
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// ZFLandScaprWindow.h
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "ZFLandscapeViewController.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface ZFLandscapeWindow : UIWindow
|
||||
|
||||
@property (nonatomic, strong, readonly) ZFLandscapeViewController *landscapeViewController;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
75
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFLandscapeWindow.m
generated
Normal file
75
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFLandscapeWindow.m
generated
Normal file
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// ZFLandScaprWindow.m
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "ZFLandscapeWindow.h"
|
||||
|
||||
@implementation ZFLandscapeWindow
|
||||
@dynamic rootViewController;
|
||||
|
||||
- (void)setBackgroundColor:(nullable UIColor *)backgroundColor {}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
self.windowLevel = UIWindowLevelNormal;
|
||||
_landscapeViewController = [[ZFLandscapeViewController alloc] init];
|
||||
self.rootViewController = _landscapeViewController;
|
||||
if (@available(iOS 13.0, *)) {
|
||||
if (self.windowScene == nil) {
|
||||
self.windowScene = UIApplication.sharedApplication.keyWindow.windowScene;
|
||||
}
|
||||
}
|
||||
self.hidden = YES;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *_Nullable)event {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews {
|
||||
[super layoutSubviews];
|
||||
static CGRect bounds;
|
||||
if (!CGRectEqualToRect(bounds, self.bounds)) {
|
||||
UIView *superview = self;
|
||||
if (@available(iOS 13.0, *)) {
|
||||
superview = self.subviews.firstObject;
|
||||
}
|
||||
[UIView performWithoutAnimation:^{
|
||||
for (UIView *view in superview.subviews) {
|
||||
if (view != self.rootViewController.view && [view isMemberOfClass:UIView.class]) {
|
||||
view.backgroundColor = UIColor.clearColor;
|
||||
for (UIView *subview in view.subviews) {
|
||||
subview.backgroundColor = UIColor.clearColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
bounds = self.bounds;
|
||||
self.rootViewController.view.frame = bounds;
|
||||
}
|
||||
|
||||
@end
|
||||
170
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFOrientationObserver.h
generated
Executable file
170
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFOrientationObserver.h
generated
Executable file
@@ -0,0 +1,170 @@
|
||||
//
|
||||
// ZFOrentationObserver.h
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "ZFPlayerView.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/// Full screen mode
|
||||
typedef NS_ENUM(NSUInteger, ZFFullScreenMode) {
|
||||
ZFFullScreenModeAutomatic, // Determine full screen mode automatically
|
||||
ZFFullScreenModeLandscape, // Landscape full screen mode
|
||||
ZFFullScreenModePortrait // Portrait full screen Model
|
||||
};
|
||||
|
||||
/// Portrait full screen mode.
|
||||
typedef NS_ENUM(NSUInteger, ZFPortraitFullScreenMode) {
|
||||
ZFPortraitFullScreenModeScaleToFill, // Full fill
|
||||
ZFPortraitFullScreenModeScaleAspectFit // contents scaled to fit with fixed aspect. remainder is transparent
|
||||
};
|
||||
|
||||
/// Player view mode
|
||||
typedef NS_ENUM(NSUInteger, ZFRotateType) {
|
||||
ZFRotateTypeNormal, // Normal
|
||||
ZFRotateTypeCell // Cell
|
||||
};
|
||||
|
||||
/**
|
||||
Rotation of support direction
|
||||
*/
|
||||
typedef NS_OPTIONS(NSUInteger, ZFInterfaceOrientationMask) {
|
||||
ZFInterfaceOrientationMaskPortrait = (1 << 0),
|
||||
ZFInterfaceOrientationMaskLandscapeLeft = (1 << 1),
|
||||
ZFInterfaceOrientationMaskLandscapeRight = (1 << 2),
|
||||
ZFInterfaceOrientationMaskPortraitUpsideDown = (1 << 3),
|
||||
ZFInterfaceOrientationMaskLandscape = (ZFInterfaceOrientationMaskLandscapeLeft | ZFInterfaceOrientationMaskLandscapeRight),
|
||||
ZFInterfaceOrientationMaskAll = (ZFInterfaceOrientationMaskPortrait | ZFInterfaceOrientationMaskLandscape | ZFInterfaceOrientationMaskPortraitUpsideDown),
|
||||
ZFInterfaceOrientationMaskAllButUpsideDown = (ZFInterfaceOrientationMaskPortrait | ZFInterfaceOrientationMaskLandscape),
|
||||
};
|
||||
|
||||
/// This enumeration lists some of the gesture types that the player has by default.
|
||||
typedef NS_OPTIONS(NSUInteger, ZFDisablePortraitGestureTypes) {
|
||||
ZFDisablePortraitGestureTypesNone = 0,
|
||||
ZFDisablePortraitGestureTypesTap = 1 << 0,
|
||||
ZFDisablePortraitGestureTypesPan = 1 << 1,
|
||||
ZFDisablePortraitGestureTypesAll = (ZFDisablePortraitGestureTypesTap | ZFDisablePortraitGestureTypesPan)
|
||||
};
|
||||
|
||||
@protocol ZFPortraitOrientationDelegate <NSObject>
|
||||
|
||||
- (void)zf_orientationWillChange:(BOOL)isFullScreen;
|
||||
|
||||
- (void)zf_orientationDidChanged:(BOOL)isFullScreen;
|
||||
|
||||
- (void)zf_interationState:(BOOL)isDragging;
|
||||
|
||||
@end
|
||||
|
||||
@interface ZFOrientationObserver : NSObject
|
||||
|
||||
/// update the rotateView and containerView.
|
||||
- (void)updateRotateView:(ZFPlayerView *)rotateView
|
||||
containerView:(UIView *)containerView;
|
||||
|
||||
/// list play
|
||||
- (void)updateRotateView:(ZFPlayerView *)rotateView
|
||||
rotateViewAtCell:(UIView *)cell
|
||||
playerViewTag:(NSInteger)playerViewTag;
|
||||
|
||||
/// Container view of a full screen state player.
|
||||
@property (nonatomic, strong) UIView *fullScreenContainerView;
|
||||
|
||||
/// Container view of a small screen state player.
|
||||
@property (nonatomic, weak) UIView *containerView;
|
||||
|
||||
/// The block invoked When player will rotate.
|
||||
@property (nonatomic, copy, nullable) void(^orientationWillChange)(ZFOrientationObserver *observer, BOOL isFullScreen);
|
||||
|
||||
/// The block invoked when player rotated.
|
||||
@property (nonatomic, copy, nullable) void(^orientationDidChanged)(ZFOrientationObserver *observer, BOOL isFullScreen);
|
||||
|
||||
/// Full screen mode, the default landscape into full screen
|
||||
@property (nonatomic) ZFFullScreenMode fullScreenMode;
|
||||
|
||||
@property (nonatomic, assign) ZFPortraitFullScreenMode portraitFullScreenMode;
|
||||
|
||||
/// rotate duration, default is 0.30
|
||||
@property (nonatomic) NSTimeInterval duration;
|
||||
|
||||
/// If the full screen.
|
||||
@property (nonatomic, readonly, getter=isFullScreen) BOOL fullScreen;
|
||||
|
||||
/// Lock screen orientation
|
||||
@property (nonatomic, getter=isLockedScreen) BOOL lockedScreen;
|
||||
|
||||
/// The fullscreen statusbar hidden.
|
||||
@property (nonatomic, assign) BOOL fullScreenStatusBarHidden;
|
||||
|
||||
/// default is UIStatusBarStyleLightContent.
|
||||
@property (nonatomic, assign) UIStatusBarStyle fullScreenStatusBarStyle;
|
||||
|
||||
/// defalut is UIStatusBarAnimationSlide.
|
||||
@property (nonatomic, assign) UIStatusBarAnimation fullScreenStatusBarAnimation;
|
||||
|
||||
@property (nonatomic, assign) CGSize presentationSize;
|
||||
|
||||
/// default is ZFDisablePortraitGestureTypesAll.
|
||||
@property (nonatomic, assign) ZFDisablePortraitGestureTypes disablePortraitGestureTypes;
|
||||
|
||||
/// The current orientation of the player.
|
||||
/// Default is UIInterfaceOrientationPortrait.
|
||||
@property (nonatomic, readonly) UIInterfaceOrientation currentOrientation;
|
||||
|
||||
/// Whether allow the video orientation rotate.
|
||||
/// default is YES.
|
||||
@property (nonatomic, assign) BOOL allowOrientationRotation;
|
||||
|
||||
/// The support Interface Orientation,default is ZFInterfaceOrientationMaskAllButUpsideDown
|
||||
@property (nonatomic, assign) ZFInterfaceOrientationMask supportInterfaceOrientation;
|
||||
|
||||
/// Add the device orientation observer.
|
||||
- (void)addDeviceOrientationObserver;
|
||||
|
||||
/// Remove the device orientation observer.
|
||||
- (void)removeDeviceOrientationObserver;
|
||||
|
||||
/// Enter the fullScreen while the ZFFullScreenMode is ZFFullScreenModeLandscape.
|
||||
- (void)rotateToOrientation:(UIInterfaceOrientation)orientation animated:(BOOL)animated;
|
||||
|
||||
/// Enter the fullScreen while the ZFFullScreenMode is ZFFullScreenModeLandscape.
|
||||
- (void)rotateToOrientation:(UIInterfaceOrientation)orientation animated:(BOOL)animated completion:(void(^ __nullable)(void))completion;
|
||||
|
||||
/// Enter the fullScreen while the ZFFullScreenMode is ZFFullScreenModePortrait.
|
||||
- (void)enterPortraitFullScreen:(BOOL)fullScreen animated:(BOOL)animated;
|
||||
|
||||
/// Enter the fullScreen while the ZFFullScreenMode is ZFFullScreenModePortrait.
|
||||
- (void)enterPortraitFullScreen:(BOOL)fullScreen animated:(BOOL)animated completion:(void(^ __nullable)(void))completion;
|
||||
|
||||
/// FullScreen mode is determined by ZFFullScreenMode.
|
||||
- (void)enterFullScreen:(BOOL)fullScreen animated:(BOOL)animated;
|
||||
|
||||
/// FullScreen mode is determined by ZFFullScreenMode.
|
||||
- (void)enterFullScreen:(BOOL)fullScreen animated:(BOOL)animated completion:(void (^ _Nullable)(void))completion;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
|
||||
551
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFOrientationObserver.m
generated
Executable file
551
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFOrientationObserver.m
generated
Executable file
@@ -0,0 +1,551 @@
|
||||
|
||||
// ZFOrentationObserver.m
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "ZFOrientationObserver.h"
|
||||
#import "ZFLandscapeWindow.h"
|
||||
#import "ZFPortraitViewController.h"
|
||||
#import "ZFPlayerConst.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
@interface UIWindow (CurrentViewController)
|
||||
|
||||
/*!
|
||||
@method currentViewController
|
||||
@return Returns the topViewController in stack of topMostController.
|
||||
*/
|
||||
+ (UIViewController*)zf_currentViewController;
|
||||
|
||||
@end
|
||||
|
||||
@implementation UIWindow (CurrentViewController)
|
||||
|
||||
+ (UIViewController*)zf_currentViewController; {
|
||||
__block UIWindow *window;
|
||||
if (@available(iOS 13, *)) {
|
||||
[[UIApplication sharedApplication].connectedScenes enumerateObjectsUsingBlock:^(UIScene * _Nonnull scene, BOOL * _Nonnull scenesStop) {
|
||||
if ([scene isKindOfClass: [UIWindowScene class]]) {
|
||||
UIWindowScene * windowScene = (UIWindowScene *)scene;
|
||||
[windowScene.windows enumerateObjectsUsingBlock:^(UIWindow * _Nonnull windowTemp, NSUInteger idx, BOOL * _Nonnull windowStop) {
|
||||
if (windowTemp.isKeyWindow) {
|
||||
window = windowTemp;
|
||||
*windowStop = YES;
|
||||
*scenesStop = YES;
|
||||
}
|
||||
}];
|
||||
}
|
||||
}];
|
||||
} else {
|
||||
window = [[UIApplication sharedApplication].delegate window];
|
||||
}
|
||||
UIViewController *topViewController = [window rootViewController];
|
||||
while (true) {
|
||||
if (topViewController.presentedViewController) {
|
||||
topViewController = topViewController.presentedViewController;
|
||||
} else if ([topViewController isKindOfClass:[UINavigationController class]] && [(UINavigationController *)topViewController topViewController]) {
|
||||
topViewController = [(UINavigationController *)topViewController topViewController];
|
||||
} else if ([topViewController isKindOfClass:[UITabBarController class]]) {
|
||||
UITabBarController *tab = (UITabBarController *)topViewController;
|
||||
topViewController = tab.selectedViewController;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return topViewController;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface ZFOrientationObserver () <ZFLandscapeViewControllerDelegate>
|
||||
|
||||
@property (nonatomic, weak) ZFPlayerView *view;
|
||||
|
||||
@property (nonatomic, assign, getter=isFullScreen) BOOL fullScreen;
|
||||
|
||||
@property (nonatomic, strong) UIView *cell;
|
||||
|
||||
@property (nonatomic, assign) NSInteger playerViewTag;
|
||||
|
||||
@property (nonatomic, assign) ZFRotateType rotateType;
|
||||
|
||||
@property (nonatomic, strong) UIWindow *previousKeyWindow;
|
||||
|
||||
@property (nonatomic, strong) ZFLandscapeWindow *window;
|
||||
|
||||
@property (nonatomic, readonly, getter=isRotating) BOOL rotating;
|
||||
|
||||
@property (nonatomic, strong) ZFPortraitViewController *portraitViewController;
|
||||
|
||||
/// current device orientation observer is activie.
|
||||
@property (nonatomic, assign) BOOL activeDeviceObserver;
|
||||
|
||||
/// Force Rotaion, default NO.
|
||||
@property (nonatomic, assign) BOOL forceRotaion;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ZFOrientationObserver
|
||||
@synthesize presentationSize = _presentationSize;
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_duration = 0.30;
|
||||
_fullScreenMode = ZFFullScreenModeLandscape;
|
||||
_supportInterfaceOrientation = ZFInterfaceOrientationMaskAllButUpsideDown;
|
||||
_allowOrientationRotation = YES;
|
||||
_rotateType = ZFRotateTypeNormal;
|
||||
_currentOrientation = UIInterfaceOrientationPortrait;
|
||||
_portraitFullScreenMode = ZFPortraitFullScreenModeScaleToFill;
|
||||
_disablePortraitGestureTypes = ZFDisablePortraitGestureTypesAll;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)updateRotateView:(ZFPlayerView *)rotateView
|
||||
containerView:(UIView *)containerView {
|
||||
self.rotateType = ZFRotateTypeNormal;
|
||||
self.view = rotateView;
|
||||
self.containerView = containerView;
|
||||
}
|
||||
|
||||
- (void)updateRotateView:(ZFPlayerView *)rotateView rotateViewAtCell:(UIView *)cell playerViewTag:(NSInteger)playerViewTag {
|
||||
self.rotateType = ZFRotateTypeCell;
|
||||
self.view = rotateView;
|
||||
self.cell = cell;
|
||||
self.playerViewTag = playerViewTag;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[self removeDeviceOrientationObserver];
|
||||
}
|
||||
|
||||
- (void)addDeviceOrientationObserver {
|
||||
if (self.allowOrientationRotation) {
|
||||
self.activeDeviceObserver = YES;
|
||||
if (![UIDevice currentDevice].generatesDeviceOrientationNotifications) {
|
||||
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
|
||||
}
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDeviceOrientationChange) name:UIDeviceOrientationDidChangeNotification object:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeDeviceOrientationObserver {
|
||||
self.activeDeviceObserver = NO;
|
||||
if (![UIDevice currentDevice].generatesDeviceOrientationNotifications) {
|
||||
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
|
||||
}
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)handleDeviceOrientationChange {
|
||||
if (self.fullScreenMode == ZFFullScreenModePortrait || !self.allowOrientationRotation) return;
|
||||
if (!UIDeviceOrientationIsValidInterfaceOrientation([UIDevice currentDevice].orientation)) {
|
||||
return;
|
||||
}
|
||||
UIInterfaceOrientation currentOrientation = (UIInterfaceOrientation)[UIDevice currentDevice].orientation;
|
||||
|
||||
// Determine that if the current direction is the same as the direction you want to rotate, do nothing
|
||||
if (currentOrientation == _currentOrientation) return;
|
||||
_currentOrientation = currentOrientation;
|
||||
if (_currentOrientation == UIInterfaceOrientationPortraitUpsideDown) return;
|
||||
|
||||
switch (currentOrientation) {
|
||||
case UIInterfaceOrientationPortrait: {
|
||||
if ([self _isSupportedPortrait]) {
|
||||
[self rotateToOrientation:UIInterfaceOrientationPortrait animated:YES];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UIInterfaceOrientationLandscapeLeft: {
|
||||
if ([self _isSupportedLandscapeLeft]) {
|
||||
[self rotateToOrientation:UIInterfaceOrientationLandscapeLeft animated:YES];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UIInterfaceOrientationLandscapeRight: {
|
||||
if ([self _isSupportedLandscapeRight]) {
|
||||
[self rotateToOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)interfaceOrientation:(UIInterfaceOrientation)orientation {
|
||||
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
|
||||
SEL selector = NSSelectorFromString(@"setOrientation:");
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
|
||||
[invocation setSelector:selector];
|
||||
[invocation setTarget:[UIDevice currentDevice]];
|
||||
UIInterfaceOrientation val = orientation;
|
||||
[invocation setArgument:&val atIndex:2];
|
||||
[invocation invoke];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - public
|
||||
|
||||
- (void)rotateToOrientation:(UIInterfaceOrientation)orientation animated:(BOOL)animated {
|
||||
[self rotateToOrientation:orientation animated:animated completion:nil];
|
||||
}
|
||||
|
||||
- (void)rotateToOrientation:(UIInterfaceOrientation)orientation animated:(BOOL)animated completion:(void(^ __nullable)(void))completion {
|
||||
if (self.fullScreenMode == ZFFullScreenModePortrait) return;
|
||||
_currentOrientation = orientation;
|
||||
self.forceRotaion = YES;
|
||||
if (UIInterfaceOrientationIsLandscape(orientation)) {
|
||||
if (!self.fullScreen) {
|
||||
UIView *containerView = nil;
|
||||
if (self.rotateType == ZFRotateTypeCell) {
|
||||
containerView = [self.cell viewWithTag:self.playerViewTag];
|
||||
} else {
|
||||
containerView = self.containerView;
|
||||
}
|
||||
CGRect targetRect = [self.view convertRect:self.view.frame toView:containerView.window];
|
||||
|
||||
if (!self.window) {
|
||||
self.window = [ZFLandscapeWindow new];
|
||||
self.window.landscapeViewController.delegate = self;
|
||||
if (@available(iOS 9.0, *)) {
|
||||
[self.window.rootViewController loadViewIfNeeded];
|
||||
} else {
|
||||
[self.window.rootViewController view];
|
||||
}
|
||||
}
|
||||
|
||||
self.window.landscapeViewController.targetRect = targetRect;
|
||||
self.window.landscapeViewController.contentView = self.view;
|
||||
self.window.landscapeViewController.containerView = self.containerView;
|
||||
self.fullScreen = YES;
|
||||
}
|
||||
if (self.orientationWillChange) self.orientationWillChange(self, self.isFullScreen);
|
||||
} else {
|
||||
self.fullScreen = NO;
|
||||
}
|
||||
self.window.landscapeViewController.disableAnimations = !animated;
|
||||
@zf_weakify(self)
|
||||
self.window.landscapeViewController.rotatingCompleted = ^{
|
||||
@zf_strongify(self)
|
||||
self.forceRotaion = NO;
|
||||
if (completion) completion();
|
||||
};
|
||||
|
||||
[self interfaceOrientation:UIInterfaceOrientationUnknown];
|
||||
[self interfaceOrientation:orientation];
|
||||
}
|
||||
|
||||
- (void)enterPortraitFullScreen:(BOOL)fullScreen animated:(BOOL)animated {
|
||||
[self enterPortraitFullScreen:fullScreen animated:animated completion:nil];
|
||||
}
|
||||
|
||||
- (void)enterPortraitFullScreen:(BOOL)fullScreen animated:(BOOL)animated completion:(void(^ __nullable)(void))completion {
|
||||
self.fullScreen = fullScreen;
|
||||
if (fullScreen) {
|
||||
self.portraitViewController.contentView = self.view;
|
||||
self.portraitViewController.containerView = self.containerView;
|
||||
self.portraitViewController.duration = self.duration;
|
||||
if (self.portraitFullScreenMode == ZFPortraitFullScreenModeScaleAspectFit) {
|
||||
self.portraitViewController.presentationSize = self.presentationSize;
|
||||
} else if (self.portraitFullScreenMode == ZFPortraitFullScreenModeScaleToFill) {
|
||||
self.portraitViewController.presentationSize = CGSizeMake(ZFPlayerScreenWidth, ZFPlayerScreenHeight);
|
||||
}
|
||||
self.portraitViewController.fullScreenAnimation = animated;
|
||||
[[UIWindow zf_currentViewController] presentViewController:self.portraitViewController animated:animated completion:^{
|
||||
if (completion) completion();
|
||||
}];
|
||||
} else {
|
||||
self.portraitViewController.fullScreenAnimation = animated;
|
||||
[self.portraitViewController dismissViewControllerAnimated:animated completion:^{
|
||||
if (completion) completion();
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)enterFullScreen:(BOOL)fullScreen animated:(BOOL)animated {
|
||||
[self enterFullScreen:fullScreen animated:animated];
|
||||
}
|
||||
|
||||
- (void)enterFullScreen:(BOOL)fullScreen animated:(BOOL)animated completion:(void (^ _Nullable)(void))completion {
|
||||
if (self.fullScreenMode == ZFFullScreenModePortrait) {
|
||||
[self enterPortraitFullScreen:fullScreen animated:animated completion:completion];
|
||||
} else {
|
||||
UIInterfaceOrientation orientation = UIInterfaceOrientationUnknown;
|
||||
orientation = fullScreen? UIInterfaceOrientationLandscapeRight : UIInterfaceOrientationPortrait;
|
||||
[self rotateToOrientation:orientation animated:animated completion:completion];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - private
|
||||
|
||||
/// is support portrait
|
||||
- (BOOL)_isSupportedPortrait {
|
||||
return self.supportInterfaceOrientation & ZFInterfaceOrientationMaskPortrait;
|
||||
}
|
||||
|
||||
/// is support landscapeLeft
|
||||
- (BOOL)_isSupportedLandscapeLeft {
|
||||
return self.supportInterfaceOrientation & ZFInterfaceOrientationMaskLandscapeLeft;
|
||||
}
|
||||
|
||||
/// is support landscapeRight
|
||||
- (BOOL)_isSupportedLandscapeRight {
|
||||
return self.supportInterfaceOrientation & ZFInterfaceOrientationMaskLandscapeRight;
|
||||
}
|
||||
|
||||
- (BOOL)_isSupported:(UIInterfaceOrientation)orientation {
|
||||
switch (orientation) {
|
||||
case UIInterfaceOrientationPortrait:
|
||||
return self.supportInterfaceOrientation & ZFInterfaceOrientationMaskPortrait;
|
||||
case UIInterfaceOrientationLandscapeLeft:
|
||||
return self.supportInterfaceOrientation & ZFInterfaceOrientationMaskLandscapeLeft;
|
||||
case UIInterfaceOrientationLandscapeRight:
|
||||
return self.supportInterfaceOrientation & ZFInterfaceOrientationMaskLandscapeRight;
|
||||
default:
|
||||
return NO;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)_rotationToLandscapeOrientation:(UIInterfaceOrientation)orientation {
|
||||
if (UIInterfaceOrientationIsLandscape(orientation)) {
|
||||
UIWindow *keyWindow = UIApplication.sharedApplication.keyWindow;
|
||||
if (keyWindow != self.window && self.previousKeyWindow != keyWindow) {
|
||||
self.previousKeyWindow = UIApplication.sharedApplication.keyWindow;
|
||||
}
|
||||
if (!self.window.isKeyWindow) {
|
||||
self.window.hidden = NO;
|
||||
[self.window makeKeyAndVisible];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_rotationToPortraitOrientation:(UIInterfaceOrientation)orientation {
|
||||
if (orientation == UIInterfaceOrientationPortrait && !self.window.hidden) {
|
||||
UIView *containerView = nil;
|
||||
if (self.rotateType == ZFRotateTypeCell) {
|
||||
containerView = [self.cell viewWithTag:self.playerViewTag];
|
||||
} else {
|
||||
containerView = self.containerView;
|
||||
}
|
||||
UIView *snapshot = [self.view snapshotViewAfterScreenUpdates:NO];
|
||||
snapshot.frame = containerView.bounds;
|
||||
[containerView addSubview:snapshot];
|
||||
[self performSelector:@selector(_contentViewAdd:) onThread:NSThread.mainThread withObject:containerView waitUntilDone:NO modes:@[NSDefaultRunLoopMode]];
|
||||
[self performSelector:@selector(_makeKeyAndVisible:) onThread:NSThread.mainThread withObject:snapshot waitUntilDone:NO modes:@[NSDefaultRunLoopMode]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_contentViewAdd:(UIView *)containerView {
|
||||
[containerView addSubview:self.view];
|
||||
self.view.frame = containerView.bounds;
|
||||
[self.view layoutIfNeeded];
|
||||
}
|
||||
|
||||
- (void)_makeKeyAndVisible:(UIView *)snapshot {
|
||||
[snapshot removeFromSuperview];
|
||||
UIWindow *previousKeyWindow = self.previousKeyWindow ?: UIApplication.sharedApplication.windows.firstObject;
|
||||
[previousKeyWindow makeKeyAndVisible];
|
||||
self.previousKeyWindow = nil;
|
||||
self.window.hidden = YES;
|
||||
}
|
||||
|
||||
#pragma mark - ZFLandscapeViewControllerDelegate
|
||||
|
||||
- (BOOL)ls_shouldAutorotate {
|
||||
if (self.fullScreenMode == ZFFullScreenModePortrait) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
UIInterfaceOrientation currentOrientation = (UIInterfaceOrientation)[UIDevice currentDevice].orientation;
|
||||
if (![self _isSupported:currentOrientation]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (self.forceRotaion) {
|
||||
[self _rotationToLandscapeOrientation:currentOrientation];
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (!self.activeDeviceObserver) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
[self _rotationToLandscapeOrientation:currentOrientation];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)ls_willRotateToOrientation:(UIInterfaceOrientation)orientation {
|
||||
self.fullScreen = UIInterfaceOrientationIsLandscape(orientation);
|
||||
if (self.orientationWillChange) self.orientationWillChange(self, self.isFullScreen);
|
||||
}
|
||||
|
||||
- (void)ls_didRotateFromOrientation:(UIInterfaceOrientation)orientation {
|
||||
if (self.orientationDidChanged) self.orientationDidChanged(self, self.isFullScreen);
|
||||
if (!self.isFullScreen) {
|
||||
[self _rotationToPortraitOrientation:UIInterfaceOrientationPortrait];
|
||||
}
|
||||
}
|
||||
|
||||
- (CGRect)ls_targetRect {
|
||||
UIView *containerView = nil;
|
||||
if (self.rotateType == ZFRotateTypeCell) {
|
||||
containerView = [self.cell viewWithTag:self.playerViewTag];
|
||||
} else {
|
||||
containerView = self.containerView;
|
||||
}
|
||||
CGRect targetRect = [containerView convertRect:containerView.bounds toView:containerView.window];
|
||||
return targetRect;
|
||||
}
|
||||
|
||||
#pragma mark - getter
|
||||
|
||||
- (ZFPortraitViewController *)portraitViewController {
|
||||
if (!_portraitViewController) {
|
||||
@zf_weakify(self)
|
||||
_portraitViewController = [[ZFPortraitViewController alloc] init];
|
||||
if (@available(iOS 9.0, *)) {
|
||||
[_portraitViewController loadViewIfNeeded];
|
||||
} else {
|
||||
[_portraitViewController view];
|
||||
}
|
||||
_portraitViewController.orientationWillChange = ^(BOOL isFullScreen) {
|
||||
@zf_strongify(self)
|
||||
self.fullScreen = isFullScreen;
|
||||
if (self.orientationWillChange) self.orientationWillChange(self, isFullScreen);
|
||||
};
|
||||
_portraitViewController.orientationDidChanged = ^(BOOL isFullScreen) {
|
||||
@zf_strongify(self)
|
||||
self.fullScreen = isFullScreen;
|
||||
if (self.orientationDidChanged) self.orientationDidChanged(self, isFullScreen);
|
||||
};
|
||||
}
|
||||
return _portraitViewController;
|
||||
}
|
||||
|
||||
#pragma mark - setter
|
||||
|
||||
- (void)setLockedScreen:(BOOL)lockedScreen {
|
||||
_lockedScreen = lockedScreen;
|
||||
if (lockedScreen) {
|
||||
[self removeDeviceOrientationObserver];
|
||||
} else {
|
||||
[self addDeviceOrientationObserver];
|
||||
}
|
||||
}
|
||||
|
||||
- (UIView *)fullScreenContainerView {
|
||||
if (self.fullScreenMode == ZFFullScreenModeLandscape) {
|
||||
return self.window.landscapeViewController.view;
|
||||
} else if (self.fullScreenMode == ZFFullScreenModePortrait) {
|
||||
return self.portraitViewController.view;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)setFullScreen:(BOOL)fullScreen {
|
||||
_fullScreen = fullScreen;
|
||||
[self.window.landscapeViewController setNeedsStatusBarAppearanceUpdate];
|
||||
[UIViewController attemptRotationToDeviceOrientation];
|
||||
}
|
||||
|
||||
- (void)setFullScreenStatusBarHidden:(BOOL)fullScreenStatusBarHidden {
|
||||
_fullScreenStatusBarHidden = fullScreenStatusBarHidden;
|
||||
if (self.fullScreenMode == ZFFullScreenModePortrait) {
|
||||
self.portraitViewController.statusBarHidden = fullScreenStatusBarHidden;
|
||||
[self.portraitViewController setNeedsStatusBarAppearanceUpdate];
|
||||
} else if (self.fullScreenMode == ZFFullScreenModeLandscape) {
|
||||
self.window.landscapeViewController.statusBarHidden = fullScreenStatusBarHidden;
|
||||
[self.window.landscapeViewController setNeedsStatusBarAppearanceUpdate];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setFullScreenStatusBarStyle:(UIStatusBarStyle)fullScreenStatusBarStyle {
|
||||
_fullScreenStatusBarStyle = fullScreenStatusBarStyle;
|
||||
if (self.fullScreenMode == ZFFullScreenModePortrait) {
|
||||
self.portraitViewController.statusBarStyle = fullScreenStatusBarStyle;
|
||||
[self.portraitViewController setNeedsStatusBarAppearanceUpdate];
|
||||
} else if (self.fullScreenMode == ZFFullScreenModeLandscape) {
|
||||
self.window.landscapeViewController.statusBarStyle = fullScreenStatusBarStyle;
|
||||
[self.window.landscapeViewController setNeedsStatusBarAppearanceUpdate];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setFullScreenStatusBarAnimation:(UIStatusBarAnimation)fullScreenStatusBarAnimation {
|
||||
_fullScreenStatusBarAnimation = fullScreenStatusBarAnimation;
|
||||
if (self.fullScreenMode == ZFFullScreenModePortrait) {
|
||||
self.portraitViewController.statusBarAnimation = fullScreenStatusBarAnimation;
|
||||
[self.portraitViewController setNeedsStatusBarAppearanceUpdate];
|
||||
} else if (self.fullScreenMode == ZFFullScreenModeLandscape) {
|
||||
self.window.landscapeViewController.statusBarAnimation = fullScreenStatusBarAnimation;
|
||||
[self.window.landscapeViewController setNeedsStatusBarAppearanceUpdate];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setDisablePortraitGestureTypes:(ZFDisablePortraitGestureTypes)disablePortraitGestureTypes {
|
||||
_disablePortraitGestureTypes = disablePortraitGestureTypes;
|
||||
self.portraitViewController.disablePortraitGestureTypes = disablePortraitGestureTypes;
|
||||
}
|
||||
|
||||
- (void)setPresentationSize:(CGSize)presentationSize {
|
||||
_presentationSize = presentationSize;
|
||||
if (self.fullScreenMode == ZFFullScreenModePortrait && self.portraitFullScreenMode == ZFPortraitFullScreenModeScaleAspectFit) {
|
||||
self.portraitViewController.presentationSize = presentationSize;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setView:(ZFPlayerView *)view {
|
||||
if (view == _view) {
|
||||
return;
|
||||
}
|
||||
_view = view;
|
||||
if (self.fullScreenMode == ZFFullScreenModeLandscape && self.window) {
|
||||
self.window.landscapeViewController.contentView = view;
|
||||
} else if (self.fullScreenMode == ZFFullScreenModePortrait) {
|
||||
self.portraitViewController.contentView = view;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setContainerView:(UIView *)containerView {
|
||||
if (containerView == _containerView) {
|
||||
return;
|
||||
}
|
||||
_containerView = containerView;
|
||||
if (self.fullScreenMode == ZFFullScreenModeLandscape) {
|
||||
self.window.landscapeViewController.containerView = containerView;
|
||||
} else if (self.fullScreenMode == ZFFullScreenModePortrait) {
|
||||
self.portraitViewController.containerView = containerView;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setAllowOrientationRotation:(BOOL)allowOrientationRotation {
|
||||
_allowOrientationRotation = allowOrientationRotation;
|
||||
if (allowOrientationRotation) {
|
||||
[self addDeviceOrientationObserver];
|
||||
} else {
|
||||
[self removeDeviceOrientationObserver];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
47
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPersentInteractiveTransition.h
generated
Normal file
47
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPersentInteractiveTransition.h
generated
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// ZFPersentInteractiveTransition.h
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "ZFOrientationObserver.h"
|
||||
|
||||
@interface ZFPersentInteractiveTransition : UIPercentDrivenInteractiveTransition
|
||||
|
||||
@property (nonatomic, weak) id<ZFPortraitOrientationDelegate> delagate;
|
||||
|
||||
@property (nonatomic, assign) BOOL interation;
|
||||
|
||||
/// default is ZFDisablePortraitGestureTypesNone.
|
||||
@property (nonatomic, assign) ZFDisablePortraitGestureTypes disablePortraitGestureTypes;
|
||||
|
||||
@property (nonatomic, assign) BOOL fullScreenAnimation;
|
||||
|
||||
@property (nonatomic, assign) CGRect contentFullScreenRect;
|
||||
|
||||
@property (nonatomic, weak) UIViewController *viewController;
|
||||
|
||||
- (void)updateContentView:(UIView *)contenView
|
||||
containerView:(UIView *)containerView;
|
||||
|
||||
@end
|
||||
296
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPersentInteractiveTransition.m
generated
Normal file
296
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPersentInteractiveTransition.m
generated
Normal file
@@ -0,0 +1,296 @@
|
||||
//
|
||||
// ZFPersentInteractiveTransition.m
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "ZFPersentInteractiveTransition.h"
|
||||
|
||||
@interface ZFPersentInteractiveTransition () <UIGestureRecognizerDelegate>
|
||||
|
||||
@property (nonatomic, weak) id<UIViewControllerContextTransitioning> transitionContext;
|
||||
@property (nonatomic, strong) UIView *bgView;
|
||||
@property (nonatomic, assign) CGPoint transitionImgViewCenter;
|
||||
@property (nonatomic, strong) UIView *contentView;
|
||||
@property (nonatomic, strong) UIView *containerView;
|
||||
@property (nonatomic, assign) CGFloat scrollViewZoomScale;
|
||||
@property (nonatomic, assign) CGSize scrollViewContentSize;
|
||||
@property (nonatomic, assign) CGPoint scrollViewContentOffset;
|
||||
@property (nonatomic, strong) UIPanGestureRecognizer *panGesture;
|
||||
@property (nonatomic, strong) UITapGestureRecognizer *tapGesture;
|
||||
@property (nonatomic, assign) BOOL isDragging;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ZFPersentInteractiveTransition
|
||||
|
||||
- (void)updateContentView:(UIView *)contenView
|
||||
containerView:(UIView *)containerView {
|
||||
self.contentView = contenView;
|
||||
self.containerView = containerView;
|
||||
}
|
||||
|
||||
- (void)removeGestureToView:(UIView *)view {
|
||||
[view removeGestureRecognizer:self.tapGesture];
|
||||
[view removeGestureRecognizer:self.panGesture];
|
||||
}
|
||||
|
||||
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
|
||||
if ([otherGestureRecognizer.view isKindOfClass:[UICollectionView class]]) {
|
||||
return NO;
|
||||
}
|
||||
if ([otherGestureRecognizer.view isKindOfClass:[UIScrollView class]]) {
|
||||
UIScrollView *scrollView = (UIScrollView *)otherGestureRecognizer.view;
|
||||
if (scrollView.contentOffset.y <= 0 && !scrollView.zooming) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
if ([otherGestureRecognizer isKindOfClass:[UITapGestureRecognizer class]] || [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
|
||||
ZFDisablePortraitGestureTypes type = ZFDisablePortraitGestureTypesNone;
|
||||
if (gestureRecognizer == self.tapGesture) type = ZFDisablePortraitGestureTypesTap;
|
||||
else if (gestureRecognizer == self.panGesture) type = ZFDisablePortraitGestureTypesPan;
|
||||
else return NO;
|
||||
|
||||
switch (type) {
|
||||
case ZFDisablePortraitGestureTypesTap: {
|
||||
if (self.disablePortraitGestureTypes & ZFDisablePortraitGestureTypesTap) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZFDisablePortraitGestureTypesPan: {
|
||||
if (self.disablePortraitGestureTypes & ZFDisablePortraitGestureTypesPan) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)tapGestureAction {
|
||||
[self.viewController dismissViewControllerAnimated:self.fullScreenAnimation completion:nil];
|
||||
}
|
||||
|
||||
- (void)gestureRecognizeDidUpdate:(UIPanGestureRecognizer *)gestureRecognizer {
|
||||
CGFloat scale = 0;
|
||||
CGPoint translation = [gestureRecognizer translationInView:gestureRecognizer.view];
|
||||
scale = translation.y / ((gestureRecognizer.view.frame.size.height - 50) / 2);
|
||||
|
||||
if (scale > 1.f) {
|
||||
scale = 1.f;
|
||||
}
|
||||
switch (gestureRecognizer.state) {
|
||||
case UIGestureRecognizerStateBegan: {
|
||||
if (scale < 0) return;
|
||||
self.interation = YES;
|
||||
[self.viewController dismissViewControllerAnimated:self.fullScreenAnimation completion:nil];
|
||||
}
|
||||
break;
|
||||
case UIGestureRecognizerStateChanged: {
|
||||
if (self.interation) {
|
||||
if (scale < 0.f) {
|
||||
scale = 0.f;
|
||||
}
|
||||
CGFloat imageViewScale = 1 - scale * 0.5;
|
||||
if (imageViewScale < 0.4) {
|
||||
imageViewScale = 0.4;
|
||||
}
|
||||
self.contentView.center = CGPointMake(self.transitionImgViewCenter.x + translation.x, self.transitionImgViewCenter.y + translation.y);
|
||||
self.contentView.transform = CGAffineTransformMakeScale(imageViewScale, imageViewScale);
|
||||
[self updateInterPercent:imageViewScale];
|
||||
[self updateInteractiveTransition:scale];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UIGestureRecognizerStateEnded: {
|
||||
if (self.interation) {
|
||||
if (scale < 0.f) {
|
||||
scale = 0.f;
|
||||
}
|
||||
self.interation = NO;
|
||||
if (scale < 0.15f) {
|
||||
[self cancelInteractiveTransition];
|
||||
[self interPercentCancel];
|
||||
} else {
|
||||
[self finishInteractiveTransition];
|
||||
[self interPercentFinish];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
if (self.interation) {
|
||||
self.interation = NO;
|
||||
[self cancelInteractiveTransition];
|
||||
[self interPercentCancel];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)beginInterPercent {
|
||||
id<UIViewControllerContextTransitioning> transitionContext = self.transitionContext;
|
||||
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
|
||||
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
|
||||
if ([toVC isKindOfClass:[UINavigationController class]]) {
|
||||
UINavigationController *nav = (UINavigationController *)toVC;
|
||||
toVC = nav.viewControllers.lastObject;
|
||||
} else if ([toVC isKindOfClass:[UITabBarController class]]) {
|
||||
UITabBarController *tabBar = (UITabBarController *)toVC;
|
||||
if ([tabBar.selectedViewController isKindOfClass:[UINavigationController class]]) {
|
||||
UINavigationController *nav = (UINavigationController *)tabBar.selectedViewController;
|
||||
toVC = nav.viewControllers.lastObject;
|
||||
} else {
|
||||
toVC = tabBar.selectedViewController;
|
||||
}
|
||||
}
|
||||
|
||||
UIView *containerView = [transitionContext containerView];
|
||||
CGRect tempImageViewFrame = [fromVC.view convertRect:self.contentView.frame toView:toVC.view];
|
||||
|
||||
self.bgView = [[UIView alloc] initWithFrame:containerView.bounds];
|
||||
self.contentView.frame = tempImageViewFrame;
|
||||
self.transitionImgViewCenter = self.contentView.center;
|
||||
|
||||
[containerView addSubview:self.bgView];
|
||||
[containerView addSubview:self.contentView];
|
||||
[containerView addSubview:fromVC.view];
|
||||
|
||||
self.bgView.backgroundColor = [UIColor blackColor];
|
||||
fromVC.view.backgroundColor = [UIColor clearColor];
|
||||
}
|
||||
|
||||
- (void)updateInterPercent:(CGFloat)scale {
|
||||
UIViewController *fromVC = [self.transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
|
||||
fromVC.view.alpha = scale;
|
||||
self.bgView.alpha = scale;
|
||||
}
|
||||
|
||||
- (void)interPercentCancel {
|
||||
id<UIViewControllerContextTransitioning> transitionContext = self.transitionContext;
|
||||
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
|
||||
[UIView animateWithDuration:0.2f animations:^{
|
||||
fromVC.view.alpha = 1;
|
||||
self.contentView.transform = CGAffineTransformIdentity;
|
||||
self.contentView.center = self.transitionImgViewCenter;
|
||||
self.bgView.alpha = 1;
|
||||
} completion:^(BOOL finished) {
|
||||
fromVC.view.backgroundColor = [UIColor blackColor];
|
||||
self.contentView.layer.anchorPoint = CGPointMake(0.5f, 0.5f);
|
||||
self.contentView.frame = self.contentFullScreenRect;
|
||||
if (self.scrollViewContentOffset.y < 0) {
|
||||
self.scrollViewContentOffset = CGPointMake(self.scrollViewContentOffset.x, 0);
|
||||
}
|
||||
[self.viewController.view addSubview:self.contentView];
|
||||
[self.bgView removeFromSuperview];
|
||||
self.bgView = nil;
|
||||
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)interPercentFinish {
|
||||
id<UIViewControllerContextTransitioning> transitionContext = self.transitionContext;
|
||||
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
|
||||
UIViewController *toVC = [self.transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
|
||||
if ([toVC isKindOfClass:[UINavigationController class]]) {
|
||||
UINavigationController *nav = (UINavigationController *)toVC;
|
||||
toVC = nav.viewControllers.lastObject;
|
||||
} else if ([toVC isKindOfClass:[UITabBarController class]]) {
|
||||
UITabBarController *tabBar = (UITabBarController *)toVC;
|
||||
if ([tabBar.selectedViewController isKindOfClass:[UINavigationController class]]) {
|
||||
UINavigationController *nav = (UINavigationController *)tabBar.selectedViewController;
|
||||
toVC = nav.viewControllers.lastObject;
|
||||
} else {
|
||||
toVC = tabBar.selectedViewController;
|
||||
}
|
||||
}
|
||||
CGRect tempImageViewFrame = self.contentView.frame;
|
||||
self.contentView.layer.anchorPoint = CGPointMake(0.5, 0.5);
|
||||
self.contentView.transform = CGAffineTransformIdentity;
|
||||
self.contentView.frame = tempImageViewFrame;
|
||||
|
||||
CGRect toRect = [self.containerView convertRect:self.containerView.bounds toView:self.containerView.window];
|
||||
[self.delagate zf_orientationWillChange:NO];
|
||||
[UIView animateWithDuration:0.3f animations:^{
|
||||
self.contentView.frame = toRect;
|
||||
fromVC.view.alpha = 0;
|
||||
self.bgView.alpha = 0;
|
||||
toVC.navigationController.navigationBar.alpha = 1;
|
||||
[self.contentView layoutIfNeeded];
|
||||
} completion:^(BOOL finished) {
|
||||
[self.containerView addSubview:self.contentView];
|
||||
self.contentView.frame = self.containerView.bounds;
|
||||
[self.contentView layoutIfNeeded];
|
||||
[self.bgView removeFromSuperview];
|
||||
fromVC.view.backgroundColor = [UIColor blackColor];
|
||||
[self.delagate zf_orientationDidChanged:NO];
|
||||
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)startInteractiveTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
|
||||
self.transitionContext = transitionContext;
|
||||
[self beginInterPercent];
|
||||
}
|
||||
|
||||
- (void)setInteration:(BOOL)interation {
|
||||
_interation = interation;
|
||||
if ([self.delagate respondsToSelector:@selector(zf_interationState:)]) {
|
||||
[self.delagate zf_interationState:interation];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setViewController:(UIViewController *)viewController {
|
||||
_viewController = viewController;
|
||||
[self removeGestureToView:viewController.view];
|
||||
[viewController.view addGestureRecognizer:self.panGesture];
|
||||
[viewController.view addGestureRecognizer:self.tapGesture];
|
||||
}
|
||||
|
||||
#pragma mark - getter
|
||||
|
||||
- (UIPanGestureRecognizer *)panGesture {
|
||||
if (!_panGesture) {
|
||||
_panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(gestureRecognizeDidUpdate:)];
|
||||
_panGesture.delegate = self;
|
||||
}
|
||||
return _panGesture;
|
||||
}
|
||||
|
||||
- (UITapGestureRecognizer *)tapGesture {
|
||||
if (!_tapGesture) {
|
||||
_tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureAction)];
|
||||
_tapGesture.delegate = self;
|
||||
}
|
||||
return _tapGesture;
|
||||
}
|
||||
|
||||
@end
|
||||
38
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayer.h
generated
Normal file
38
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayer.h
generated
Normal file
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// ZFPlayer.h
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
//! Project version number for ZFPlayer.
|
||||
FOUNDATION_EXPORT double ZFPlayerVersionNumber;
|
||||
|
||||
//! Project version string for ZFPlayer.
|
||||
FOUNDATION_EXPORT const unsigned char ZFPlayerVersionString[];
|
||||
|
||||
#import "ZFPlayerController.h"
|
||||
#import "ZFPlayerMediaControl.h"
|
||||
#import "ZFKVOController.h"
|
||||
#import "UIScrollView+ZFPlayer.h"
|
||||
#import "ZFPlayerLogManager.h"
|
||||
#import "ZFPlayerConst.h"
|
||||
130
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerConst.h
generated
Normal file
130
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerConst.h
generated
Normal file
@@ -0,0 +1,130 @@
|
||||
//
|
||||
// ZFPlayerConst.h
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
typedef NS_ENUM(NSUInteger, ZFPlayerPlaybackState) {
|
||||
ZFPlayerPlayStateUnknown,
|
||||
ZFPlayerPlayStatePlaying,
|
||||
ZFPlayerPlayStatePaused,
|
||||
ZFPlayerPlayStatePlayFailed,
|
||||
ZFPlayerPlayStatePlayStopped
|
||||
};
|
||||
|
||||
typedef NS_OPTIONS(NSUInteger, ZFPlayerLoadState) {
|
||||
ZFPlayerLoadStateUnknown = 0,
|
||||
ZFPlayerLoadStatePrepare = 1 << 0,
|
||||
ZFPlayerLoadStatePlayable = 1 << 1,
|
||||
ZFPlayerLoadStatePlaythroughOK = 1 << 2, // Playback will be automatically started.
|
||||
ZFPlayerLoadStateStalled = 1 << 3, // Playback will be automatically paused in this state, if started.
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, ZFPlayerScalingMode) {
|
||||
ZFPlayerScalingModeNone, // No scaling.
|
||||
ZFPlayerScalingModeAspectFit, // Uniform scale until one dimension fits.
|
||||
ZFPlayerScalingModeAspectFill, // Uniform scale until the movie fills the visible bounds. One dimension may have clipped contents.
|
||||
ZFPlayerScalingModeFill // Non-uniform scale. Both render dimensions will exactly match the visible bounds.
|
||||
};
|
||||
|
||||
/**
|
||||
Synthsize a weak or strong reference.
|
||||
|
||||
Example:
|
||||
@zf_weakify(self)
|
||||
[self doSomething^{
|
||||
@zf_strongify(self)
|
||||
if (!self) return;
|
||||
...
|
||||
}];
|
||||
|
||||
*/
|
||||
#ifndef weakify
|
||||
#if DEBUG
|
||||
#if __has_feature(objc_arc)
|
||||
#define zf_weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;
|
||||
#else
|
||||
#define zf_weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;
|
||||
#endif
|
||||
#else
|
||||
#if __has_feature(objc_arc)
|
||||
#define zf_weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;
|
||||
#else
|
||||
#define zf_weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef strongify
|
||||
#if DEBUG
|
||||
#if __has_feature(objc_arc)
|
||||
#define zf_strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;
|
||||
#else
|
||||
#define zf_strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;
|
||||
#endif
|
||||
#else
|
||||
#if __has_feature(objc_arc)
|
||||
#define zf_strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;
|
||||
#else
|
||||
#define zf_strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Screen width
|
||||
#define ZFPlayerScreenWidth [[UIScreen mainScreen] bounds].size.width
|
||||
// Screen height
|
||||
#define ZFPlayerScreenHeight [[UIScreen mainScreen] bounds].size.height
|
||||
|
||||
|
||||
// deprecated
|
||||
#ifndef weakify
|
||||
#if DEBUG
|
||||
#if __has_feature(objc_arc)
|
||||
#define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;
|
||||
#else
|
||||
#define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;
|
||||
#endif
|
||||
#else
|
||||
#if __has_feature(objc_arc)
|
||||
#define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;
|
||||
#else
|
||||
#define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef strongify
|
||||
#if DEBUG
|
||||
#if __has_feature(objc_arc)
|
||||
#define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;
|
||||
#else
|
||||
#define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;
|
||||
#endif
|
||||
#else
|
||||
#if __has_feature(objc_arc)
|
||||
#define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;
|
||||
#else
|
||||
#define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
608
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerController.h
generated
Normal file
608
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerController.h
generated
Normal file
@@ -0,0 +1,608 @@
|
||||
//
|
||||
// ZFPlayerController.h
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "ZFPlayerMediaPlayback.h"
|
||||
#import "ZFOrientationObserver.h"
|
||||
#import "ZFPlayerMediaControl.h"
|
||||
#import "ZFPlayerGestureControl.h"
|
||||
#import "ZFPlayerNotification.h"
|
||||
#import "ZFFloatView.h"
|
||||
#import "UIScrollView+ZFPlayer.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface ZFPlayerController : NSObject
|
||||
|
||||
/// The video contrainerView in normal model.
|
||||
@property (nonatomic, strong) UIView *containerView;
|
||||
|
||||
/// The currentPlayerManager must conform `ZFPlayerMediaPlayback` protocol.
|
||||
@property (nonatomic, strong) id<ZFPlayerMediaPlayback> currentPlayerManager;
|
||||
|
||||
/// The custom controlView must conform `ZFPlayerMediaControl` protocol.
|
||||
@property (nonatomic, strong) UIView<ZFPlayerMediaControl> *controlView;
|
||||
|
||||
/// The notification manager class.
|
||||
@property (nonatomic, strong, readonly) ZFPlayerNotification *notification;
|
||||
|
||||
/// The container view type.
|
||||
@property (nonatomic, assign, readonly) ZFPlayerContainerType containerType;
|
||||
|
||||
/// The player's small container view.
|
||||
@property (nonatomic, strong, readonly) ZFFloatView *smallFloatView;
|
||||
|
||||
/// Whether the small window is displayed.
|
||||
@property (nonatomic, assign, readonly) BOOL isSmallFloatViewShow;
|
||||
|
||||
/*!
|
||||
@method playerWithPlayerManager:containerView:
|
||||
@abstract Create an ZFPlayerController that plays a single audiovisual item.
|
||||
@param playerManager must conform `ZFPlayerMediaPlayback` protocol.
|
||||
@param containerView to see the video frames must set the contrainerView.
|
||||
@result An instance of ZFPlayerController.
|
||||
*/
|
||||
+ (instancetype)playerWithPlayerManager:(id<ZFPlayerMediaPlayback>)playerManager containerView:(UIView *)containerView;
|
||||
|
||||
/*!
|
||||
@method initWithPlayerManager:containerView:
|
||||
@abstract Create an ZFPlayerController that plays a single audiovisual item.
|
||||
@param playerManager must conform `ZFPlayerMediaPlayback` protocol.
|
||||
@param containerView to see the video frames must set the contrainerView.
|
||||
@result An instance of ZFPlayerController.
|
||||
*/
|
||||
- (instancetype)initWithPlayerManager:(id<ZFPlayerMediaPlayback>)playerManager containerView:(UIView *)containerView;
|
||||
|
||||
/*!
|
||||
@method playerWithScrollView:playerManager:containerViewTag:
|
||||
@abstract Create an ZFPlayerController that plays a single audiovisual item. Use in `UITableView` or `UICollectionView`.
|
||||
@param scrollView is `tableView` or `collectionView`.
|
||||
@param playerManager must conform `ZFPlayerMediaPlayback` protocol.
|
||||
@param containerViewTag to see the video at scrollView must set the contrainerViewTag.
|
||||
@result An instance of ZFPlayerController.
|
||||
*/
|
||||
+ (instancetype)playerWithScrollView:(UIScrollView *)scrollView playerManager:(id<ZFPlayerMediaPlayback>)playerManager containerViewTag:(NSInteger)containerViewTag;
|
||||
|
||||
/*!
|
||||
@method initWithScrollView:playerManager:containerViewTag:
|
||||
@abstract Create an ZFPlayerController that plays a single audiovisual item. Use in `UITableView` or `UICollectionView`.
|
||||
@param scrollView is `tableView` or `collectionView`.
|
||||
@param playerManager must conform `ZFPlayerMediaPlayback` protocol.
|
||||
@param containerViewTag to see the video at scrollView must set the contrainerViewTag.
|
||||
@result An instance of ZFPlayerController.
|
||||
*/
|
||||
- (instancetype)initWithScrollView:(UIScrollView *)scrollView playerManager:(id<ZFPlayerMediaPlayback>)playerManager containerViewTag:(NSInteger)containerViewTag;
|
||||
|
||||
/*!
|
||||
@method playerWithScrollView:playerManager:containerView:
|
||||
@abstract Create an ZFPlayerController that plays a single audiovisual item. Use in `UIScrollView`.
|
||||
@param playerManager must conform `ZFPlayerMediaPlayback` protocol.
|
||||
@param containerView to see the video at the scrollView.
|
||||
@result An instance of ZFPlayerController.
|
||||
*/
|
||||
+ (instancetype)playerWithScrollView:(UIScrollView *)scrollView playerManager:(id<ZFPlayerMediaPlayback>)playerManager containerView:(UIView *)containerView;
|
||||
|
||||
/*!
|
||||
@method initWithScrollView:playerManager:containerView:
|
||||
@abstract Create an ZFPlayerController that plays a single audiovisual item. Use in `UIScrollView`.
|
||||
@param playerManager must conform `ZFPlayerMediaPlayback` protocol.
|
||||
@param containerView to see the video at the scrollView.
|
||||
@result An instance of ZFPlayerController.
|
||||
*/
|
||||
- (instancetype)initWithScrollView:(UIScrollView *)scrollView playerManager:(id<ZFPlayerMediaPlayback>)playerManager containerView:(UIView *)containerView;
|
||||
|
||||
@end
|
||||
|
||||
@interface ZFPlayerController (ZFPlayerTimeControl)
|
||||
|
||||
/// The player current play time.
|
||||
@property (nonatomic, readonly) NSTimeInterval currentTime;
|
||||
|
||||
/// The player total time.
|
||||
@property (nonatomic, readonly) NSTimeInterval totalTime;
|
||||
|
||||
/// The player buffer time.
|
||||
@property (nonatomic, readonly) NSTimeInterval bufferTime;
|
||||
|
||||
/// The player progress, 0...1
|
||||
@property (nonatomic, readonly) float progress;
|
||||
|
||||
/// The player bufferProgress, 0...1
|
||||
@property (nonatomic, readonly) float bufferProgress;
|
||||
|
||||
/**
|
||||
Use this method to seek to a specified time for the current player and to be notified when the seek operation is complete.
|
||||
|
||||
@param time seek time.
|
||||
@param completionHandler completion handler.
|
||||
*/
|
||||
- (void)seekToTime:(NSTimeInterval)time completionHandler:(void (^ __nullable)(BOOL finished))completionHandler;
|
||||
|
||||
@end
|
||||
|
||||
@interface ZFPlayerController (ZFPlayerPlaybackControl)
|
||||
|
||||
/// Resume playback record.default is NO.
|
||||
/// Memory storage playback records.
|
||||
@property (nonatomic, assign) BOOL resumePlayRecord;
|
||||
|
||||
/// 0...1.0
|
||||
/// Only affects audio volume for the device instance and not for the player.
|
||||
/// You can change device volume or player volume as needed,change the player volume you can conform the `ZFPlayerMediaPlayback` protocol.
|
||||
@property (nonatomic) float volume;
|
||||
|
||||
/// The device muted.
|
||||
/// Only affects audio muting for the device instance and not for the player.
|
||||
/// You can change device mute or player mute as needed,change the player mute you can conform the `ZFPlayerMediaPlayback` protocol.
|
||||
@property (nonatomic, getter=isMuted) BOOL muted;
|
||||
|
||||
// 0...1.0, where 1.0 is maximum brightness. Only supported by main screen.
|
||||
@property (nonatomic) float brightness;
|
||||
|
||||
/// The play asset URL.
|
||||
@property (nonatomic) NSURL *assetURL;
|
||||
|
||||
/// If tableView or collectionView has only one section , use `assetURLs`.
|
||||
/// If tableView or collectionView has more sections , use `sectionAssetURLs`.
|
||||
/// Set this you can use `playTheNext` `playThePrevious` `playTheIndex:` method.
|
||||
@property (nonatomic, copy, nullable) NSArray <NSURL *>*assetURLs;
|
||||
|
||||
/// The currently playing index,limited to one-dimensional arrays.
|
||||
@property (nonatomic) NSInteger currentPlayIndex;
|
||||
|
||||
/// is the last asset URL in `assetURLs`.
|
||||
@property (nonatomic, readonly) BOOL isLastAssetURL;
|
||||
|
||||
/// is the first asset URL in `assetURLs`.
|
||||
@property (nonatomic, readonly) BOOL isFirstAssetURL;
|
||||
|
||||
/// If Yes, player will be called pause method When Received `UIApplicationWillResignActiveNotification` notification.
|
||||
/// default is YES.
|
||||
@property (nonatomic) BOOL pauseWhenAppResignActive;
|
||||
|
||||
/// When the player is playing, it is paused by some event,not by user click to pause.
|
||||
/// For example, when the player is playing, application goes into the background or pushed to another viewController
|
||||
@property (nonatomic, getter=isPauseByEvent) BOOL pauseByEvent;
|
||||
|
||||
/// The current player controller is disappear, not dealloc
|
||||
@property (nonatomic, getter=isViewControllerDisappear) BOOL viewControllerDisappear;
|
||||
|
||||
/// You can custom the AVAudioSession,
|
||||
/// default is NO.
|
||||
@property (nonatomic, assign) BOOL customAudioSession;
|
||||
|
||||
/// The block invoked when the player is Prepare to play.
|
||||
@property (nonatomic, copy, nullable) void(^playerPrepareToPlay)(id<ZFPlayerMediaPlayback> asset, NSURL *assetURL);
|
||||
|
||||
/// The block invoked when the player is Ready to play.
|
||||
@property (nonatomic, copy, nullable) void(^playerReadyToPlay)(id<ZFPlayerMediaPlayback> asset, NSURL *assetURL);
|
||||
|
||||
/// The block invoked when the player play progress changed.
|
||||
@property (nonatomic, copy, nullable) void(^playerPlayTimeChanged)(id<ZFPlayerMediaPlayback> asset, NSTimeInterval currentTime, NSTimeInterval duration);
|
||||
|
||||
/// The block invoked when the player play buffer changed.
|
||||
@property (nonatomic, copy, nullable) void(^playerBufferTimeChanged)(id<ZFPlayerMediaPlayback> asset, NSTimeInterval bufferTime);
|
||||
|
||||
/// The block invoked when the player playback state changed.
|
||||
@property (nonatomic, copy, nullable) void(^playerPlayStateChanged)(id<ZFPlayerMediaPlayback> asset, ZFPlayerPlaybackState playState);
|
||||
|
||||
/// The block invoked when the player load state changed.
|
||||
@property (nonatomic, copy, nullable) void(^playerLoadStateChanged)(id<ZFPlayerMediaPlayback> asset, ZFPlayerLoadState loadState);
|
||||
|
||||
/// The block invoked when the player play failed.
|
||||
@property (nonatomic, copy, nullable) void(^playerPlayFailed)(id<ZFPlayerMediaPlayback> asset, id error);
|
||||
|
||||
/// The block invoked when the player play end.
|
||||
@property (nonatomic, copy, nullable) void(^playerDidToEnd)(id<ZFPlayerMediaPlayback> asset);
|
||||
|
||||
// The block invoked when video size changed.
|
||||
@property (nonatomic, copy, nullable) void(^presentationSizeChanged)(id<ZFPlayerMediaPlayback> asset, CGSize size);
|
||||
|
||||
/**
|
||||
Play the next url ,while the `assetURLs` is not NULL.
|
||||
*/
|
||||
- (void)playTheNext;
|
||||
|
||||
/**
|
||||
Play the previous url ,while the `assetURLs` is not NULL.
|
||||
*/
|
||||
- (void)playThePrevious;
|
||||
|
||||
/**
|
||||
Play the index of url ,while the `assetURLs` is not NULL.
|
||||
|
||||
@param index play the index.
|
||||
*/
|
||||
- (void)playTheIndex:(NSInteger)index;
|
||||
|
||||
/**
|
||||
Player stop and playerView remove from super view,remove other notification.
|
||||
*/
|
||||
- (void)stop;
|
||||
|
||||
/*!
|
||||
@method replaceCurrentPlayerManager:
|
||||
@abstract Replaces the player's current playeranager with the specified player item.
|
||||
@param manager must conform `ZFPlayerMediaPlayback` protocol
|
||||
@discussion The playerManager that will become the player's current playeranager.
|
||||
*/
|
||||
- (void)replaceCurrentPlayerManager:(id<ZFPlayerMediaPlayback>)manager;
|
||||
|
||||
/**
|
||||
Add video to cell.
|
||||
*/
|
||||
- (void)addPlayerViewToCell;
|
||||
|
||||
/**
|
||||
Add video to container view.
|
||||
*/
|
||||
- (void)addPlayerViewToContainerView:(UIView *)containerView;
|
||||
|
||||
/**
|
||||
Add to small float view.
|
||||
*/
|
||||
- (void)addPlayerViewToSmallFloatView;
|
||||
|
||||
/**
|
||||
Stop the current playing video and remove the playerView.
|
||||
*/
|
||||
- (void)stopCurrentPlayingView;
|
||||
|
||||
/**
|
||||
stop the current playing video on cell.
|
||||
*/
|
||||
- (void)stopCurrentPlayingCell;
|
||||
|
||||
@end
|
||||
|
||||
@interface ZFPlayerController (ZFPlayerOrientationRotation)
|
||||
|
||||
@property (nonatomic, readonly) ZFOrientationObserver *orientationObserver;
|
||||
|
||||
/// Whether automatic screen rotation is supported.
|
||||
/// The value is NO.
|
||||
/// This property is used for the return value of UIViewController `shouldAutorotate` method.
|
||||
@property (nonatomic, readonly) BOOL shouldAutorotate;
|
||||
|
||||
/// Whether allow the video orientation rotate.
|
||||
/// default is YES.
|
||||
@property (nonatomic) BOOL allowOrentitaionRotation;
|
||||
|
||||
/// When ZFFullScreenMode is ZFFullScreenModeLandscape the orientation is LandscapeLeft or LandscapeRight, this value is YES.
|
||||
/// When ZFFullScreenMode is ZFFullScreenModePortrait, while the player fullSceen this value is YES.
|
||||
@property (nonatomic, readonly) BOOL isFullScreen;
|
||||
|
||||
/// when call the `stop` method, exit the fullScreen model, default is YES.
|
||||
@property (nonatomic, assign) BOOL exitFullScreenWhenStop;
|
||||
|
||||
/// Lock the screen orientation.
|
||||
@property (nonatomic, getter=isLockedScreen) BOOL lockedScreen;
|
||||
|
||||
/// The current orientation of the player.
|
||||
/// Default is UIInterfaceOrientationPortrait.
|
||||
@property (nonatomic, readonly) UIInterfaceOrientation currentOrientation;
|
||||
|
||||
/// The block invoked When player will rotate.
|
||||
@property (nonatomic, copy, nullable) void(^orientationWillChange)(ZFPlayerController *player, BOOL isFullScreen);
|
||||
|
||||
/// The block invoked when player rotated.
|
||||
@property (nonatomic, copy, nullable) void(^orientationDidChanged)(ZFPlayerController *player, BOOL isFullScreen);
|
||||
|
||||
/// default is UIStatusBarStyleLightContent.
|
||||
@property (nonatomic, assign) UIStatusBarStyle fullScreenStatusBarStyle;
|
||||
|
||||
/// defalut is UIStatusBarAnimationSlide.
|
||||
@property (nonatomic, assign) UIStatusBarAnimation fullScreenStatusBarAnimation;
|
||||
|
||||
/// The fullscreen statusbar hidden.
|
||||
@property (nonatomic, getter=isStatusBarHidden) BOOL statusBarHidden;
|
||||
|
||||
/**
|
||||
Add the device orientation observer.
|
||||
*/
|
||||
- (void)addDeviceOrientationObserver;
|
||||
|
||||
/**
|
||||
Remove the device orientation observer.
|
||||
*/
|
||||
- (void)removeDeviceOrientationObserver;
|
||||
|
||||
/**
|
||||
Enter the fullScreen while the ZFFullScreenMode is ZFFullScreenModeLandscape.
|
||||
|
||||
@param orientation is UIInterfaceOrientation.
|
||||
@param animated is animated.
|
||||
*/
|
||||
- (void)rotateToOrientation:(UIInterfaceOrientation)orientation animated:(BOOL)animated;
|
||||
|
||||
/**
|
||||
Enter the fullScreen while the ZFFullScreenMode is ZFFullScreenModeLandscape.
|
||||
|
||||
@param orientation is UIInterfaceOrientation.
|
||||
@param animated is animated.
|
||||
@param completion rotating completed callback.
|
||||
*/
|
||||
- (void)rotateToOrientation:(UIInterfaceOrientation)orientation animated:(BOOL)animated completion:(void(^ __nullable)(void))completion;
|
||||
|
||||
/**
|
||||
Enter the fullScreen while the ZFFullScreenMode is ZFFullScreenModePortrait.
|
||||
|
||||
@param fullScreen is fullscreen.
|
||||
@param animated is animated.
|
||||
@param completion rotating completed callback.
|
||||
*/
|
||||
- (void)enterPortraitFullScreen:(BOOL)fullScreen animated:(BOOL)animated completion:(void(^ __nullable)(void))completion;
|
||||
|
||||
/**
|
||||
Enter the fullScreen while the ZFFullScreenMode is ZFFullScreenModePortrait.
|
||||
|
||||
@param fullScreen is fullscreen.
|
||||
@param animated is animated.
|
||||
*/
|
||||
- (void)enterPortraitFullScreen:(BOOL)fullScreen animated:(BOOL)animated;
|
||||
|
||||
/**
|
||||
FullScreen mode is determined by ZFFullScreenMode.
|
||||
|
||||
@param fullScreen is fullscreen.
|
||||
@param animated is animated.
|
||||
@param completion rotating completed callback.
|
||||
*/
|
||||
- (void)enterFullScreen:(BOOL)fullScreen animated:(BOOL)animated completion:(void(^ __nullable)(void))completion;
|
||||
|
||||
/**
|
||||
FullScreen mode is determined by ZFFullScreenMode.
|
||||
|
||||
@param fullScreen is fullscreen.
|
||||
@param animated is animated.
|
||||
*/
|
||||
- (void)enterFullScreen:(BOOL)fullScreen animated:(BOOL)animated;
|
||||
|
||||
@end
|
||||
|
||||
@interface ZFPlayerController (ZFPlayerViewGesture)
|
||||
|
||||
/// An instance of ZFPlayerGestureControl.
|
||||
@property (nonatomic, readonly) ZFPlayerGestureControl *gestureControl;
|
||||
|
||||
/// The gesture types that the player not support.
|
||||
@property (nonatomic, assign) ZFPlayerDisableGestureTypes disableGestureTypes;
|
||||
|
||||
/// The pan gesture moving direction that the player not support.
|
||||
@property (nonatomic) ZFPlayerDisablePanMovingDirection disablePanMovingDirection;
|
||||
|
||||
@end
|
||||
|
||||
@interface ZFPlayerController (ZFPlayerScrollView)
|
||||
|
||||
/// The scroll view is `tableView` or `collectionView`.
|
||||
@property (nonatomic, readonly, nullable) UIScrollView *scrollView;
|
||||
|
||||
/// The scrollView player should auto player, default is YES.
|
||||
@property (nonatomic) BOOL shouldAutoPlay;
|
||||
|
||||
/// WWAN network auto play, only support in scrollView mode when the `shouldAutoPlay` is YES, default is NO.
|
||||
@property (nonatomic, getter=isWWANAutoPlay) BOOL WWANAutoPlay;
|
||||
|
||||
/// The indexPath is playing.
|
||||
@property (nonatomic, readonly, nullable) NSIndexPath *playingIndexPath;
|
||||
|
||||
/// The indexPath should be play while scrolling.
|
||||
@property (nonatomic, readonly, nullable) NSIndexPath *shouldPlayIndexPath;
|
||||
|
||||
/// The view tag that the player display in scrollView.
|
||||
@property (nonatomic, readonly) NSInteger containerViewTag;
|
||||
|
||||
/// The current playing cell stop playing when the cell has out off the screen,defalut is YES.
|
||||
@property (nonatomic) BOOL stopWhileNotVisible;
|
||||
|
||||
/**
|
||||
The current player scroll slides off the screen percent.
|
||||
the property used when the `stopWhileNotVisible` is YES, stop the current playing player.
|
||||
the property used when the `stopWhileNotVisible` is NO, the current playing player add to small container view.
|
||||
The range is 0.0~1.0, defalut is 0.5.
|
||||
0.0 is the player will disappear.
|
||||
1.0 is the player did disappear.
|
||||
*/
|
||||
@property (nonatomic) CGFloat playerDisapperaPercent;
|
||||
|
||||
/**
|
||||
The current player scroll to the screen percent to play the video.
|
||||
The range is 0.0~1.0, defalut is 0.0.
|
||||
0.0 is the player will appear.
|
||||
1.0 is the player did appear.
|
||||
*/
|
||||
@property (nonatomic) CGFloat playerApperaPercent;
|
||||
|
||||
/// If tableView or collectionView has more sections, use `sectionAssetURLs`.
|
||||
@property (nonatomic, copy, nullable) NSArray <NSArray <NSURL *>*>*sectionAssetURLs;
|
||||
|
||||
/// The block invoked When the player appearing.
|
||||
@property (nonatomic, copy, nullable) void(^zf_playerAppearingInScrollView)(NSIndexPath *indexPath, CGFloat playerApperaPercent);
|
||||
|
||||
/// The block invoked When the player disappearing.
|
||||
@property (nonatomic, copy, nullable) void(^zf_playerDisappearingInScrollView)(NSIndexPath *indexPath, CGFloat playerDisapperaPercent);
|
||||
|
||||
/// The block invoked When the player will appeared.
|
||||
@property (nonatomic, copy, nullable) void(^zf_playerWillAppearInScrollView)(NSIndexPath *indexPath);
|
||||
|
||||
/// The block invoked When the player did appeared.
|
||||
@property (nonatomic, copy, nullable) void(^zf_playerDidAppearInScrollView)(NSIndexPath *indexPath);
|
||||
|
||||
/// The block invoked When the player will disappear.
|
||||
@property (nonatomic, copy, nullable) void(^zf_playerWillDisappearInScrollView)(NSIndexPath *indexPath);
|
||||
|
||||
/// The block invoked When the player did disappeared.
|
||||
@property (nonatomic, copy, nullable) void(^zf_playerDidDisappearInScrollView)(NSIndexPath *indexPath);
|
||||
|
||||
/// The block invoked When the player should play.
|
||||
@property (nonatomic, copy, nullable) void(^zf_playerShouldPlayInScrollView)(NSIndexPath *indexPath);
|
||||
|
||||
/// The block invoked When the player did stop scroll.
|
||||
@property (nonatomic, copy, nullable) void(^zf_scrollViewDidEndScrollingCallback)(NSIndexPath *indexPath);
|
||||
|
||||
/// Filter the cell that should be played when the scroll is stopped (to play when the scroll is stopped).
|
||||
- (void)zf_filterShouldPlayCellWhileScrolled:(void (^ __nullable)(NSIndexPath *indexPath))handler;
|
||||
|
||||
/// Filter the cell that should be played while scrolling (you can use this to filter the highlighted cell).
|
||||
- (void)zf_filterShouldPlayCellWhileScrolling:(void (^ __nullable)(NSIndexPath *indexPath))handler;
|
||||
|
||||
/**
|
||||
Play the indexPath of url without scroll postion, while the `assetURLs` or `sectionAssetURLs` is not NULL.
|
||||
|
||||
@param indexPath Play the indexPath of url.
|
||||
*/
|
||||
- (void)playTheIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
/**
|
||||
Play the indexPath of url, while the `assetURLs` or `sectionAssetURLs` is not NULL.
|
||||
|
||||
@param indexPath Play the indexPath of url.
|
||||
@param scrollPosition scroll position.
|
||||
@param animated scroll animation.
|
||||
*/
|
||||
- (void)playTheIndexPath:(NSIndexPath *)indexPath
|
||||
scrollPosition:(ZFPlayerScrollViewScrollPosition)scrollPosition
|
||||
animated:(BOOL)animated;
|
||||
|
||||
/**
|
||||
Play the indexPath of url with scroll postion, while the `assetURLs` or `sectionAssetURLs` is not NULL.
|
||||
|
||||
@param indexPath Play the indexPath of url.
|
||||
@param scrollPosition scroll position.
|
||||
@param animated scroll animation.
|
||||
@param completionHandler Scroll completion callback.
|
||||
*/
|
||||
- (void)playTheIndexPath:(NSIndexPath *)indexPath
|
||||
scrollPosition:(ZFPlayerScrollViewScrollPosition)scrollPosition
|
||||
animated:(BOOL)animated
|
||||
completionHandler:(void (^ __nullable)(void))completionHandler;
|
||||
|
||||
|
||||
/**
|
||||
Play the indexPath of url with scroll postion.
|
||||
|
||||
@param indexPath Play the indexPath of url
|
||||
@param assetURL The player URL.
|
||||
*/
|
||||
- (void)playTheIndexPath:(NSIndexPath *)indexPath assetURL:(NSURL *)assetURL;
|
||||
|
||||
|
||||
/**
|
||||
Play the indexPath of url with scroll postion.
|
||||
|
||||
@param indexPath Play the indexPath of url
|
||||
@param assetURL The player URL.
|
||||
@param scrollPosition scroll position.
|
||||
@param animated scroll animation.
|
||||
*/
|
||||
- (void)playTheIndexPath:(NSIndexPath *)indexPath
|
||||
assetURL:(NSURL *)assetURL
|
||||
scrollPosition:(ZFPlayerScrollViewScrollPosition)scrollPosition
|
||||
animated:(BOOL)animated;
|
||||
|
||||
/**
|
||||
Play the indexPath of url with scroll postion.
|
||||
|
||||
@param indexPath Play the indexPath of url
|
||||
@param assetURL The player URL.
|
||||
@param scrollPosition scroll position.
|
||||
@param animated scroll animation.
|
||||
@param completionHandler Scroll completion callback.
|
||||
*/
|
||||
- (void)playTheIndexPath:(NSIndexPath *)indexPath
|
||||
assetURL:(NSURL *)assetURL
|
||||
scrollPosition:(ZFPlayerScrollViewScrollPosition)scrollPosition
|
||||
animated:(BOOL)animated
|
||||
completionHandler:(void (^ __nullable)(void))completionHandler;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@interface ZFPlayerController (ZFPlayerDeprecated)
|
||||
|
||||
/**
|
||||
Add the playerView to cell.
|
||||
*/
|
||||
- (void)updateScrollViewPlayerToCell __attribute__((deprecated("use `addPlayerViewToCell:` instead.")));
|
||||
|
||||
/**
|
||||
Add the playerView to containerView.
|
||||
|
||||
@param containerView The playerView containerView.
|
||||
*/
|
||||
- (void)updateNoramlPlayerWithContainerView:(UIView *)containerView __attribute__((deprecated("use `addPlayerViewToContainerView:` instead.")));
|
||||
|
||||
/**
|
||||
Play the indexPath of url ,while the `assetURLs` or `sectionAssetURLs` is not NULL.
|
||||
|
||||
@param indexPath Play the indexPath of url
|
||||
@param scrollToTop Scroll the current cell to top with animations.
|
||||
*/
|
||||
- (void)playTheIndexPath:(NSIndexPath *)indexPath scrollToTop:(BOOL)scrollToTop __attribute__((deprecated("use `playTheIndexPath:scrollPosition:animated:` instead.")));
|
||||
|
||||
/**
|
||||
Play the indexPath of url with scroll postion.
|
||||
|
||||
@param indexPath Play the indexPath of url
|
||||
@param assetURL The player URL.
|
||||
@param scrollToTop Scroll the current cell to top with animations.
|
||||
*/
|
||||
- (void)playTheIndexPath:(NSIndexPath *)indexPath assetURL:(NSURL *)assetURL scrollToTop:(BOOL)scrollToTop __attribute__((deprecated("use `playTheIndexPath:assetURL:scrollPosition:animated:` instead.")));
|
||||
|
||||
/**
|
||||
Play the indexPath of url ,while the `assetURLs` or `sectionAssetURLs` is not NULL.
|
||||
|
||||
@param indexPath Play the indexPath of url
|
||||
@param scrollToTop scroll the current cell to top with animations.
|
||||
@param completionHandler Scroll completion callback.
|
||||
*/
|
||||
- (void)playTheIndexPath:(NSIndexPath *)indexPath scrollToTop:(BOOL)scrollToTop completionHandler:(void (^ __nullable)(void))completionHandler __attribute__((deprecated("use `playTheIndexPath:scrollPosition:animated:completionHandler:` instead.")));
|
||||
|
||||
/**
|
||||
Enter the fullScreen while the ZFFullScreenMode is ZFFullScreenModeLandscape.
|
||||
|
||||
@param orientation UIInterfaceOrientation
|
||||
@param animated is animated.
|
||||
@param completion rotating completed callback.
|
||||
*/
|
||||
- (void)enterLandscapeFullScreen:(UIInterfaceOrientation)orientation animated:(BOOL)animated completion:(void(^ __nullable)(void))completion __attribute__((deprecated("use `rotateToOrientation:animated:completion:` instead.")));
|
||||
|
||||
/**
|
||||
Enter the fullScreen while the ZFFullScreenMode is ZFFullScreenModeLandscape.
|
||||
|
||||
@param orientation UIInterfaceOrientation
|
||||
@param animated is animated.
|
||||
*/
|
||||
- (void)enterLandscapeFullScreen:(UIInterfaceOrientation)orientation animated:(BOOL)animated __attribute__((deprecated("use `rotateToOrientation:animated:` instead.")));
|
||||
|
||||
/**
|
||||
Add to the keyWindow.
|
||||
*/
|
||||
- (void)addPlayerViewToKeyWindow __attribute__((deprecated("use `addPlayerViewToSmallFloatView` instead.")));;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
1448
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerController.m
generated
Normal file
1448
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerController.m
generated
Normal file
File diff suppressed because it is too large
Load Diff
137
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerGestureControl.h
generated
Executable file
137
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerGestureControl.h
generated
Executable file
@@ -0,0 +1,137 @@
|
||||
//
|
||||
// ZFPlayerGestureControl.h
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(NSUInteger, ZFPlayerGestureType) {
|
||||
ZFPlayerGestureTypeUnknown,
|
||||
ZFPlayerGestureTypeSingleTap,
|
||||
ZFPlayerGestureTypeDoubleTap,
|
||||
ZFPlayerGestureTypePan,
|
||||
ZFPlayerGestureTypePinch
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSUInteger, ZFPanDirection) {
|
||||
ZFPanDirectionUnknown,
|
||||
ZFPanDirectionV,
|
||||
ZFPanDirectionH,
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSUInteger, ZFPanLocation) {
|
||||
ZFPanLocationUnknown,
|
||||
ZFPanLocationLeft,
|
||||
ZFPanLocationRight,
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSUInteger, ZFPanMovingDirection) {
|
||||
ZFPanMovingDirectionUnkown,
|
||||
ZFPanMovingDirectionTop,
|
||||
ZFPanMovingDirectionLeft,
|
||||
ZFPanMovingDirectionBottom,
|
||||
ZFPanMovingDirectionRight,
|
||||
};
|
||||
|
||||
/// This enumeration lists some of the gesture types that the player has by default.
|
||||
typedef NS_OPTIONS(NSUInteger, ZFPlayerDisableGestureTypes) {
|
||||
ZFPlayerDisableGestureTypesNone = 0,
|
||||
ZFPlayerDisableGestureTypesSingleTap = 1 << 0,
|
||||
ZFPlayerDisableGestureTypesDoubleTap = 1 << 1,
|
||||
ZFPlayerDisableGestureTypesPan = 1 << 2,
|
||||
ZFPlayerDisableGestureTypesPinch = 1 << 3,
|
||||
ZFPlayerDisableGestureTypesAll = (ZFPlayerDisableGestureTypesSingleTap | ZFPlayerDisableGestureTypesDoubleTap | ZFPlayerDisableGestureTypesPan | ZFPlayerDisableGestureTypesPinch)
|
||||
};
|
||||
|
||||
/// This enumeration lists some of the pan gesture moving direction that the player not support.
|
||||
typedef NS_OPTIONS(NSUInteger, ZFPlayerDisablePanMovingDirection) {
|
||||
ZFPlayerDisablePanMovingDirectionNone = 0, /// Not disable pan moving direction.
|
||||
ZFPlayerDisablePanMovingDirectionVertical = 1 << 0, /// Disable pan moving vertical direction.
|
||||
ZFPlayerDisablePanMovingDirectionHorizontal = 1 << 1, /// Disable pan moving horizontal direction.
|
||||
ZFPlayerDisablePanMovingDirectionAll = (ZFPlayerDisablePanMovingDirectionVertical | ZFPlayerDisablePanMovingDirectionHorizontal) /// Disable pan moving all direction.
|
||||
};
|
||||
|
||||
@interface ZFPlayerGestureControl : NSObject
|
||||
|
||||
/// Gesture condition callback.
|
||||
@property (nonatomic, copy, nullable) BOOL(^triggerCondition)(ZFPlayerGestureControl *control, ZFPlayerGestureType type, UIGestureRecognizer *gesture, UITouch *touch);
|
||||
|
||||
/// Single tap gesture callback.
|
||||
@property (nonatomic, copy, nullable) void(^singleTapped)(ZFPlayerGestureControl *control);
|
||||
|
||||
/// Double tap gesture callback.
|
||||
@property (nonatomic, copy, nullable) void(^doubleTapped)(ZFPlayerGestureControl *control);
|
||||
|
||||
/// Begin pan gesture callback.
|
||||
@property (nonatomic, copy, nullable) void(^beganPan)(ZFPlayerGestureControl *control, ZFPanDirection direction, ZFPanLocation location);
|
||||
|
||||
/// Pan gesture changing callback.
|
||||
@property (nonatomic, copy, nullable) void(^changedPan)(ZFPlayerGestureControl *control, ZFPanDirection direction, ZFPanLocation location, CGPoint velocity);
|
||||
|
||||
/// End the Pan gesture callback.
|
||||
@property (nonatomic, copy, nullable) void(^endedPan)(ZFPlayerGestureControl *control, ZFPanDirection direction, ZFPanLocation location);
|
||||
|
||||
/// Pinch gesture callback.
|
||||
@property (nonatomic, copy, nullable) void(^pinched)(ZFPlayerGestureControl *control, float scale);
|
||||
|
||||
/// The single tap gesture.
|
||||
@property (nonatomic, strong, readonly) UITapGestureRecognizer *singleTap;
|
||||
|
||||
/// The double tap gesture.
|
||||
@property (nonatomic, strong, readonly) UITapGestureRecognizer *doubleTap;
|
||||
|
||||
/// The pan tap gesture.
|
||||
@property (nonatomic, strong, readonly) UIPanGestureRecognizer *panGR;
|
||||
|
||||
/// The pinch tap gesture.
|
||||
@property (nonatomic, strong, readonly) UIPinchGestureRecognizer *pinchGR;
|
||||
|
||||
/// The pan gesture direction.
|
||||
@property (nonatomic, readonly) ZFPanDirection panDirection;
|
||||
|
||||
/// The pan location.
|
||||
@property (nonatomic, readonly) ZFPanLocation panLocation;
|
||||
|
||||
/// The moving drection.
|
||||
@property (nonatomic, readonly) ZFPanMovingDirection panMovingDirection;
|
||||
|
||||
/// The gesture types that the player not support.
|
||||
@property (nonatomic) ZFPlayerDisableGestureTypes disableTypes;
|
||||
|
||||
/// The pan gesture moving direction that the player not support.
|
||||
@property (nonatomic) ZFPlayerDisablePanMovingDirection disablePanMovingDirection;
|
||||
|
||||
/**
|
||||
Add all gestures(singleTap、doubleTap、panGR、pinchGR) to the view.
|
||||
*/
|
||||
- (void)addGestureToView:(UIView *)view;
|
||||
|
||||
/**
|
||||
Remove all gestures(singleTap、doubleTap、panGR、pinchGR) form the view.
|
||||
*/
|
||||
- (void)removeGestureToView:(UIView *)view;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
261
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerGestureControl.m
generated
Executable file
261
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerGestureControl.m
generated
Executable file
@@ -0,0 +1,261 @@
|
||||
//
|
||||
// ZFPlayerGestureControl.m
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "ZFPlayerGestureControl.h"
|
||||
|
||||
@interface ZFPlayerGestureControl ()<UIGestureRecognizerDelegate>
|
||||
|
||||
@property (nonatomic, strong) UITapGestureRecognizer *singleTap;
|
||||
@property (nonatomic, strong) UITapGestureRecognizer *doubleTap;
|
||||
@property (nonatomic, strong) UIPanGestureRecognizer *panGR;
|
||||
@property (nonatomic, strong) UIPinchGestureRecognizer *pinchGR;
|
||||
@property (nonatomic) ZFPanDirection panDirection;
|
||||
@property (nonatomic) ZFPanLocation panLocation;
|
||||
@property (nonatomic) ZFPanMovingDirection panMovingDirection;
|
||||
@property (nonatomic, weak) UIView *targetView;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ZFPlayerGestureControl
|
||||
|
||||
- (void)addGestureToView:(UIView *)view {
|
||||
self.targetView = view;
|
||||
self.targetView.multipleTouchEnabled = YES;
|
||||
[self.singleTap requireGestureRecognizerToFail:self.doubleTap];
|
||||
[self.singleTap requireGestureRecognizerToFail:self.panGR];
|
||||
[self.targetView addGestureRecognizer:self.singleTap];
|
||||
[self.targetView addGestureRecognizer:self.doubleTap];
|
||||
[self.targetView addGestureRecognizer:self.panGR];
|
||||
[self.targetView addGestureRecognizer:self.pinchGR];
|
||||
}
|
||||
|
||||
- (void)removeGestureToView:(UIView *)view {
|
||||
[view removeGestureRecognizer:self.singleTap];
|
||||
[view removeGestureRecognizer:self.doubleTap];
|
||||
[view removeGestureRecognizer:self.panGR];
|
||||
[view removeGestureRecognizer:self.pinchGR];
|
||||
}
|
||||
|
||||
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
|
||||
if (gestureRecognizer == self.panGR) {
|
||||
CGPoint translation = [(UIPanGestureRecognizer *)gestureRecognizer translationInView:self.targetView];
|
||||
CGFloat x = fabs(translation.x);
|
||||
CGFloat y = fabs(translation.y);
|
||||
if (x < y && self.disablePanMovingDirection & ZFPlayerDisablePanMovingDirectionVertical) { /// up and down moving direction.
|
||||
return NO;
|
||||
} else if (x > y && self.disablePanMovingDirection & ZFPlayerDisablePanMovingDirectionHorizontal) { /// left and right moving direction.
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
|
||||
ZFPlayerGestureType type = ZFPlayerGestureTypeUnknown;
|
||||
if (gestureRecognizer == self.singleTap) type = ZFPlayerGestureTypeSingleTap;
|
||||
else if (gestureRecognizer == self.doubleTap) type = ZFPlayerGestureTypeDoubleTap;
|
||||
else if (gestureRecognizer == self.panGR) type = ZFPlayerGestureTypePan;
|
||||
else if (gestureRecognizer == self.pinchGR) type = ZFPlayerGestureTypePinch;
|
||||
CGPoint locationPoint = [touch locationInView:touch.view];
|
||||
if (locationPoint.x > _targetView.bounds.size.width / 2) {
|
||||
self.panLocation = ZFPanLocationRight;
|
||||
} else {
|
||||
self.panLocation = ZFPanLocationLeft;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case ZFPlayerGestureTypeUnknown: break;
|
||||
case ZFPlayerGestureTypePan: {
|
||||
if (self.disableTypes & ZFPlayerDisableGestureTypesPan) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZFPlayerGestureTypePinch: {
|
||||
if (self.disableTypes & ZFPlayerDisableGestureTypesPinch) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZFPlayerGestureTypeDoubleTap: {
|
||||
if (self.disableTypes & ZFPlayerDisableGestureTypesDoubleTap) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZFPlayerGestureTypeSingleTap: {
|
||||
if (self.disableTypes & ZFPlayerDisableGestureTypesSingleTap) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (self.triggerCondition) return self.triggerCondition(self, type, gestureRecognizer, touch);
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Whether to support multi-trigger, return YES, you can trigger a method with multiple gestures, return NO is mutually exclusive
|
||||
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
|
||||
if (otherGestureRecognizer != self.singleTap &&
|
||||
otherGestureRecognizer != self.doubleTap &&
|
||||
otherGestureRecognizer != self.panGR &&
|
||||
otherGestureRecognizer != self.pinchGR) return NO;
|
||||
|
||||
if (gestureRecognizer == self.panGR) {
|
||||
CGPoint translation = [(UIPanGestureRecognizer *)gestureRecognizer translationInView:self.targetView];
|
||||
CGFloat x = fabs(translation.x);
|
||||
CGFloat y = fabs(translation.y);
|
||||
if (x < y && self.disablePanMovingDirection & ZFPlayerDisablePanMovingDirectionVertical) {
|
||||
return YES;
|
||||
} else if (x > y && self.disablePanMovingDirection & ZFPlayerDisablePanMovingDirectionHorizontal) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
if (gestureRecognizer.numberOfTouches >= 2) {
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (UITapGestureRecognizer *)singleTap {
|
||||
if (!_singleTap){
|
||||
_singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
|
||||
_singleTap.delegate = self;
|
||||
_singleTap.delaysTouchesBegan = YES;
|
||||
_singleTap.delaysTouchesEnded = YES;
|
||||
_singleTap.numberOfTouchesRequired = 1;
|
||||
_singleTap.numberOfTapsRequired = 1;
|
||||
}
|
||||
return _singleTap;
|
||||
}
|
||||
|
||||
- (UITapGestureRecognizer *)doubleTap {
|
||||
if (!_doubleTap) {
|
||||
_doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
|
||||
_doubleTap.delegate = self;
|
||||
_doubleTap.delaysTouchesBegan = YES;
|
||||
_singleTap.delaysTouchesEnded = YES;
|
||||
_doubleTap.numberOfTouchesRequired = 1;
|
||||
_doubleTap.numberOfTapsRequired = 2;
|
||||
}
|
||||
return _doubleTap;
|
||||
}
|
||||
|
||||
- (UIPanGestureRecognizer *)panGR {
|
||||
if (!_panGR) {
|
||||
_panGR = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
|
||||
_panGR.delegate = self;
|
||||
_panGR.delaysTouchesBegan = YES;
|
||||
_panGR.delaysTouchesEnded = YES;
|
||||
_panGR.maximumNumberOfTouches = 1;
|
||||
_panGR.cancelsTouchesInView = YES;
|
||||
}
|
||||
return _panGR;
|
||||
}
|
||||
|
||||
- (UIPinchGestureRecognizer *)pinchGR {
|
||||
if (!_pinchGR) {
|
||||
_pinchGR = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)];
|
||||
_pinchGR.delegate = self;
|
||||
_pinchGR.delaysTouchesBegan = YES;
|
||||
}
|
||||
return _pinchGR;
|
||||
}
|
||||
|
||||
- (void)handleSingleTap:(UITapGestureRecognizer *)tap {
|
||||
if (self.singleTapped) self.singleTapped(self);
|
||||
}
|
||||
|
||||
- (void)handleDoubleTap:(UITapGestureRecognizer *)tap {
|
||||
if (self.doubleTapped) self.doubleTapped(self);
|
||||
}
|
||||
|
||||
- (void)handlePan:(UIPanGestureRecognizer *)pan {
|
||||
CGPoint translate = [pan translationInView:pan.view];
|
||||
CGPoint velocity = [pan velocityInView:pan.view];
|
||||
switch (pan.state) {
|
||||
case UIGestureRecognizerStateBegan: {
|
||||
self.panMovingDirection = ZFPanMovingDirectionUnkown;
|
||||
CGFloat x = fabs(velocity.x);
|
||||
CGFloat y = fabs(velocity.y);
|
||||
if (x > y) {
|
||||
self.panDirection = ZFPanDirectionH;
|
||||
} else if (x < y) {
|
||||
self.panDirection = ZFPanDirectionV;
|
||||
} else {
|
||||
self.panDirection = ZFPanDirectionUnknown;
|
||||
}
|
||||
|
||||
if (self.beganPan) self.beganPan(self, self.panDirection, self.panLocation);
|
||||
}
|
||||
break;
|
||||
case UIGestureRecognizerStateChanged: {
|
||||
switch (_panDirection) {
|
||||
case ZFPanDirectionH: {
|
||||
if (translate.x > 0) {
|
||||
self.panMovingDirection = ZFPanMovingDirectionRight;
|
||||
} else {
|
||||
self.panMovingDirection = ZFPanMovingDirectionLeft;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZFPanDirectionV: {
|
||||
if (translate.y > 0) {
|
||||
self.panMovingDirection = ZFPanMovingDirectionBottom;
|
||||
} else {
|
||||
self.panMovingDirection = ZFPanMovingDirectionTop;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZFPanDirectionUnknown:
|
||||
break;
|
||||
}
|
||||
if (self.changedPan) self.changedPan(self, self.panDirection, self.panLocation, velocity);
|
||||
}
|
||||
break;
|
||||
case UIGestureRecognizerStateFailed:
|
||||
case UIGestureRecognizerStateCancelled:
|
||||
case UIGestureRecognizerStateEnded: {
|
||||
if (self.endedPan) self.endedPan(self, self.panDirection, self.panLocation);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
[pan setTranslation:CGPointZero inView:pan.view];
|
||||
}
|
||||
|
||||
- (void)handlePinch:(UIPinchGestureRecognizer *)pinch {
|
||||
switch (pinch.state) {
|
||||
case UIGestureRecognizerStateEnded: {
|
||||
if (self.pinched) self.pinched(self, pinch.scale);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
44
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerLogManager.h
generated
Executable file
44
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerLogManager.h
generated
Executable file
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// ZFPlayerLogManager.h
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#define ZFPlayerLog(format,...) [ZFPlayerLogManager logWithFunction:__FUNCTION__ lineNumber:__LINE__ formatString:[NSString stringWithFormat:format, ##__VA_ARGS__]]
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface ZFPlayerLogManager : NSObject
|
||||
|
||||
// Set the log output status.
|
||||
+ (void)setLogEnable:(BOOL)enable;
|
||||
|
||||
// Gets the log output status.
|
||||
+ (BOOL)getLogEnable;
|
||||
|
||||
/// Get ZFPlayer version.
|
||||
+ (NSString *)version;
|
||||
|
||||
// Log output method.
|
||||
+ (void)logWithFunction:(const char *)function lineNumber:(int)lineNumber formatString:(NSString *)formatString;
|
||||
|
||||
@end
|
||||
49
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerLogManager.m
generated
Executable file
49
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerLogManager.m
generated
Executable file
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// ZFPlayerLogManager.m
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "ZFPlayerLogManager.h"
|
||||
|
||||
static BOOL kLogEnable = NO;
|
||||
|
||||
@implementation ZFPlayerLogManager
|
||||
|
||||
+ (void)setLogEnable:(BOOL)enable {
|
||||
kLogEnable = enable;
|
||||
}
|
||||
|
||||
+ (BOOL)getLogEnable {
|
||||
return kLogEnable;
|
||||
}
|
||||
|
||||
+ (NSString *)version {
|
||||
return @"4.0.2";
|
||||
}
|
||||
|
||||
+ (void)logWithFunction:(const char *)function lineNumber:(int)lineNumber formatString:(NSString *)formatString {
|
||||
if ([self getLogEnable]) {
|
||||
NSLog(@"%s[%d]%@", function, lineNumber, formatString);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
210
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerMediaControl.h
generated
Normal file
210
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerMediaControl.h
generated
Normal file
@@ -0,0 +1,210 @@
|
||||
//
|
||||
// ZFPlayerMediaControl.h
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "ZFPlayerMediaPlayback.h"
|
||||
#import "ZFOrientationObserver.h"
|
||||
#import "ZFPlayerGestureControl.h"
|
||||
#import "ZFReachabilityManager.h"
|
||||
@class ZFPlayerController;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol ZFPlayerMediaControl <NSObject>
|
||||
|
||||
@required
|
||||
/// Current playerController
|
||||
@property (nonatomic, weak) ZFPlayerController *player;
|
||||
|
||||
@optional
|
||||
|
||||
#pragma mark - Playback state
|
||||
|
||||
/// When the player prepare to play the video.
|
||||
- (void)videoPlayer:(ZFPlayerController *)videoPlayer prepareToPlay:(NSURL *)assetURL;
|
||||
|
||||
/// When th player playback state changed.
|
||||
- (void)videoPlayer:(ZFPlayerController *)videoPlayer playStateChanged:(ZFPlayerPlaybackState)state;
|
||||
|
||||
/// When th player loading state changed.
|
||||
- (void)videoPlayer:(ZFPlayerController *)videoPlayer loadStateChanged:(ZFPlayerLoadState)state;
|
||||
|
||||
#pragma mark - progress
|
||||
|
||||
/**
|
||||
When the playback changed.
|
||||
|
||||
@param videoPlayer the player.
|
||||
@param currentTime the current play time.
|
||||
@param totalTime the video total time.
|
||||
*/
|
||||
- (void)videoPlayer:(ZFPlayerController *)videoPlayer
|
||||
currentTime:(NSTimeInterval)currentTime
|
||||
totalTime:(NSTimeInterval)totalTime;
|
||||
|
||||
/**
|
||||
When buffer progress changed.
|
||||
*/
|
||||
- (void)videoPlayer:(ZFPlayerController *)videoPlayer
|
||||
bufferTime:(NSTimeInterval)bufferTime;
|
||||
|
||||
/**
|
||||
When you are dragging to change the video progress.
|
||||
*/
|
||||
- (void)videoPlayer:(ZFPlayerController *)videoPlayer
|
||||
draggingTime:(NSTimeInterval)seekTime
|
||||
totalTime:(NSTimeInterval)totalTime;
|
||||
|
||||
/**
|
||||
When play end.
|
||||
*/
|
||||
- (void)videoPlayerPlayEnd:(ZFPlayerController *)videoPlayer;
|
||||
|
||||
/**
|
||||
When play failed.
|
||||
*/
|
||||
- (void)videoPlayerPlayFailed:(ZFPlayerController *)videoPlayer error:(id)error;
|
||||
|
||||
#pragma mark - lock screen
|
||||
|
||||
/**
|
||||
When set `videoPlayer.lockedScreen`.
|
||||
*/
|
||||
- (void)lockedVideoPlayer:(ZFPlayerController *)videoPlayer lockedScreen:(BOOL)locked;
|
||||
|
||||
#pragma mark - Screen rotation
|
||||
|
||||
/**
|
||||
When the fullScreen maode will changed.
|
||||
*/
|
||||
- (void)videoPlayer:(ZFPlayerController *)videoPlayer orientationWillChange:(ZFOrientationObserver *)observer;
|
||||
|
||||
/**
|
||||
When the fullScreen maode did changed.
|
||||
*/
|
||||
- (void)videoPlayer:(ZFPlayerController *)videoPlayer orientationDidChanged:(ZFOrientationObserver *)observer;
|
||||
|
||||
#pragma mark - The network changed
|
||||
|
||||
/**
|
||||
When the network changed
|
||||
*/
|
||||
- (void)videoPlayer:(ZFPlayerController *)videoPlayer reachabilityChanged:(ZFReachabilityStatus)status;
|
||||
|
||||
#pragma mark - The video size changed
|
||||
|
||||
/**
|
||||
When the video size changed
|
||||
*/
|
||||
- (void)videoPlayer:(ZFPlayerController *)videoPlayer presentationSizeChanged:(CGSize)size;
|
||||
|
||||
#pragma mark - Gesture
|
||||
|
||||
/**
|
||||
When the gesture condition
|
||||
*/
|
||||
- (BOOL)gestureTriggerCondition:(ZFPlayerGestureControl *)gestureControl
|
||||
gestureType:(ZFPlayerGestureType)gestureType
|
||||
gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
|
||||
touch:(UITouch *)touch;
|
||||
|
||||
/**
|
||||
When the gesture single tapped
|
||||
*/
|
||||
- (void)gestureSingleTapped:(ZFPlayerGestureControl *)gestureControl;
|
||||
|
||||
/**
|
||||
When the gesture double tapped
|
||||
*/
|
||||
- (void)gestureDoubleTapped:(ZFPlayerGestureControl *)gestureControl;
|
||||
|
||||
/**
|
||||
When the gesture begin panGesture
|
||||
*/
|
||||
- (void)gestureBeganPan:(ZFPlayerGestureControl *)gestureControl
|
||||
panDirection:(ZFPanDirection)direction
|
||||
panLocation:(ZFPanLocation)location;
|
||||
|
||||
/**
|
||||
When the gesture paning
|
||||
*/
|
||||
- (void)gestureChangedPan:(ZFPlayerGestureControl *)gestureControl
|
||||
panDirection:(ZFPanDirection)direction
|
||||
panLocation:(ZFPanLocation)location
|
||||
withVelocity:(CGPoint)velocity;
|
||||
|
||||
/**
|
||||
When the end panGesture
|
||||
*/
|
||||
- (void)gestureEndedPan:(ZFPlayerGestureControl *)gestureControl
|
||||
panDirection:(ZFPanDirection)direction
|
||||
panLocation:(ZFPanLocation)location;
|
||||
|
||||
/**
|
||||
When the pinchGesture changed
|
||||
*/
|
||||
- (void)gesturePinched:(ZFPlayerGestureControl *)gestureControl
|
||||
scale:(float)scale;
|
||||
|
||||
#pragma mark - scrollview
|
||||
|
||||
/**
|
||||
When the player will appear in scrollView.
|
||||
*/
|
||||
- (void)playerWillAppearInScrollView:(ZFPlayerController *)videoPlayer;
|
||||
|
||||
/**
|
||||
When the player did appear in scrollView.
|
||||
*/
|
||||
- (void)playerDidAppearInScrollView:(ZFPlayerController *)videoPlayer;
|
||||
|
||||
/**
|
||||
When the player will disappear in scrollView.
|
||||
*/
|
||||
- (void)playerWillDisappearInScrollView:(ZFPlayerController *)videoPlayer;
|
||||
|
||||
/**
|
||||
When the player did disappear in scrollView.
|
||||
*/
|
||||
- (void)playerDidDisappearInScrollView:(ZFPlayerController *)videoPlayer;
|
||||
|
||||
/**
|
||||
When the player appearing in scrollView.
|
||||
*/
|
||||
- (void)playerAppearingInScrollView:(ZFPlayerController *)videoPlayer playerApperaPercent:(CGFloat)playerApperaPercent;
|
||||
|
||||
/**
|
||||
When the player disappearing in scrollView.
|
||||
*/
|
||||
- (void)playerDisappearingInScrollView:(ZFPlayerController *)videoPlayer playerDisapperaPercent:(CGFloat)playerDisapperaPercent;
|
||||
|
||||
/**
|
||||
When the small float view show.
|
||||
*/
|
||||
- (void)videoPlayer:(ZFPlayerController *)videoPlayer floatViewShow:(BOOL)show;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
160
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerMediaPlayback.h
generated
Normal file
160
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerMediaPlayback.h
generated
Normal file
@@ -0,0 +1,160 @@
|
||||
//
|
||||
// ZFMediaPlayback.h
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "ZFPlayerView.h"
|
||||
#import "ZFPlayerConst.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol ZFPlayerMediaPlayback <NSObject>
|
||||
|
||||
@required
|
||||
/// The view must inherited `ZFPlayerView`,this view deals with some gesture conflicts.
|
||||
@property (nonatomic) ZFPlayerView *view;
|
||||
|
||||
/// The player volume.
|
||||
/// Only affects audio volume for the player instance and not for the device.
|
||||
/// You can change device volume or player volume as needed,change the player volume you can follow the `ZFPlayerMediaPlayback` protocol.
|
||||
@property (nonatomic) float volume;
|
||||
|
||||
/// The player muted.
|
||||
/// indicates whether or not audio output of the player is muted. Only affects audio muting for the player instance and not for the device.
|
||||
/// You can change device volume or player muted as needed,change the player muted you can follow the `ZFPlayerMediaPlayback` protocol.
|
||||
@property (nonatomic, getter=isMuted) BOOL muted;
|
||||
|
||||
/// Playback speed,0.5...2
|
||||
@property (nonatomic) float rate;
|
||||
|
||||
/// The player current play time.
|
||||
@property (nonatomic, readonly) NSTimeInterval currentTime;
|
||||
|
||||
/// The player total time.
|
||||
@property (nonatomic, readonly) NSTimeInterval totalTime;
|
||||
|
||||
/// The player buffer time.
|
||||
@property (nonatomic, readonly) NSTimeInterval bufferTime;
|
||||
|
||||
/// The player seek time.
|
||||
@property (nonatomic) NSTimeInterval seekTime;
|
||||
|
||||
/// The player play state,playing or not playing.
|
||||
@property (nonatomic, readonly) BOOL isPlaying;
|
||||
|
||||
/// Determines how the content scales to fit the view. Defaults to ZFPlayerScalingModeNone.
|
||||
@property (nonatomic) ZFPlayerScalingMode scalingMode;
|
||||
|
||||
/**
|
||||
@abstract Check whether video preparation is complete.
|
||||
@discussion isPreparedToPlay processing logic
|
||||
|
||||
* If isPreparedToPlay is true, you can call [ZFPlayerMediaPlayback play] API start playing;
|
||||
* If isPreparedToPlay to false, direct call [ZFPlayerMediaPlayback play], in the play the internal automatic call [ZFPlayerMediaPlayback prepareToPlay] API.
|
||||
* Returns true if prepared for playback.
|
||||
*/
|
||||
@property (nonatomic, readonly) BOOL isPreparedToPlay;
|
||||
|
||||
/// The player should auto player, default is YES.
|
||||
@property (nonatomic) BOOL shouldAutoPlay;
|
||||
|
||||
/// The play asset URL.
|
||||
@property (nonatomic) NSURL *assetURL;
|
||||
|
||||
/// The video size.
|
||||
@property (nonatomic) CGSize presentationSize;
|
||||
|
||||
/// The playback state.
|
||||
@property (nonatomic, readonly) ZFPlayerPlaybackState playState;
|
||||
|
||||
/// The player load state.
|
||||
@property (nonatomic, readonly) ZFPlayerLoadState loadState;
|
||||
|
||||
///------------------------------------
|
||||
/// If you don't appoint the controlView, you can called the following blocks.
|
||||
/// If you appoint the controlView, The following block cannot be called outside, only for `ZFPlayerController` calls.
|
||||
///------------------------------------
|
||||
|
||||
/// The block invoked when the player is Prepare to play.
|
||||
@property (nonatomic, copy, nullable) void(^playerPrepareToPlay)(id<ZFPlayerMediaPlayback> asset, NSURL *assetURL);
|
||||
|
||||
/// The block invoked when the player is Ready to play.
|
||||
@property (nonatomic, copy, nullable) void(^playerReadyToPlay)(id<ZFPlayerMediaPlayback> asset, NSURL *assetURL);
|
||||
|
||||
/// The block invoked when the player play progress changed.
|
||||
@property (nonatomic, copy, nullable) void(^playerPlayTimeChanged)(id<ZFPlayerMediaPlayback> asset, NSTimeInterval currentTime, NSTimeInterval duration);
|
||||
|
||||
/// The block invoked when the player play buffer changed.
|
||||
@property (nonatomic, copy, nullable) void(^playerBufferTimeChanged)(id<ZFPlayerMediaPlayback> asset, NSTimeInterval bufferTime);
|
||||
|
||||
/// The block invoked when the player playback state changed.
|
||||
@property (nonatomic, copy, nullable) void(^playerPlayStateChanged)(id<ZFPlayerMediaPlayback> asset, ZFPlayerPlaybackState playState);
|
||||
|
||||
/// The block invoked when the player load state changed.
|
||||
@property (nonatomic, copy, nullable) void(^playerLoadStateChanged)(id<ZFPlayerMediaPlayback> asset, ZFPlayerLoadState loadState);
|
||||
|
||||
/// The block invoked when the player play failed.
|
||||
@property (nonatomic, copy, nullable) void(^playerPlayFailed)(id<ZFPlayerMediaPlayback> asset, id error);
|
||||
|
||||
/// The block invoked when the player play end.
|
||||
@property (nonatomic, copy, nullable) void(^playerDidToEnd)(id<ZFPlayerMediaPlayback> asset);
|
||||
|
||||
// The block invoked when video size changed.
|
||||
@property (nonatomic, copy, nullable) void(^presentationSizeChanged)(id<ZFPlayerMediaPlayback> asset, CGSize size);
|
||||
|
||||
///------------------------------------
|
||||
/// end
|
||||
///------------------------------------
|
||||
|
||||
/// Prepares the current queue for playback, interrupting any active (non-mixible) audio sessions.
|
||||
- (void)prepareToPlay;
|
||||
|
||||
/// Reload player.
|
||||
- (void)reloadPlayer;
|
||||
|
||||
/// Play playback.
|
||||
- (void)play;
|
||||
|
||||
/// Pauses playback.
|
||||
- (void)pause;
|
||||
|
||||
/// Replay playback.
|
||||
- (void)replay;
|
||||
|
||||
/// Stop playback.
|
||||
- (void)stop;
|
||||
|
||||
/// Use this method to seek to a specified time for the current player and to be notified when the seek operation is complete.
|
||||
- (void)seekToTime:(NSTimeInterval)time completionHandler:(void (^ __nullable)(BOOL finished))completionHandler;
|
||||
|
||||
@optional
|
||||
|
||||
/// Video UIImage at the current time.
|
||||
- (UIImage *)thumbnailImageAtCurrentTime;
|
||||
|
||||
/// Video UIImage at the current time.
|
||||
- (void)thumbnailImageAtCurrentTime:(void(^)(UIImage *))handler;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
59
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerNotification.h
generated
Executable file
59
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerNotification.h
generated
Executable file
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// ZFPlayerNotification.h
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(NSUInteger, ZFPlayerBackgroundState) {
|
||||
ZFPlayerBackgroundStateForeground, // Enter the foreground from the background.
|
||||
ZFPlayerBackgroundStateBackground, // From the foreground to the background.
|
||||
};
|
||||
|
||||
@interface ZFPlayerNotification : NSObject
|
||||
|
||||
@property (nonatomic, readonly) ZFPlayerBackgroundState backgroundState;
|
||||
|
||||
@property (nonatomic, copy, nullable) void(^willResignActive)(ZFPlayerNotification *registrar);
|
||||
|
||||
@property (nonatomic, copy, nullable) void(^didBecomeActive)(ZFPlayerNotification *registrar);
|
||||
|
||||
@property (nonatomic, copy, nullable) void(^newDeviceAvailable)(ZFPlayerNotification *registrar);
|
||||
|
||||
@property (nonatomic, copy, nullable) void(^oldDeviceUnavailable)(ZFPlayerNotification *registrar);
|
||||
|
||||
@property (nonatomic, copy, nullable) void(^categoryChange)(ZFPlayerNotification *registrar);
|
||||
|
||||
@property (nonatomic, copy, nullable) void(^volumeChanged)(float volume);
|
||||
|
||||
@property (nonatomic, copy, nullable) void(^audioInterruptionCallback)(AVAudioSessionInterruptionType interruptionType);
|
||||
|
||||
- (void)addNotification;
|
||||
|
||||
- (void)removeNotification;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
113
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerNotification.m
generated
Executable file
113
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerNotification.m
generated
Executable file
@@ -0,0 +1,113 @@
|
||||
//
|
||||
// ZFPlayerNotification.m
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "ZFPlayerNotification.h"
|
||||
|
||||
@interface ZFPlayerNotification ()
|
||||
|
||||
@property (nonatomic, assign) ZFPlayerBackgroundState backgroundState;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ZFPlayerNotification
|
||||
|
||||
- (void)addNotification {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(audioSessionRouteChangeNotification:)
|
||||
name:AVAudioSessionRouteChangeNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(applicationWillResignActiveNotification)
|
||||
name:UIApplicationWillResignActiveNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(applicationDidBecomeActiveNotification)
|
||||
name:UIApplicationDidBecomeActiveNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(volumeDidChangeNotification:)
|
||||
name:@"AVSystemController_SystemVolumeDidChangeNotification"
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(audioSessionInterruptionNotification:)
|
||||
name:AVAudioSessionInterruptionNotification
|
||||
object:nil];
|
||||
|
||||
}
|
||||
|
||||
- (void)removeNotification {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVAudioSessionRouteChangeNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillResignActiveNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVAudioSessionInterruptionNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[self removeNotification];
|
||||
}
|
||||
|
||||
- (void)audioSessionRouteChangeNotification:(NSNotification*)notification {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSDictionary *interuptionDict = notification.userInfo;
|
||||
NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
|
||||
switch (routeChangeReason) {
|
||||
case AVAudioSessionRouteChangeReasonNewDeviceAvailable: {
|
||||
if (self.newDeviceAvailable) self.newDeviceAvailable(self);
|
||||
}
|
||||
break;
|
||||
case AVAudioSessionRouteChangeReasonOldDeviceUnavailable: {
|
||||
if (self.oldDeviceUnavailable) self.oldDeviceUnavailable(self);
|
||||
}
|
||||
break;
|
||||
case AVAudioSessionRouteChangeReasonCategoryChange: {
|
||||
if (self.categoryChange) self.categoryChange(self);
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)volumeDidChangeNotification:(NSNotification *)notification {
|
||||
float volume = [[[notification userInfo] objectForKey:@"AVSystemController_AudioVolumeNotificationParameter"] floatValue];
|
||||
if (self.volumeChanged) self.volumeChanged(volume);
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActiveNotification {
|
||||
self.backgroundState = ZFPlayerBackgroundStateBackground;
|
||||
if (_willResignActive) _willResignActive(self);
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActiveNotification {
|
||||
self.backgroundState = ZFPlayerBackgroundStateForeground;
|
||||
if (_didBecomeActive) _didBecomeActive(self);
|
||||
}
|
||||
|
||||
- (void)audioSessionInterruptionNotification:(NSNotification *)notification {
|
||||
NSDictionary *interuptionDict = notification.userInfo;
|
||||
AVAudioSessionInterruptionType interruptionType = [[interuptionDict valueForKey:AVAudioSessionInterruptionTypeKey] integerValue];
|
||||
if (self.audioInterruptionCallback) self.audioInterruptionCallback(interruptionType);
|
||||
}
|
||||
|
||||
@end
|
||||
42
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerView.h
generated
Normal file
42
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerView.h
generated
Normal file
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// ZFPlayerView.h
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "ZFPlayerConst.h"
|
||||
|
||||
@interface ZFPlayerView : UIView
|
||||
|
||||
/// player content view.
|
||||
@property (nonatomic, strong) UIView *playerView;
|
||||
|
||||
/// Determines how the content scales to fit the view.
|
||||
@property (nonatomic, assign) ZFPlayerScalingMode scalingMode;
|
||||
|
||||
/// The video size.
|
||||
@property (nonatomic, assign) CGSize presentationSize;
|
||||
|
||||
/// The cover for playerView.
|
||||
@property (nonatomic, strong, readonly) UIImageView *coverImageView;
|
||||
|
||||
@end
|
||||
125
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerView.m
generated
Normal file
125
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPlayerView.m
generated
Normal file
@@ -0,0 +1,125 @@
|
||||
//
|
||||
// ZFPlayerView.m
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "ZFPlayerView.h"
|
||||
#import "ZFPlayerConst.h"
|
||||
|
||||
@implementation ZFPlayerView
|
||||
@synthesize presentationSize = _presentationSize;
|
||||
@synthesize coverImageView = _coverImageView;
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.backgroundColor = [UIColor blackColor];
|
||||
[self addSubview:self.coverImageView];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setPlayerView:(UIView *)playerView {
|
||||
if (_playerView) {
|
||||
[_playerView removeFromSuperview];
|
||||
self.presentationSize = CGSizeZero;
|
||||
}
|
||||
_playerView = playerView;
|
||||
if (playerView != nil) {
|
||||
[self addSubview:playerView];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)layoutSubviews {
|
||||
[super layoutSubviews];
|
||||
CGFloat min_x = 0;
|
||||
CGFloat min_y = 0;
|
||||
CGFloat min_w = 0;
|
||||
CGFloat min_h = 0;
|
||||
CGFloat min_view_w = self.frame.size.width;
|
||||
CGFloat min_view_h = self.frame.size.height;
|
||||
|
||||
CGSize playerViewSize = CGSizeZero;
|
||||
CGFloat videoWidth = self.presentationSize.width;
|
||||
CGFloat videoHeight = self.presentationSize.height;
|
||||
if (videoHeight == 0) return;
|
||||
CGFloat screenScale = min_view_w/min_view_h;
|
||||
CGFloat videoScale = videoWidth/videoHeight;
|
||||
if (screenScale > videoScale) {
|
||||
CGFloat height = min_view_h;
|
||||
CGFloat width = height * videoScale;
|
||||
playerViewSize = CGSizeMake(width, height);
|
||||
} else {
|
||||
CGFloat width = min_view_w;
|
||||
CGFloat height = width / videoScale;
|
||||
playerViewSize = CGSizeMake(width, height);
|
||||
}
|
||||
|
||||
if (self.scalingMode == ZFPlayerScalingModeNone || self.scalingMode == ZFPlayerScalingModeAspectFit) {
|
||||
min_w = playerViewSize.width;
|
||||
min_h = playerViewSize.height;
|
||||
min_x = (min_view_w - min_w) / 2.0;
|
||||
min_y = (min_view_h - min_h) / 2.0;
|
||||
self.playerView.frame = CGRectMake(min_x, min_y, min_w, min_h);
|
||||
} else if (self.scalingMode == ZFPlayerScalingModeAspectFill || self.scalingMode == ZFPlayerScalingModeFill) {
|
||||
self.playerView.frame = self.bounds;
|
||||
}
|
||||
self.coverImageView.frame = self.playerView.frame;
|
||||
}
|
||||
|
||||
- (CGSize)presentationSize {
|
||||
if (CGSizeEqualToSize(_presentationSize, CGSizeZero)) {
|
||||
_presentationSize = self.frame.size;
|
||||
}
|
||||
return _presentationSize;
|
||||
}
|
||||
|
||||
- (UIImageView *)coverImageView {
|
||||
if (!_coverImageView) {
|
||||
_coverImageView = [[UIImageView alloc] init];
|
||||
_coverImageView.userInteractionEnabled = YES;
|
||||
_coverImageView.clipsToBounds = YES;
|
||||
_coverImageView.contentMode = UIViewContentModeScaleAspectFit;
|
||||
}
|
||||
return _coverImageView;
|
||||
}
|
||||
|
||||
- (void)setScalingMode:(ZFPlayerScalingMode)scalingMode {
|
||||
_scalingMode = scalingMode;
|
||||
if (scalingMode == ZFPlayerScalingModeNone || scalingMode == ZFPlayerScalingModeAspectFit) {
|
||||
self.coverImageView.contentMode = UIViewContentModeScaleAspectFit;
|
||||
} else if (scalingMode == ZFPlayerScalingModeAspectFill) {
|
||||
self.coverImageView.contentMode = UIViewContentModeScaleAspectFill;
|
||||
} else if (scalingMode == ZFPlayerScalingModeFill) {
|
||||
self.coverImageView.contentMode = UIViewContentModeScaleToFill;
|
||||
}
|
||||
[self layoutIfNeeded];
|
||||
}
|
||||
|
||||
- (void)setPresentationSize:(CGSize)presentationSize {
|
||||
_presentationSize = presentationSize;
|
||||
if (CGSizeEqualToSize(CGSizeZero, presentationSize)) return;
|
||||
[self setNeedsLayout];
|
||||
[self layoutIfNeeded];
|
||||
}
|
||||
|
||||
@end
|
||||
60
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPortraitViewController.h
generated
Normal file
60
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPortraitViewController.h
generated
Normal file
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// ZFPortraitViewController.h
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "ZFOrientationObserver.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface ZFPortraitViewController : UIViewController
|
||||
|
||||
/// The block invoked When player will rotate.
|
||||
@property (nonatomic, copy, nullable) void(^orientationWillChange)(BOOL isFullScreen);
|
||||
|
||||
/// The block invoked when player rotated.
|
||||
@property (nonatomic, copy, nullable) void(^orientationDidChanged)(BOOL isFullScreen);
|
||||
|
||||
@property (nonatomic, strong) UIView *contentView;
|
||||
|
||||
@property (nonatomic, strong) UIView *containerView;
|
||||
|
||||
@property (nonatomic, assign) BOOL statusBarHidden;
|
||||
|
||||
/// default is UIStatusBarStyleLightContent.
|
||||
@property (nonatomic, assign) UIStatusBarStyle statusBarStyle;
|
||||
/// defalut is UIStatusBarAnimationSlide.
|
||||
@property (nonatomic, assign) UIStatusBarAnimation statusBarAnimation;
|
||||
|
||||
/// default is ZFDisablePortraitGestureTypesNone.
|
||||
@property (nonatomic, assign) ZFDisablePortraitGestureTypes disablePortraitGestureTypes;
|
||||
|
||||
@property (nonatomic, assign) CGSize presentationSize;
|
||||
|
||||
@property (nonatomic, assign) BOOL fullScreenAnimation;
|
||||
|
||||
@property (nonatomic, assign) NSTimeInterval duration;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
231
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPortraitViewController.m
generated
Normal file
231
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPortraitViewController.m
generated
Normal file
@@ -0,0 +1,231 @@
|
||||
//
|
||||
// ZFPortraitViewController.m
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "ZFPortraitViewController.h"
|
||||
#import "ZFPersentInteractiveTransition.h"
|
||||
#import "ZFPresentTransition.h"
|
||||
|
||||
@interface ZFPortraitViewController ()<UIViewControllerTransitioningDelegate,ZFPortraitOrientationDelegate>
|
||||
|
||||
@property (nonatomic, strong) ZFPresentTransition *transition;
|
||||
@property (nonatomic, strong) ZFPersentInteractiveTransition *interactiveTransition;
|
||||
@property (nonatomic, assign, getter=isFullScreen) BOOL fullScreen;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ZFPortraitViewController
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.transitioningDelegate = self;
|
||||
self.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
||||
self.modalPresentationCapturesStatusBarAppearance = YES;
|
||||
_statusBarStyle = UIStatusBarStyleLightContent;
|
||||
_statusBarAnimation = UIStatusBarAnimationSlide;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
self.view.backgroundColor = [UIColor blackColor];
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated {
|
||||
[super viewWillAppear:animated];
|
||||
if (!self.fullScreenAnimation) {
|
||||
if (self.orientationWillChange) {
|
||||
self.orientationWillChange(YES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated {
|
||||
[super viewDidAppear:animated];
|
||||
if (!self.fullScreenAnimation) {
|
||||
self.view.alpha = 1;
|
||||
[self.view addSubview:self.contentView];
|
||||
self.contentView.frame = [self contentFullScreenRect];
|
||||
if (self.orientationDidChanged) {
|
||||
self.orientationDidChanged(YES);
|
||||
}
|
||||
}
|
||||
self.fullScreen = YES;
|
||||
[self.interactiveTransition updateContentView:self.contentView
|
||||
containerView:self.containerView];
|
||||
}
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated {
|
||||
[super viewWillDisappear:animated];
|
||||
if (!self.fullScreenAnimation) {
|
||||
if (self.orientationWillChange) {
|
||||
self.orientationWillChange(NO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)viewDidDisappear:(BOOL)animated {
|
||||
[super viewDidDisappear:animated];
|
||||
self.fullScreen = NO;
|
||||
if (!self.fullScreenAnimation) {
|
||||
[self.containerView addSubview:self.contentView];
|
||||
self.contentView.frame = self.containerView.bounds;
|
||||
if (self.orientationDidChanged) {
|
||||
self.orientationDidChanged(NO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - transition delegate
|
||||
|
||||
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
|
||||
[self.transition transitionWithTransitionType:ZFPresentTransitionTypePresent contentView:self.contentView containerView:self.containerView];
|
||||
return self.transition;
|
||||
}
|
||||
|
||||
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
|
||||
[self.transition transitionWithTransitionType:ZFPresentTransitionTypeDismiss contentView:self.contentView containerView:self.containerView];
|
||||
return self.transition;
|
||||
}
|
||||
|
||||
- (id<UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id<UIViewControllerAnimatedTransitioning>)animator {
|
||||
return self.interactiveTransition.interation ? self.interactiveTransition : nil;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)shouldAutorotate {
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)prefersStatusBarHidden {
|
||||
return self.statusBarHidden;
|
||||
}
|
||||
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle {
|
||||
return self.statusBarStyle;
|
||||
}
|
||||
|
||||
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
|
||||
return self.statusBarAnimation;
|
||||
}
|
||||
|
||||
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
|
||||
return UIInterfaceOrientationMaskPortrait;
|
||||
}
|
||||
|
||||
#pragma mark - ZFPortraitOrientationDelegate
|
||||
|
||||
- (void)zf_orientationWillChange:(BOOL)isFullScreen {
|
||||
if (self.orientationWillChange) {
|
||||
self.orientationWillChange(isFullScreen);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)zf_orientationDidChanged:(BOOL)isFullScreen {
|
||||
if (self.orientationDidChanged) {
|
||||
self.orientationDidChanged(isFullScreen);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)zf_interationState:(BOOL)isDragging {
|
||||
self.transition.interation = isDragging;
|
||||
}
|
||||
|
||||
#pragma mark - getter
|
||||
|
||||
- (ZFPresentTransition *)transition {
|
||||
if (!_transition) {
|
||||
_transition = [[ZFPresentTransition alloc] init];
|
||||
_transition.contentFullScreenRect = [self contentFullScreenRect];
|
||||
_transition.delagate = self;
|
||||
}
|
||||
return _transition;
|
||||
}
|
||||
|
||||
- (ZFPersentInteractiveTransition *)interactiveTransition {
|
||||
if (!_interactiveTransition) {
|
||||
_interactiveTransition = [[ZFPersentInteractiveTransition alloc] init];
|
||||
_interactiveTransition.contentFullScreenRect = [self contentFullScreenRect];
|
||||
_interactiveTransition.viewController = self;
|
||||
_interactiveTransition.delagate = self;
|
||||
}
|
||||
return _interactiveTransition;;
|
||||
}
|
||||
|
||||
- (void)setDisablePortraitGestureTypes:(ZFDisablePortraitGestureTypes)disablePortraitGestureTypes {
|
||||
_disablePortraitGestureTypes = disablePortraitGestureTypes;
|
||||
self.interactiveTransition.disablePortraitGestureTypes = disablePortraitGestureTypes;
|
||||
}
|
||||
|
||||
- (void)setPresentationSize:(CGSize)presentationSize {
|
||||
_presentationSize = presentationSize;
|
||||
self.transition.contentFullScreenRect = [self contentFullScreenRect];
|
||||
self.interactiveTransition.contentFullScreenRect = [self contentFullScreenRect];
|
||||
if (!self.fullScreenAnimation && self.isFullScreen) {
|
||||
self.contentView.frame = [self contentFullScreenRect];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setFullScreen:(BOOL)fullScreen {
|
||||
_fullScreen = fullScreen;
|
||||
self.transition.fullScreen = fullScreen;
|
||||
}
|
||||
|
||||
- (void)setFullScreenAnimation:(BOOL)fullScreenAnimation {
|
||||
_fullScreenAnimation = fullScreenAnimation;
|
||||
self.interactiveTransition.fullScreenAnimation = fullScreenAnimation;
|
||||
}
|
||||
|
||||
- (void)setDuration:(NSTimeInterval)duration {
|
||||
_duration = duration;
|
||||
self.transition.duration = duration;
|
||||
}
|
||||
|
||||
- (CGRect)contentFullScreenRect {
|
||||
CGFloat videoWidth = self.presentationSize.width;
|
||||
CGFloat videoHeight = self.presentationSize.height;
|
||||
if (videoHeight == 0) {
|
||||
return CGRectZero;
|
||||
}
|
||||
CGSize fullScreenScaleSize = CGSizeZero;
|
||||
CGFloat screenScale = ZFPlayerScreenWidth/ZFPlayerScreenHeight;
|
||||
CGFloat videoScale = videoWidth/videoHeight;
|
||||
if (screenScale > videoScale) {
|
||||
CGFloat height = ZFPlayerScreenHeight;
|
||||
CGFloat width = height * videoScale;
|
||||
fullScreenScaleSize = CGSizeMake(width, height);
|
||||
} else {
|
||||
CGFloat width = ZFPlayerScreenWidth;
|
||||
CGFloat height = (CGFloat)(width / videoScale);
|
||||
fullScreenScaleSize = CGSizeMake(width, height);
|
||||
}
|
||||
|
||||
videoWidth = fullScreenScaleSize.width;
|
||||
videoHeight = fullScreenScaleSize.height;
|
||||
CGRect rect = CGRectMake((ZFPlayerScreenWidth - videoWidth) / 2.0, (ZFPlayerScreenHeight - videoHeight) / 2.0, videoWidth, videoHeight);
|
||||
return rect;
|
||||
}
|
||||
|
||||
@end
|
||||
49
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPresentTransition.h
generated
Normal file
49
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPresentTransition.h
generated
Normal file
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// ZFPresentTransition.h
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "ZFOrientationObserver.h"
|
||||
|
||||
typedef NS_ENUM(NSUInteger, ZFPresentTransitionType) {
|
||||
ZFPresentTransitionTypePresent,
|
||||
ZFPresentTransitionTypeDismiss,
|
||||
};
|
||||
|
||||
@interface ZFPresentTransition : NSObject<UIViewControllerAnimatedTransitioning>
|
||||
|
||||
@property (nonatomic, weak) id<ZFPortraitOrientationDelegate> delagate;
|
||||
|
||||
@property (nonatomic, assign) CGRect contentFullScreenRect;
|
||||
|
||||
@property (nonatomic, assign, getter=isFullScreen) BOOL fullScreen;
|
||||
|
||||
@property (nonatomic, assign) BOOL interation;
|
||||
|
||||
@property (nonatomic, assign) NSTimeInterval duration;
|
||||
|
||||
- (void)transitionWithTransitionType:(ZFPresentTransitionType)type
|
||||
contentView:(UIView *)contentView
|
||||
containerView:(UIView *)containerView;
|
||||
|
||||
@end
|
||||
156
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPresentTransition.m
generated
Normal file
156
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFPresentTransition.m
generated
Normal file
@@ -0,0 +1,156 @@
|
||||
//
|
||||
// ZFPresentTransition.m
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2020年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "ZFPresentTransition.h"
|
||||
#import "ZFPlayerConst.h"
|
||||
|
||||
@interface ZFPresentTransition ()
|
||||
|
||||
@property (nonatomic, strong) UIView *contentView;
|
||||
@property (nonatomic, assign) ZFPresentTransitionType type;
|
||||
@property (nonatomic, strong) UIView *containerView;
|
||||
@property (nonatomic, assign, getter=isTransiting) BOOL transiting;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ZFPresentTransition
|
||||
|
||||
- (void)transitionWithTransitionType:(ZFPresentTransitionType)type
|
||||
contentView:(UIView *)contentView
|
||||
containerView:(UIView *)containerView {
|
||||
|
||||
self.type = type;
|
||||
self.contentView = contentView;
|
||||
self.containerView = containerView;
|
||||
}
|
||||
|
||||
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
|
||||
return self.duration == 0 ? 0.25f : self.duration;
|
||||
}
|
||||
|
||||
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
|
||||
switch (self.type) {
|
||||
case ZFPresentTransitionTypePresent: {
|
||||
[self presentAnimation:transitionContext];
|
||||
}
|
||||
break;
|
||||
case ZFPresentTransitionTypeDismiss: {
|
||||
[self dismissAnimation:transitionContext];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)presentAnimation:(id<UIViewControllerContextTransitioning>)transitionContext {
|
||||
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
|
||||
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
|
||||
if ([fromVC isKindOfClass:[UINavigationController class]]) {
|
||||
UINavigationController *nav = (UINavigationController *)fromVC;
|
||||
fromVC = nav.viewControllers.lastObject;
|
||||
} else if ([fromVC isKindOfClass:[UITabBarController class]]) {
|
||||
UITabBarController *tabBar = (UITabBarController *)fromVC;
|
||||
if ([tabBar.selectedViewController isKindOfClass:[UINavigationController class]]) {
|
||||
UINavigationController *nav = (UINavigationController *)tabBar.selectedViewController;
|
||||
fromVC = nav.viewControllers.lastObject;
|
||||
} else {
|
||||
fromVC = tabBar.selectedViewController;
|
||||
}
|
||||
}
|
||||
UIView *containerView = [transitionContext containerView];
|
||||
[containerView addSubview:toVC.view];
|
||||
[containerView addSubview:self.contentView];
|
||||
CGRect originRect = [self.containerView convertRect:self.contentView.frame toView:toVC.view];
|
||||
self.contentView.frame = originRect;
|
||||
|
||||
UIColor *tempColor = toVC.view.backgroundColor;
|
||||
toVC.view.backgroundColor = [tempColor colorWithAlphaComponent:0];
|
||||
toVC.view.alpha = 1;
|
||||
[self.delagate zf_orientationWillChange:YES];
|
||||
|
||||
CGRect toRect = self.contentFullScreenRect;
|
||||
self.transiting = YES;
|
||||
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
|
||||
self.contentView.frame = toRect;
|
||||
[self.contentView layoutIfNeeded];
|
||||
toVC.view.backgroundColor = [tempColor colorWithAlphaComponent:1.f];
|
||||
} completion:^(BOOL finished) {
|
||||
self.transiting = NO;
|
||||
[toVC.view addSubview:self.contentView];
|
||||
[transitionContext completeTransition:YES];
|
||||
[self.delagate zf_orientationDidChanged:YES];
|
||||
if (!CGRectEqualToRect(toRect, self.contentFullScreenRect)) {
|
||||
self.contentView.frame = self.contentFullScreenRect;
|
||||
[self.contentView layoutIfNeeded];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)dismissAnimation:(id<UIViewControllerContextTransitioning>)transitionContext {
|
||||
UIView *containerView = [transitionContext containerView];
|
||||
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
|
||||
if ([toVC isKindOfClass:[UINavigationController class]]) {
|
||||
UINavigationController *nav = (UINavigationController *)toVC;
|
||||
toVC = nav.viewControllers.lastObject;
|
||||
} else if ([toVC isKindOfClass:[UITabBarController class]]) {
|
||||
UITabBarController *tabBar = (UITabBarController *)toVC;
|
||||
if ([tabBar.selectedViewController isKindOfClass:[UINavigationController class]]) {
|
||||
UINavigationController *nav = (UINavigationController *)tabBar.selectedViewController;
|
||||
toVC = nav.viewControllers.lastObject;
|
||||
} else {
|
||||
toVC = tabBar.selectedViewController;
|
||||
}
|
||||
}
|
||||
|
||||
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
|
||||
fromVC.view.frame = containerView.bounds;
|
||||
[containerView addSubview:fromVC.view];
|
||||
[containerView addSubview:self.contentView];
|
||||
|
||||
CGRect originRect = [fromVC.view convertRect:self.contentView.frame toView:toVC.view];
|
||||
self.contentView.frame = originRect;
|
||||
CGRect toRect = [self.containerView convertRect:self.containerView.bounds toView:toVC.view];
|
||||
[fromVC.view convertRect:self.contentView.bounds toView:self.containerView.window];
|
||||
[self.delagate zf_orientationWillChange:NO];
|
||||
self.transiting = YES;
|
||||
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
|
||||
fromVC.view.alpha = 0;
|
||||
self.contentView.frame = toRect;
|
||||
[self.contentView layoutIfNeeded];
|
||||
} completion:^(BOOL finished) {
|
||||
[self.containerView addSubview:self.contentView];
|
||||
self.contentView.frame = self.containerView.bounds;
|
||||
[transitionContext completeTransition:YES];
|
||||
[self.delagate zf_orientationDidChanged:NO];
|
||||
self.transiting = NO;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setContentFullScreenRect:(CGRect)contentFullScreenRect {
|
||||
_contentFullScreenRect = contentFullScreenRect;
|
||||
if (!self.transiting && self.isFullScreen && !self.interation) {
|
||||
self.contentView.frame = contentFullScreenRect;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
167
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFReachabilityManager.h
generated
Normal file
167
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFReachabilityManager.h
generated
Normal file
@@ -0,0 +1,167 @@
|
||||
//
|
||||
// ZFReachabilityManager.h
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#if !TARGET_OS_WATCH
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
|
||||
typedef NS_ENUM(NSInteger, ZFReachabilityStatus) {
|
||||
ZFReachabilityStatusUnknown = -1,
|
||||
ZFReachabilityStatusNotReachable = 0,
|
||||
ZFReachabilityStatusReachableViaWiFi = 1,
|
||||
ZFReachabilityStatusReachableVia2G = 2,
|
||||
ZFReachabilityStatusReachableVia3G = 3,
|
||||
ZFReachabilityStatusReachableVia4G = 4,
|
||||
};
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
`ZFReachabilityManager` monitors the reachability of domains, and addresses for both WWAN and WiFi network interfaces.
|
||||
|
||||
Reachability can be used to determine background information about why a network operation failed, or to trigger a network operation retrying when a connection is established. It should not be used to prevent a user from initiating a network request, as it's possible that an initial request may be required to establish reachability.
|
||||
|
||||
See Apple's Reachability Sample Code ( https://developer.apple.com/library/ios/samplecode/reachability/ )
|
||||
|
||||
@warning Instances of `AFNetworkReachabilityManager` must be started with `-startMonitoring` before reachability status can be determined.
|
||||
*/
|
||||
@interface ZFReachabilityManager : NSObject
|
||||
|
||||
/**
|
||||
The current network reachability status.
|
||||
*/
|
||||
@property (readonly, nonatomic, assign) ZFReachabilityStatus networkReachabilityStatus;
|
||||
|
||||
/**
|
||||
Whether or not the network is currently reachable.
|
||||
*/
|
||||
@property (readonly, nonatomic, assign, getter = isReachable) BOOL reachable;
|
||||
|
||||
/**
|
||||
Whether or not the network is currently reachable via WWAN.
|
||||
*/
|
||||
@property (readonly, nonatomic, assign, getter = isReachableViaWWAN) BOOL reachableViaWWAN;
|
||||
|
||||
/**
|
||||
Whether or not the network is currently reachable via WiFi.
|
||||
*/
|
||||
@property (readonly, nonatomic, assign, getter = isReachableViaWiFi) BOOL reachableViaWiFi;
|
||||
|
||||
///---------------------
|
||||
/// @name Initialization
|
||||
///---------------------
|
||||
|
||||
/**
|
||||
Returns the shared network reachability manager.
|
||||
*/
|
||||
+ (instancetype)sharedManager;
|
||||
|
||||
/**
|
||||
Creates and returns a network reachability manager with the default socket address.
|
||||
|
||||
@return An initialized network reachability manager, actively monitoring the default socket address.
|
||||
*/
|
||||
+ (instancetype)manager;
|
||||
|
||||
/**
|
||||
Creates and returns a network reachability manager for the specified domain.
|
||||
|
||||
@param domain The domain used to evaluate network reachability.
|
||||
|
||||
@return An initialized network reachability manager, actively monitoring the specified domain.
|
||||
*/
|
||||
+ (instancetype)managerForDomain:(NSString *)domain;
|
||||
|
||||
/**
|
||||
Creates and returns a network reachability manager for the socket address.
|
||||
|
||||
@param address The socket address (`sockaddr_in6`) used to evaluate network reachability.
|
||||
|
||||
@return An initialized network reachability manager, actively monitoring the specified socket address.
|
||||
*/
|
||||
+ (instancetype)managerForAddress:(const void *)address;
|
||||
|
||||
/**
|
||||
Initializes an instance of a network reachability manager from the specified reachability object.
|
||||
|
||||
@param reachability The reachability object to monitor.
|
||||
|
||||
@return An initialized network reachability manager, actively monitoring the specified reachability.
|
||||
*/
|
||||
- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
///--------------------------------------------------
|
||||
/// @name Starting & Stopping Reachability Monitoring
|
||||
///--------------------------------------------------
|
||||
|
||||
/**
|
||||
Starts monitoring for changes in network reachability status.
|
||||
*/
|
||||
- (void)startMonitoring;
|
||||
|
||||
/**
|
||||
Stops monitoring for changes in network reachability status.
|
||||
*/
|
||||
- (void)stopMonitoring;
|
||||
|
||||
///-------------------------------------------------
|
||||
/// @name Getting Localized Reachability Description
|
||||
///-------------------------------------------------
|
||||
|
||||
/**
|
||||
Returns a localized string representation of the current network reachability status.
|
||||
*/
|
||||
- (NSString *)localizedNetworkReachabilityStatusString;
|
||||
|
||||
///---------------------------------------------------
|
||||
/// @name Setting Network Reachability Change Callback
|
||||
///---------------------------------------------------
|
||||
|
||||
/**
|
||||
Sets a callback to be executed when the network availability of the `baseURL` host changes.
|
||||
|
||||
@param block A block object to be executed when the network availability of the `baseURL` host changes.. This block has no return value and takes a single argument which represents the various reachability states from the device to the `baseURL`.
|
||||
*/
|
||||
- (void)setReachabilityStatusChangeBlock:(nullable void (^)(ZFReachabilityStatus status))block;
|
||||
|
||||
@end
|
||||
|
||||
///--------------------
|
||||
/// @name Notifications
|
||||
///--------------------
|
||||
|
||||
FOUNDATION_EXPORT NSString * const ZFReachabilityDidChangeNotification;
|
||||
FOUNDATION_EXPORT NSString * const ZFReachabilityNotificationStatusItem;
|
||||
|
||||
///--------------------
|
||||
/// @name Functions
|
||||
///--------------------
|
||||
|
||||
/**
|
||||
Returns a localized string representation of an `ZFReachabilityStatus` value.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString * ZFStringFromNetworkReachabilityStatus(ZFReachabilityStatus status);
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
#endif
|
||||
269
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFReachabilityManager.m
generated
Normal file
269
Pods/DDZFPlayerKit_Private/DDZFPlayerKit_Private/Classes/Core/ZFReachabilityManager.m
generated
Normal file
@@ -0,0 +1,269 @@
|
||||
//
|
||||
// ZFReachabilityManager.m
|
||||
// ZFPlayer
|
||||
//
|
||||
// Copyright (c) 2016年 任子丰 ( http://github.com/renzifeng )
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "ZFReachabilityManager.h"
|
||||
#if !TARGET_OS_WATCH
|
||||
#import <netinet/in.h>
|
||||
#import <netinet6/in6.h>
|
||||
#import <arpa/inet.h>
|
||||
#import <ifaddrs.h>
|
||||
#import <netdb.h>
|
||||
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
|
||||
|
||||
NSString * const ZFReachabilityDidChangeNotification = @"com.ZFPlayer.reachability.change";
|
||||
NSString * const ZFReachabilityNotificationStatusItem = @"ZFNetworkingReachabilityNotificationStatusItem";
|
||||
|
||||
typedef void (^ZFReachabilityStatusBlock)(ZFReachabilityStatus status);
|
||||
|
||||
NSString * ZFStringFromNetworkReachabilityStatus(ZFReachabilityStatus status) {
|
||||
switch (status) {
|
||||
case ZFReachabilityStatusNotReachable:
|
||||
return NSLocalizedStringFromTable(@"Not Reachable", @"ZFPlayer", nil);
|
||||
case ZFReachabilityStatusReachableViaWiFi:
|
||||
return NSLocalizedStringFromTable(@"Reachable via WiFi", @"ZFPlayer", nil);
|
||||
case ZFReachabilityStatusReachableVia2G:
|
||||
return NSLocalizedStringFromTable(@"Reachable via 2G", @"ZFPlayer", nil);
|
||||
case ZFReachabilityStatusReachableVia3G:
|
||||
return NSLocalizedStringFromTable(@"Reachable via 3G", @"ZFPlayer", nil);
|
||||
case ZFReachabilityStatusReachableVia4G:
|
||||
return NSLocalizedStringFromTable(@"Reachable via 4G", @"ZFPlayer", nil);
|
||||
case ZFReachabilityStatusUnknown:
|
||||
default:
|
||||
return NSLocalizedStringFromTable(@"Unknown", @"ZFPlayer", nil);
|
||||
}
|
||||
}
|
||||
|
||||
static ZFReachabilityStatus ZFReachabilityStatusForFlags(SCNetworkReachabilityFlags flags) {
|
||||
BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0);
|
||||
BOOL needsConnection = ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0);
|
||||
BOOL canConnectionAutomatically = (((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) || ((flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0));
|
||||
BOOL canConnectWithoutUserInteraction = (canConnectionAutomatically && (flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0);
|
||||
BOOL isNetworkReachable = (isReachable && (!needsConnection || canConnectWithoutUserInteraction));
|
||||
|
||||
ZFReachabilityStatus status = ZFReachabilityStatusUnknown;
|
||||
if (isNetworkReachable == NO) {
|
||||
status = ZFReachabilityStatusNotReachable;
|
||||
}
|
||||
#if TARGET_OS_IPHONE
|
||||
else if ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0) {
|
||||
CTTelephonyNetworkInfo * info = [[CTTelephonyNetworkInfo alloc] init];
|
||||
NSString *currentRadioAccessTechnology = info.currentRadioAccessTechnology;
|
||||
if (currentRadioAccessTechnology) {
|
||||
if ([currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyLTE]) {
|
||||
status = ZFReachabilityStatusReachableVia4G;
|
||||
} else if ([currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyEdge] || [currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyGPRS]) {
|
||||
status = ZFReachabilityStatusReachableVia2G;
|
||||
} else {
|
||||
status = ZFReachabilityStatusReachableVia3G;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
status = ZFReachabilityStatusReachableViaWiFi;
|
||||
}
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue a status change notification for the main thread.
|
||||
*
|
||||
* This is done to ensure that the notifications are received in the same order
|
||||
* as they are sent. If notifications are sent directly, it is possible that
|
||||
* a queued notification (for an earlier status condition) is processed after
|
||||
* the later update, resulting in the listener being left in the wrong state.
|
||||
*/
|
||||
static void ZFPostReachabilityStatusChange(SCNetworkReachabilityFlags flags, ZFReachabilityStatusBlock block) {
|
||||
ZFReachabilityStatus status = ZFReachabilityStatusForFlags(flags);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (block) block(status);
|
||||
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
NSMutableDictionary *userInfo = @{}.mutableCopy;
|
||||
userInfo[ZFReachabilityNotificationStatusItem] = @(status);
|
||||
|
||||
[notificationCenter postNotificationName:ZFReachabilityDidChangeNotification object:nil userInfo:userInfo];
|
||||
});
|
||||
}
|
||||
|
||||
static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkReachabilityFlags flags, void *info) {
|
||||
ZFPostReachabilityStatusChange(flags, (__bridge ZFReachabilityStatusBlock)info);
|
||||
}
|
||||
|
||||
|
||||
static const void * ZFReachabilityRetainCallback(const void *info) {
|
||||
return Block_copy(info);
|
||||
}
|
||||
|
||||
static void ZFReachabilityReleaseCallback(const void *info) {
|
||||
if (info) {
|
||||
Block_release(info);
|
||||
}
|
||||
}
|
||||
|
||||
@interface ZFReachabilityManager ()
|
||||
|
||||
@property (readonly, nonatomic, assign) SCNetworkReachabilityRef networkReachability;
|
||||
@property (readwrite, nonatomic, assign) ZFReachabilityStatus networkReachabilityStatus;
|
||||
@property (readwrite, nonatomic, copy) ZFReachabilityStatusBlock networkReachabilityStatusBlock;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ZFReachabilityManager
|
||||
|
||||
+ (instancetype)sharedManager {
|
||||
static ZFReachabilityManager *_sharedManager = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_sharedManager = [self manager];
|
||||
});
|
||||
return _sharedManager;
|
||||
}
|
||||
|
||||
+ (instancetype)managerForDomain:(NSString *)domain {
|
||||
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [domain UTF8String]);
|
||||
ZFReachabilityManager *manager = [[self alloc] initWithReachability:reachability];
|
||||
CFRelease(reachability);
|
||||
return manager;
|
||||
}
|
||||
|
||||
+ (instancetype)managerForAddress:(const void *)address {
|
||||
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)address);
|
||||
ZFReachabilityManager *manager = [[self alloc] initWithReachability:reachability];
|
||||
CFRelease(reachability);
|
||||
return manager;
|
||||
}
|
||||
|
||||
+ (instancetype)manager {
|
||||
#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 90000) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)
|
||||
struct sockaddr_in6 address;
|
||||
bzero(&address, sizeof(address));
|
||||
address.sin6_len = sizeof(address);
|
||||
address.sin6_family = AF_INET6;
|
||||
#else
|
||||
struct sockaddr_in address;
|
||||
bzero(&address, sizeof(address));
|
||||
address.sin_len = sizeof(address);
|
||||
address.sin_family = AF_INET;
|
||||
#endif
|
||||
return [self managerForAddress:&address];
|
||||
}
|
||||
|
||||
- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability {
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
_networkReachability = CFRetain(reachability);
|
||||
self.networkReachabilityStatus = ZFReachabilityStatusUnknown;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[self stopMonitoring];
|
||||
if (_networkReachability != NULL) {
|
||||
CFRelease(_networkReachability);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (BOOL)isReachable {
|
||||
return [self isReachableViaWWAN] || [self isReachableViaWiFi];
|
||||
}
|
||||
|
||||
- (BOOL)isReachableViaWWAN {
|
||||
return (self.networkReachabilityStatus == ZFReachabilityStatusReachableVia2G ||self.networkReachabilityStatus == ZFReachabilityStatusReachableVia3G || self.networkReachabilityStatus == ZFReachabilityStatusReachableVia4G);
|
||||
}
|
||||
|
||||
- (BOOL)isReachableViaWiFi {
|
||||
return self.networkReachabilityStatus == ZFReachabilityStatusReachableViaWiFi;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)startMonitoring {
|
||||
[self stopMonitoring];
|
||||
if (!self.networkReachability) {
|
||||
return;
|
||||
}
|
||||
|
||||
__weak __typeof(self)weakSelf = self;
|
||||
ZFReachabilityStatusBlock callback = ^(ZFReachabilityStatus status) {
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
strongSelf.networkReachabilityStatus = status;
|
||||
if (strongSelf.networkReachabilityStatusBlock) {
|
||||
strongSelf.networkReachabilityStatusBlock(status);
|
||||
}
|
||||
};
|
||||
|
||||
SCNetworkReachabilityContext context = {0, (__bridge void *)callback, ZFReachabilityRetainCallback, ZFReachabilityReleaseCallback, NULL};
|
||||
SCNetworkReachabilitySetCallback(self.networkReachability, AFNetworkReachabilityCallback, &context);
|
||||
SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
|
||||
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{
|
||||
SCNetworkReachabilityFlags flags;
|
||||
if (SCNetworkReachabilityGetFlags(self.networkReachability, &flags)) {
|
||||
ZFPostReachabilityStatusChange(flags, callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)stopMonitoring {
|
||||
if (!self.networkReachability) {
|
||||
return;
|
||||
}
|
||||
|
||||
SCNetworkReachabilityUnscheduleFromRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSString *)localizedNetworkReachabilityStatusString {
|
||||
return ZFStringFromNetworkReachabilityStatus(self.networkReachabilityStatus);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)setReachabilityStatusChangeBlock:(void (^)(ZFReachabilityStatus status))block {
|
||||
self.networkReachabilityStatusBlock = block;
|
||||
}
|
||||
|
||||
#pragma mark - NSKeyValueObserving
|
||||
|
||||
+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key {
|
||||
if ([key isEqualToString:@"reachable"] || [key isEqualToString:@"reachableViaWWAN"] || [key isEqualToString:@"reachableViaWiFi"]) {
|
||||
return [NSSet setWithObject:@"networkReachabilityStatus"];
|
||||
}
|
||||
return [super keyPathsForValuesAffectingValueForKey:key];
|
||||
}
|
||||
|
||||
@end
|
||||
#endif
|
||||
Reference in New Issue
Block a user