提交
This commit is contained in:
parent
4326de86e5
commit
1989abab7f
@ -111,6 +111,35 @@
|
|||||||
91C871412C13111B0093790D /* HBHomeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871402C13111B0093790D /* HBHomeViewController.m */; };
|
91C871412C13111B0093790D /* HBHomeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871402C13111B0093790D /* HBHomeViewController.m */; };
|
||||||
91C871442C13112F0093790D /* HBDiscoverViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871432C13112F0093790D /* HBDiscoverViewController.m */; };
|
91C871442C13112F0093790D /* HBDiscoverViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871432C13112F0093790D /* HBDiscoverViewController.m */; };
|
||||||
91C871472C1311450093790D /* HBMineViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871462C1311450093790D /* HBMineViewController.m */; };
|
91C871472C1311450093790D /* HBMineViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871462C1311450093790D /* HBMineViewController.m */; };
|
||||||
|
91C8718E2C1314770093790D /* UIButton+GKEnlarge.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871492C1314770093790D /* UIButton+GKEnlarge.m */; };
|
||||||
|
91C8718F2C1314770093790D /* GKDoubleLikeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C8714C2C1314770093790D /* GKDoubleLikeView.m */; };
|
||||||
|
91C871902C1314770093790D /* GKLikeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C8714E2C1314770093790D /* GKLikeView.m */; };
|
||||||
|
91C871912C1314770093790D /* GKBallLoadingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871512C1314770093790D /* GKBallLoadingView.m */; };
|
||||||
|
91C871922C1314770093790D /* GKLandscapeNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871542C1314770093790D /* GKLandscapeNavigationController.m */; };
|
||||||
|
91C871932C1314770093790D /* GKLandscapeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871562C1314770093790D /* GKLandscapeViewController.m */; };
|
||||||
|
91C871942C1314770093790D /* GKLandscapeWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871582C1314770093790D /* GKLandscapeWindow.m */; };
|
||||||
|
91C871952C1314770093790D /* GKRotationManager_iOS_9_15.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C8715A2C1314770093790D /* GKRotationManager_iOS_9_15.m */; };
|
||||||
|
91C871962C1314770093790D /* GKRotationManager_iOS_16_Later.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C8715C2C1314770093790D /* GKRotationManager_iOS_16_Later.m */; };
|
||||||
|
91C871972C1314770093790D /* GKRotationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C8715E2C1314770093790D /* GKRotationManager.m */; };
|
||||||
|
91C871992C1314770093790D /* GKDYPlayerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871652C1314770093790D /* GKDYPlayerManager.m */; };
|
||||||
|
91C8719A2C1314770093790D /* GKDUVideoInfoModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871682C1314770093790D /* GKDUVideoInfoModel.m */; };
|
||||||
|
91C8719B2C1314770093790D /* GKDYVideoModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C8716A2C1314770093790D /* GKDYVideoModel.m */; };
|
||||||
|
91C8719C2C1314770093790D /* GKDYPanGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C8716D2C1314770093790D /* GKDYPanGestureRecognizer.m */; };
|
||||||
|
91C8719D2C1314770093790D /* GKDYScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C8716F2C1314770093790D /* GKDYScrollView.m */; };
|
||||||
|
91C8719E2C1314770093790D /* GKDYTitleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871712C1314770093790D /* GKDYTitleView.m */; };
|
||||||
|
91C8719F2C1314770093790D /* GKDYVideoCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871732C1314770093790D /* GKDYVideoCell.m */; };
|
||||||
|
91C871A02C1314770093790D /* GKDYVideoControlView.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871752C1314770093790D /* GKDYVideoControlView.m */; };
|
||||||
|
91C871A12C1314770093790D /* GKDYVideoFullscreenView.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871772C1314770093790D /* GKDYVideoFullscreenView.m */; };
|
||||||
|
91C871A22C1314770093790D /* GKDYVideoItemButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871792C1314770093790D /* GKDYVideoItemButton.m */; };
|
||||||
|
91C871A32C1314770093790D /* GKDYVideoLandscapeCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C8717B2C1314770093790D /* GKDYVideoLandscapeCell.m */; };
|
||||||
|
91C871A42C1314770093790D /* GKDYVideoLandscapeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C8717D2C1314770093790D /* GKDYVideoLandscapeView.m */; };
|
||||||
|
91C871A52C1314770093790D /* GKDYVideoMaskView.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C8717F2C1314770093790D /* GKDYVideoMaskView.m */; };
|
||||||
|
91C871A62C1314770093790D /* GKDYVideoPortraitCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871812C1314770093790D /* GKDYVideoPortraitCell.m */; };
|
||||||
|
91C871A72C1314770093790D /* GKDYVideoPortraitView.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871832C1314770093790D /* GKDYVideoPortraitView.m */; };
|
||||||
|
91C871A82C1314770093790D /* GKDYVideoPreviewView.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871852C1314770093790D /* GKDYVideoPreviewView.m */; };
|
||||||
|
91C871A92C1314770093790D /* GKDYVideoScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871872C1314770093790D /* GKDYVideoScrollView.m */; };
|
||||||
|
91C871AA2C1314770093790D /* GKDYVideoSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C871892C1314770093790D /* GKDYVideoSlider.m */; };
|
||||||
|
91C871AB2C1314770093790D /* GKDYVideoStatusBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C8718B2C1314770093790D /* GKDYVideoStatusBar.m */; };
|
||||||
C8AC2283D47E2B99FF559E75 /* libPods-HiBit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 141F02EF5C0783797594009A /* libPods-HiBit.a */; };
|
C8AC2283D47E2B99FF559E75 /* libPods-HiBit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 141F02EF5C0783797594009A /* libPods-HiBit.a */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
@ -327,6 +356,64 @@
|
|||||||
91C871432C13112F0093790D /* HBDiscoverViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HBDiscoverViewController.m; sourceTree = "<group>"; };
|
91C871432C13112F0093790D /* HBDiscoverViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HBDiscoverViewController.m; sourceTree = "<group>"; };
|
||||||
91C871452C1311450093790D /* HBMineViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HBMineViewController.h; sourceTree = "<group>"; };
|
91C871452C1311450093790D /* HBMineViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HBMineViewController.h; sourceTree = "<group>"; };
|
||||||
91C871462C1311450093790D /* HBMineViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HBMineViewController.m; sourceTree = "<group>"; };
|
91C871462C1311450093790D /* HBMineViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HBMineViewController.m; sourceTree = "<group>"; };
|
||||||
|
91C871482C1314770093790D /* UIButton+GKEnlarge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIButton+GKEnlarge.h"; sourceTree = "<group>"; };
|
||||||
|
91C871492C1314770093790D /* UIButton+GKEnlarge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIButton+GKEnlarge.m"; sourceTree = "<group>"; };
|
||||||
|
91C8714B2C1314770093790D /* GKDoubleLikeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDoubleLikeView.h; sourceTree = "<group>"; };
|
||||||
|
91C8714C2C1314770093790D /* GKDoubleLikeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDoubleLikeView.m; sourceTree = "<group>"; };
|
||||||
|
91C8714D2C1314770093790D /* GKLikeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKLikeView.h; sourceTree = "<group>"; };
|
||||||
|
91C8714E2C1314770093790D /* GKLikeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKLikeView.m; sourceTree = "<group>"; };
|
||||||
|
91C871502C1314770093790D /* GKBallLoadingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKBallLoadingView.h; sourceTree = "<group>"; };
|
||||||
|
91C871512C1314770093790D /* GKBallLoadingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKBallLoadingView.m; sourceTree = "<group>"; };
|
||||||
|
91C871532C1314770093790D /* GKLandscapeNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKLandscapeNavigationController.h; sourceTree = "<group>"; };
|
||||||
|
91C871542C1314770093790D /* GKLandscapeNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKLandscapeNavigationController.m; sourceTree = "<group>"; };
|
||||||
|
91C871552C1314770093790D /* GKLandscapeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKLandscapeViewController.h; sourceTree = "<group>"; };
|
||||||
|
91C871562C1314770093790D /* GKLandscapeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKLandscapeViewController.m; sourceTree = "<group>"; };
|
||||||
|
91C871572C1314770093790D /* GKLandscapeWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKLandscapeWindow.h; sourceTree = "<group>"; };
|
||||||
|
91C871582C1314770093790D /* GKLandscapeWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKLandscapeWindow.m; sourceTree = "<group>"; };
|
||||||
|
91C871592C1314770093790D /* GKRotationManager_iOS_9_15.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKRotationManager_iOS_9_15.h; sourceTree = "<group>"; };
|
||||||
|
91C8715A2C1314770093790D /* GKRotationManager_iOS_9_15.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKRotationManager_iOS_9_15.m; sourceTree = "<group>"; };
|
||||||
|
91C8715B2C1314770093790D /* GKRotationManager_iOS_16_Later.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKRotationManager_iOS_16_Later.h; sourceTree = "<group>"; };
|
||||||
|
91C8715C2C1314770093790D /* GKRotationManager_iOS_16_Later.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKRotationManager_iOS_16_Later.m; sourceTree = "<group>"; };
|
||||||
|
91C8715D2C1314770093790D /* GKRotationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKRotationManager.h; sourceTree = "<group>"; };
|
||||||
|
91C8715E2C1314770093790D /* GKRotationManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKRotationManager.m; sourceTree = "<group>"; };
|
||||||
|
91C871642C1314770093790D /* GKDYPlayerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDYPlayerManager.h; sourceTree = "<group>"; };
|
||||||
|
91C871652C1314770093790D /* GKDYPlayerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDYPlayerManager.m; sourceTree = "<group>"; };
|
||||||
|
91C871672C1314770093790D /* GKDUVideoInfoModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDUVideoInfoModel.h; sourceTree = "<group>"; };
|
||||||
|
91C871682C1314770093790D /* GKDUVideoInfoModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDUVideoInfoModel.m; sourceTree = "<group>"; };
|
||||||
|
91C871692C1314770093790D /* GKDYVideoModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDYVideoModel.h; sourceTree = "<group>"; };
|
||||||
|
91C8716A2C1314770093790D /* GKDYVideoModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDYVideoModel.m; sourceTree = "<group>"; };
|
||||||
|
91C8716C2C1314770093790D /* GKDYPanGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDYPanGestureRecognizer.h; sourceTree = "<group>"; };
|
||||||
|
91C8716D2C1314770093790D /* GKDYPanGestureRecognizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDYPanGestureRecognizer.m; sourceTree = "<group>"; };
|
||||||
|
91C8716E2C1314770093790D /* GKDYScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDYScrollView.h; sourceTree = "<group>"; };
|
||||||
|
91C8716F2C1314770093790D /* GKDYScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDYScrollView.m; sourceTree = "<group>"; };
|
||||||
|
91C871702C1314770093790D /* GKDYTitleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDYTitleView.h; sourceTree = "<group>"; };
|
||||||
|
91C871712C1314770093790D /* GKDYTitleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDYTitleView.m; sourceTree = "<group>"; };
|
||||||
|
91C871722C1314770093790D /* GKDYVideoCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDYVideoCell.h; sourceTree = "<group>"; };
|
||||||
|
91C871732C1314770093790D /* GKDYVideoCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDYVideoCell.m; sourceTree = "<group>"; };
|
||||||
|
91C871742C1314770093790D /* GKDYVideoControlView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDYVideoControlView.h; sourceTree = "<group>"; };
|
||||||
|
91C871752C1314770093790D /* GKDYVideoControlView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDYVideoControlView.m; sourceTree = "<group>"; };
|
||||||
|
91C871762C1314770093790D /* GKDYVideoFullscreenView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDYVideoFullscreenView.h; sourceTree = "<group>"; };
|
||||||
|
91C871772C1314770093790D /* GKDYVideoFullscreenView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDYVideoFullscreenView.m; sourceTree = "<group>"; };
|
||||||
|
91C871782C1314770093790D /* GKDYVideoItemButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDYVideoItemButton.h; sourceTree = "<group>"; };
|
||||||
|
91C871792C1314770093790D /* GKDYVideoItemButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDYVideoItemButton.m; sourceTree = "<group>"; };
|
||||||
|
91C8717A2C1314770093790D /* GKDYVideoLandscapeCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDYVideoLandscapeCell.h; sourceTree = "<group>"; };
|
||||||
|
91C8717B2C1314770093790D /* GKDYVideoLandscapeCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDYVideoLandscapeCell.m; sourceTree = "<group>"; };
|
||||||
|
91C8717C2C1314770093790D /* GKDYVideoLandscapeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDYVideoLandscapeView.h; sourceTree = "<group>"; };
|
||||||
|
91C8717D2C1314770093790D /* GKDYVideoLandscapeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDYVideoLandscapeView.m; sourceTree = "<group>"; };
|
||||||
|
91C8717E2C1314770093790D /* GKDYVideoMaskView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDYVideoMaskView.h; sourceTree = "<group>"; };
|
||||||
|
91C8717F2C1314770093790D /* GKDYVideoMaskView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDYVideoMaskView.m; sourceTree = "<group>"; };
|
||||||
|
91C871802C1314770093790D /* GKDYVideoPortraitCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDYVideoPortraitCell.h; sourceTree = "<group>"; };
|
||||||
|
91C871812C1314770093790D /* GKDYVideoPortraitCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDYVideoPortraitCell.m; sourceTree = "<group>"; };
|
||||||
|
91C871822C1314770093790D /* GKDYVideoPortraitView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDYVideoPortraitView.h; sourceTree = "<group>"; };
|
||||||
|
91C871832C1314770093790D /* GKDYVideoPortraitView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDYVideoPortraitView.m; sourceTree = "<group>"; };
|
||||||
|
91C871842C1314770093790D /* GKDYVideoPreviewView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDYVideoPreviewView.h; sourceTree = "<group>"; };
|
||||||
|
91C871852C1314770093790D /* GKDYVideoPreviewView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDYVideoPreviewView.m; sourceTree = "<group>"; };
|
||||||
|
91C871862C1314770093790D /* GKDYVideoScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDYVideoScrollView.h; sourceTree = "<group>"; };
|
||||||
|
91C871872C1314770093790D /* GKDYVideoScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDYVideoScrollView.m; sourceTree = "<group>"; };
|
||||||
|
91C871882C1314770093790D /* GKDYVideoSlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDYVideoSlider.h; sourceTree = "<group>"; };
|
||||||
|
91C871892C1314770093790D /* GKDYVideoSlider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDYVideoSlider.m; sourceTree = "<group>"; };
|
||||||
|
91C8718A2C1314770093790D /* GKDYVideoStatusBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKDYVideoStatusBar.h; sourceTree = "<group>"; };
|
||||||
|
91C8718B2C1314770093790D /* GKDYVideoStatusBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKDYVideoStatusBar.m; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@ -782,6 +869,7 @@
|
|||||||
916353402C12C10100593047 /* Project */ = {
|
916353402C12C10100593047 /* Project */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
91C8718D2C1314770093790D /* Player */,
|
||||||
916353852C12C20B00593047 /* Publics */,
|
916353852C12C20B00593047 /* Publics */,
|
||||||
9163533F2C12C01E00593047 /* Services */,
|
9163533F2C12C01E00593047 /* Services */,
|
||||||
91C871362C13108E0093790D /* Login */,
|
91C871362C13108E0093790D /* Login */,
|
||||||
@ -1039,6 +1127,135 @@
|
|||||||
path = Views;
|
path = Views;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
91C8714A2C1314770093790D /* Category */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
91C871482C1314770093790D /* UIButton+GKEnlarge.h */,
|
||||||
|
91C871492C1314770093790D /* UIButton+GKEnlarge.m */,
|
||||||
|
);
|
||||||
|
path = Category;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
91C8714F2C1314770093790D /* GKLikeView */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
91C8714B2C1314770093790D /* GKDoubleLikeView.h */,
|
||||||
|
91C8714C2C1314770093790D /* GKDoubleLikeView.m */,
|
||||||
|
91C8714D2C1314770093790D /* GKLikeView.h */,
|
||||||
|
91C8714E2C1314770093790D /* GKLikeView.m */,
|
||||||
|
);
|
||||||
|
path = GKLikeView;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
91C871522C1314770093790D /* GKLoadingView */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
91C871502C1314770093790D /* GKBallLoadingView.h */,
|
||||||
|
91C871512C1314770093790D /* GKBallLoadingView.m */,
|
||||||
|
);
|
||||||
|
path = GKLoadingView;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
91C8715F2C1314770093790D /* GKRotationManager */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
91C871532C1314770093790D /* GKLandscapeNavigationController.h */,
|
||||||
|
91C871542C1314770093790D /* GKLandscapeNavigationController.m */,
|
||||||
|
91C871552C1314770093790D /* GKLandscapeViewController.h */,
|
||||||
|
91C871562C1314770093790D /* GKLandscapeViewController.m */,
|
||||||
|
91C871572C1314770093790D /* GKLandscapeWindow.h */,
|
||||||
|
91C871582C1314770093790D /* GKLandscapeWindow.m */,
|
||||||
|
91C871592C1314770093790D /* GKRotationManager_iOS_9_15.h */,
|
||||||
|
91C8715A2C1314770093790D /* GKRotationManager_iOS_9_15.m */,
|
||||||
|
91C8715B2C1314770093790D /* GKRotationManager_iOS_16_Later.h */,
|
||||||
|
91C8715C2C1314770093790D /* GKRotationManager_iOS_16_Later.m */,
|
||||||
|
91C8715D2C1314770093790D /* GKRotationManager.h */,
|
||||||
|
91C8715E2C1314770093790D /* GKRotationManager.m */,
|
||||||
|
);
|
||||||
|
path = GKRotationManager;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
91C871602C1314770093790D /* Common */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
91C8714A2C1314770093790D /* Category */,
|
||||||
|
91C8714F2C1314770093790D /* GKLikeView */,
|
||||||
|
91C871522C1314770093790D /* GKLoadingView */,
|
||||||
|
91C8715F2C1314770093790D /* GKRotationManager */,
|
||||||
|
);
|
||||||
|
path = Common;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
91C871662C1314770093790D /* Manager */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
91C871642C1314770093790D /* GKDYPlayerManager.h */,
|
||||||
|
91C871652C1314770093790D /* GKDYPlayerManager.m */,
|
||||||
|
);
|
||||||
|
path = Manager;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
91C8716B2C1314770093790D /* Model */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
91C871672C1314770093790D /* GKDUVideoInfoModel.h */,
|
||||||
|
91C871682C1314770093790D /* GKDUVideoInfoModel.m */,
|
||||||
|
91C871692C1314770093790D /* GKDYVideoModel.h */,
|
||||||
|
91C8716A2C1314770093790D /* GKDYVideoModel.m */,
|
||||||
|
);
|
||||||
|
path = Model;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
91C8718C2C1314770093790D /* View */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
91C8716C2C1314770093790D /* GKDYPanGestureRecognizer.h */,
|
||||||
|
91C8716D2C1314770093790D /* GKDYPanGestureRecognizer.m */,
|
||||||
|
91C8716E2C1314770093790D /* GKDYScrollView.h */,
|
||||||
|
91C8716F2C1314770093790D /* GKDYScrollView.m */,
|
||||||
|
91C871702C1314770093790D /* GKDYTitleView.h */,
|
||||||
|
91C871712C1314770093790D /* GKDYTitleView.m */,
|
||||||
|
91C871722C1314770093790D /* GKDYVideoCell.h */,
|
||||||
|
91C871732C1314770093790D /* GKDYVideoCell.m */,
|
||||||
|
91C871742C1314770093790D /* GKDYVideoControlView.h */,
|
||||||
|
91C871752C1314770093790D /* GKDYVideoControlView.m */,
|
||||||
|
91C871762C1314770093790D /* GKDYVideoFullscreenView.h */,
|
||||||
|
91C871772C1314770093790D /* GKDYVideoFullscreenView.m */,
|
||||||
|
91C871782C1314770093790D /* GKDYVideoItemButton.h */,
|
||||||
|
91C871792C1314770093790D /* GKDYVideoItemButton.m */,
|
||||||
|
91C8717A2C1314770093790D /* GKDYVideoLandscapeCell.h */,
|
||||||
|
91C8717B2C1314770093790D /* GKDYVideoLandscapeCell.m */,
|
||||||
|
91C8717C2C1314770093790D /* GKDYVideoLandscapeView.h */,
|
||||||
|
91C8717D2C1314770093790D /* GKDYVideoLandscapeView.m */,
|
||||||
|
91C8717E2C1314770093790D /* GKDYVideoMaskView.h */,
|
||||||
|
91C8717F2C1314770093790D /* GKDYVideoMaskView.m */,
|
||||||
|
91C871802C1314770093790D /* GKDYVideoPortraitCell.h */,
|
||||||
|
91C871812C1314770093790D /* GKDYVideoPortraitCell.m */,
|
||||||
|
91C871822C1314770093790D /* GKDYVideoPortraitView.h */,
|
||||||
|
91C871832C1314770093790D /* GKDYVideoPortraitView.m */,
|
||||||
|
91C871842C1314770093790D /* GKDYVideoPreviewView.h */,
|
||||||
|
91C871852C1314770093790D /* GKDYVideoPreviewView.m */,
|
||||||
|
91C871862C1314770093790D /* GKDYVideoScrollView.h */,
|
||||||
|
91C871872C1314770093790D /* GKDYVideoScrollView.m */,
|
||||||
|
91C871882C1314770093790D /* GKDYVideoSlider.h */,
|
||||||
|
91C871892C1314770093790D /* GKDYVideoSlider.m */,
|
||||||
|
91C8718A2C1314770093790D /* GKDYVideoStatusBar.h */,
|
||||||
|
91C8718B2C1314770093790D /* GKDYVideoStatusBar.m */,
|
||||||
|
);
|
||||||
|
path = View;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
91C8718D2C1314770093790D /* Player */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
91C871602C1314770093790D /* Common */,
|
||||||
|
91C871662C1314770093790D /* Manager */,
|
||||||
|
91C8716B2C1314770093790D /* Model */,
|
||||||
|
91C8718C2C1314770093790D /* View */,
|
||||||
|
);
|
||||||
|
path = Player;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
B36329ED094310C499FEBA2F /* Frameworks */ = {
|
B36329ED094310C499FEBA2F /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -1184,28 +1401,43 @@
|
|||||||
files = (
|
files = (
|
||||||
916353892C12C20B00593047 /* HBNavigationController.m in Sources */,
|
916353892C12C20B00593047 /* HBNavigationController.m in Sources */,
|
||||||
916353002C12B6D400593047 /* NSUserDefaults+Extesion.m in Sources */,
|
916353002C12B6D400593047 /* NSUserDefaults+Extesion.m in Sources */,
|
||||||
|
91C871A12C1314770093790D /* GKDYVideoFullscreenView.m in Sources */,
|
||||||
|
91C871A92C1314770093790D /* GKDYVideoScrollView.m in Sources */,
|
||||||
916351402C12B12F00593047 /* AppDelegate.m in Sources */,
|
916351402C12B12F00593047 /* AppDelegate.m in Sources */,
|
||||||
|
91C871A72C1314770093790D /* GKDYVideoPortraitView.m in Sources */,
|
||||||
9163530D2C12B6D400593047 /* UINavigationController+Transparent.m in Sources */,
|
9163530D2C12B6D400593047 /* UINavigationController+Transparent.m in Sources */,
|
||||||
916352FA2C12B6D400593047 /* NSNumber+Extension.m in Sources */,
|
916352FA2C12B6D400593047 /* NSNumber+Extension.m in Sources */,
|
||||||
9163534D2C12C15300593047 /* HBNetWorkingUtilityResult.m in Sources */,
|
9163534D2C12C15300593047 /* HBNetWorkingUtilityResult.m in Sources */,
|
||||||
916353292C12B6D400593047 /* DGActivityIndicatorLineScalePulseOutRapidAnimation.m in Sources */,
|
916353292C12B6D400593047 /* DGActivityIndicatorLineScalePulseOutRapidAnimation.m in Sources */,
|
||||||
916353A22C12C3DC00593047 /* HtyoNetWorking.m in Sources */,
|
916353A22C12C3DC00593047 /* HtyoNetWorking.m in Sources */,
|
||||||
|
91C871992C1314770093790D /* GKDYPlayerManager.m in Sources */,
|
||||||
916353232C12B6D400593047 /* DGActivityIndicatorCookieTerminatorAnimation.m in Sources */,
|
916353232C12B6D400593047 /* DGActivityIndicatorCookieTerminatorAnimation.m in Sources */,
|
||||||
|
91C871A42C1314770093790D /* GKDYVideoLandscapeView.m in Sources */,
|
||||||
91C871412C13111B0093790D /* HBHomeViewController.m in Sources */,
|
91C871412C13111B0093790D /* HBHomeViewController.m in Sources */,
|
||||||
|
91C871A62C1314770093790D /* GKDYVideoPortraitCell.m in Sources */,
|
||||||
|
91C8718F2C1314770093790D /* GKDoubleLikeView.m in Sources */,
|
||||||
9163530A2C12B6D400593047 /* NSLayoutConstraint+BSIBDesignable.m in Sources */,
|
9163530A2C12B6D400593047 /* NSLayoutConstraint+BSIBDesignable.m in Sources */,
|
||||||
9163534C2C12C15300593047 /* HBNetWorkingUtility.m in Sources */,
|
9163534C2C12C15300593047 /* HBNetWorkingUtility.m in Sources */,
|
||||||
|
91C8719A2C1314770093790D /* GKDUVideoInfoModel.m in Sources */,
|
||||||
916353352C12B6D400593047 /* SVIndefiniteAnimatedView.m in Sources */,
|
916353352C12B6D400593047 /* SVIndefiniteAnimatedView.m in Sources */,
|
||||||
916353332C12B6D400593047 /* DGActivityIndicatorView.m in Sources */,
|
916353332C12B6D400593047 /* DGActivityIndicatorView.m in Sources */,
|
||||||
916353152C12B6D400593047 /* DGActivityIndicatorBallClipRotatePulseAnimation.m in Sources */,
|
916353152C12B6D400593047 /* DGActivityIndicatorBallClipRotatePulseAnimation.m in Sources */,
|
||||||
|
91C8719E2C1314770093790D /* GKDYTitleView.m in Sources */,
|
||||||
916353132C12B6D400593047 /* DGActivityIndicatorBallClipRotateAnimation.m in Sources */,
|
916353132C12B6D400593047 /* DGActivityIndicatorBallClipRotateAnimation.m in Sources */,
|
||||||
|
91C871952C1314770093790D /* GKRotationManager_iOS_9_15.m in Sources */,
|
||||||
916353322C12B6D400593047 /* DGActivityIndicatorTwoDotsAnimation.m in Sources */,
|
916353322C12B6D400593047 /* DGActivityIndicatorTwoDotsAnimation.m in Sources */,
|
||||||
916353862C12C20B00593047 /* HBColor.m in Sources */,
|
916353862C12C20B00593047 /* HBColor.m in Sources */,
|
||||||
9163532B2C12B6D400593047 /* DGActivityIndicatorRotatingSandglassAnimation.m in Sources */,
|
9163532B2C12B6D400593047 /* DGActivityIndicatorRotatingSandglassAnimation.m in Sources */,
|
||||||
|
91C871912C1314770093790D /* GKBallLoadingView.m in Sources */,
|
||||||
9163530E2C12B6D400593047 /* UIViewController+present.m in Sources */,
|
9163530E2C12B6D400593047 /* UIViewController+present.m in Sources */,
|
||||||
916353212C12B6D400593047 /* DGActivityIndicatorBallZigZagAnimation.m in Sources */,
|
916353212C12B6D400593047 /* DGActivityIndicatorBallZigZagAnimation.m in Sources */,
|
||||||
|
91C871942C1314770093790D /* GKLandscapeWindow.m in Sources */,
|
||||||
|
91C871922C1314770093790D /* GKLandscapeNavigationController.m in Sources */,
|
||||||
916353262C12B6D400593047 /* DGActivityIndicatorLineScaleAnimation.m in Sources */,
|
916353262C12B6D400593047 /* DGActivityIndicatorLineScaleAnimation.m in Sources */,
|
||||||
916353272C12B6D400593047 /* DGActivityIndicatorLineScalePartyAnimation.m in Sources */,
|
916353272C12B6D400593047 /* DGActivityIndicatorLineScalePartyAnimation.m in Sources */,
|
||||||
|
91C871A52C1314770093790D /* GKDYVideoMaskView.m in Sources */,
|
||||||
916353102C12B6D400593047 /* NSString+AES.m in Sources */,
|
916353102C12B6D400593047 /* NSString+AES.m in Sources */,
|
||||||
|
91C871A22C1314770093790D /* GKDYVideoItemButton.m in Sources */,
|
||||||
9163538B2C12C20B00593047 /* HBViewController.m in Sources */,
|
9163538B2C12C20B00593047 /* HBViewController.m in Sources */,
|
||||||
9163531A2C12B6D400593047 /* DGActivityIndicatorBallRotateAnimation.m in Sources */,
|
9163531A2C12B6D400593047 /* DGActivityIndicatorBallRotateAnimation.m in Sources */,
|
||||||
916352F82C12B6D400593047 /* NSDate+Extension.m in Sources */,
|
916352F82C12B6D400593047 /* NSDate+Extension.m in Sources */,
|
||||||
@ -1214,9 +1446,13 @@
|
|||||||
9163531D2C12B6D400593047 /* DGActivityIndicatorBallScaleRippleAnimation.m in Sources */,
|
9163531D2C12B6D400593047 /* DGActivityIndicatorBallScaleRippleAnimation.m in Sources */,
|
||||||
9163533A2C12B6D400593047 /* HUDManager.m in Sources */,
|
9163533A2C12B6D400593047 /* HUDManager.m in Sources */,
|
||||||
916353072C12B6D400593047 /* UIScreen+Extension.m in Sources */,
|
916353072C12B6D400593047 /* UIScreen+Extension.m in Sources */,
|
||||||
|
91C8719D2C1314770093790D /* GKDYScrollView.m in Sources */,
|
||||||
916353282C12B6D400593047 /* DGActivityIndicatorLineScalePulseOutAnimation.m in Sources */,
|
916353282C12B6D400593047 /* DGActivityIndicatorLineScalePulseOutAnimation.m in Sources */,
|
||||||
|
91C871972C1314770093790D /* GKRotationManager.m in Sources */,
|
||||||
9163534B2C12C15300593047 /* HBApiParams.m in Sources */,
|
9163534B2C12C15300593047 /* HBApiParams.m in Sources */,
|
||||||
9163531C2C12B6D400593047 /* DGActivityIndicatorBallScaleMultipleAnimation.m in Sources */,
|
9163531C2C12B6D400593047 /* DGActivityIndicatorBallScaleMultipleAnimation.m in Sources */,
|
||||||
|
91C871A32C1314770093790D /* GKDYVideoLandscapeCell.m in Sources */,
|
||||||
|
91C871AA2C1314770093790D /* GKDYVideoSlider.m in Sources */,
|
||||||
916353042C12B6D400593047 /* UIFont+Category.m in Sources */,
|
916353042C12B6D400593047 /* UIFont+Category.m in Sources */,
|
||||||
916353092C12B6D400593047 /* UITextField+Category.m in Sources */,
|
916353092C12B6D400593047 /* UITextField+Category.m in Sources */,
|
||||||
916353972C12C20B00593047 /* HBTableView.m in Sources */,
|
916353972C12C20B00593047 /* HBTableView.m in Sources */,
|
||||||
@ -1230,10 +1466,14 @@
|
|||||||
9163538D2C12C20B00593047 /* HBMultiLanguageManager.m in Sources */,
|
9163538D2C12C20B00593047 /* HBMultiLanguageManager.m in Sources */,
|
||||||
9163531F2C12B6D400593047 /* DGActivityIndicatorBallSpinFadeLoader.m in Sources */,
|
9163531F2C12B6D400593047 /* DGActivityIndicatorBallSpinFadeLoader.m in Sources */,
|
||||||
9163539A2C12C20B00593047 /* RSButton.m in Sources */,
|
9163539A2C12C20B00593047 /* RSButton.m in Sources */,
|
||||||
|
91C8719F2C1314770093790D /* GKDYVideoCell.m in Sources */,
|
||||||
|
91C8718E2C1314770093790D /* UIButton+GKEnlarge.m in Sources */,
|
||||||
916353302C12B6D400593047 /* DGActivityIndicatorTriplePulseAnimation.m in Sources */,
|
916353302C12B6D400593047 /* DGActivityIndicatorTriplePulseAnimation.m in Sources */,
|
||||||
916353022C12B6D400593047 /* UIControl+Extension.m in Sources */,
|
916353022C12B6D400593047 /* UIControl+Extension.m in Sources */,
|
||||||
9163532D2C12B6D400593047 /* DGActivityIndicatorRotatingTrigonAnimation.m in Sources */,
|
9163532D2C12B6D400593047 /* DGActivityIndicatorRotatingTrigonAnimation.m in Sources */,
|
||||||
|
91C871902C1314770093790D /* GKLikeView.m in Sources */,
|
||||||
916353342C12B6D400593047 /* MBProgressHUD.m in Sources */,
|
916353342C12B6D400593047 /* MBProgressHUD.m in Sources */,
|
||||||
|
91C871A82C1314770093790D /* GKDYVideoPreviewView.m in Sources */,
|
||||||
916353242C12B6D400593047 /* DGActivityIndicatorDoubleBounceAnimation.m in Sources */,
|
916353242C12B6D400593047 /* DGActivityIndicatorDoubleBounceAnimation.m in Sources */,
|
||||||
9163538C2C12C20B00593047 /* HBMultiLanguageController.m in Sources */,
|
9163538C2C12C20B00593047 /* HBMultiLanguageController.m in Sources */,
|
||||||
916353192C12B6D400593047 /* DGActivityIndicatorBallPulseSyncAnimation.m in Sources */,
|
916353192C12B6D400593047 /* DGActivityIndicatorBallPulseSyncAnimation.m in Sources */,
|
||||||
@ -1241,6 +1481,7 @@
|
|||||||
9163533D2C12B6D400593047 /* KxMenu.m in Sources */,
|
9163533D2C12B6D400593047 /* KxMenu.m in Sources */,
|
||||||
916353A82C12C6AF00593047 /* NSNotificationCenter+Extension.m in Sources */,
|
916353A82C12C6AF00593047 /* NSNotificationCenter+Extension.m in Sources */,
|
||||||
91C8711E2C12ECF50093790D /* HBFirstStartController.m in Sources */,
|
91C8711E2C12ECF50093790D /* HBFirstStartController.m in Sources */,
|
||||||
|
91C8719B2C1314770093790D /* GKDYVideoModel.m in Sources */,
|
||||||
9163531E2C12B6D400593047 /* DGActivityIndicatorBallScaleRippleMultipleAnimation.m in Sources */,
|
9163531E2C12B6D400593047 /* DGActivityIndicatorBallScaleRippleMultipleAnimation.m in Sources */,
|
||||||
916353362C12B6D400593047 /* SVProgressAnimatedView.m in Sources */,
|
916353362C12B6D400593047 /* SVProgressAnimatedView.m in Sources */,
|
||||||
916353112C12B6D400593047 /* DGActivityIndicatorAnimation.m in Sources */,
|
916353112C12B6D400593047 /* DGActivityIndicatorAnimation.m in Sources */,
|
||||||
@ -1248,6 +1489,7 @@
|
|||||||
9163531B2C12B6D400593047 /* DGActivityIndicatorBallScaleAnimation.m in Sources */,
|
9163531B2C12B6D400593047 /* DGActivityIndicatorBallScaleAnimation.m in Sources */,
|
||||||
916353182C12B6D400593047 /* DGActivityIndicatorBallPulseAnimation.m in Sources */,
|
916353182C12B6D400593047 /* DGActivityIndicatorBallPulseAnimation.m in Sources */,
|
||||||
916353872C12C20B00593047 /* HBCommonKeys.m in Sources */,
|
916353872C12C20B00593047 /* HBCommonKeys.m in Sources */,
|
||||||
|
91C871AB2C1314770093790D /* GKDYVideoStatusBar.m in Sources */,
|
||||||
916353052C12B6D400593047 /* UIImage+Category.m in Sources */,
|
916353052C12B6D400593047 /* UIImage+Category.m in Sources */,
|
||||||
916353962C12C20B00593047 /* HBRefreshNormalHeader.m in Sources */,
|
916353962C12C20B00593047 /* HBRefreshNormalHeader.m in Sources */,
|
||||||
916353392C12B6D400593047 /* SVRadialGradientLayer.m in Sources */,
|
916353392C12B6D400593047 /* SVRadialGradientLayer.m in Sources */,
|
||||||
@ -1256,9 +1498,13 @@
|
|||||||
916353312C12B6D400593047 /* DGActivityIndicatorTripleRingsAnimation.m in Sources */,
|
916353312C12B6D400593047 /* DGActivityIndicatorTripleRingsAnimation.m in Sources */,
|
||||||
916352FE2C12B6D400593047 /* NSString+Extension.m in Sources */,
|
916352FE2C12B6D400593047 /* NSString+Extension.m in Sources */,
|
||||||
916352FD2C12B6D400593047 /* NSObject+Tool.m in Sources */,
|
916352FD2C12B6D400593047 /* NSObject+Tool.m in Sources */,
|
||||||
|
91C8719C2C1314770093790D /* GKDYPanGestureRecognizer.m in Sources */,
|
||||||
9163530F2C12B6D400593047 /* GTMBase64.m in Sources */,
|
9163530F2C12B6D400593047 /* GTMBase64.m in Sources */,
|
||||||
|
91C871962C1314770093790D /* GKRotationManager_iOS_16_Later.m in Sources */,
|
||||||
916353062C12B6D400593047 /* UIImageView+Extension.m in Sources */,
|
916353062C12B6D400593047 /* UIImageView+Extension.m in Sources */,
|
||||||
|
91C871A02C1314770093790D /* GKDYVideoControlView.m in Sources */,
|
||||||
9163530C2C12B6D400593047 /* UIView+Frame.m in Sources */,
|
9163530C2C12B6D400593047 /* UIView+Frame.m in Sources */,
|
||||||
|
91C871932C1314770093790D /* GKLandscapeViewController.m in Sources */,
|
||||||
916353382C12B6D400593047 /* SVProgressHUD.m in Sources */,
|
916353382C12B6D400593047 /* SVProgressHUD.m in Sources */,
|
||||||
9163534E2C12C15300593047 /* HBNetWorkingUtility+Services.m in Sources */,
|
9163534E2C12C15300593047 /* HBNetWorkingUtility+Services.m in Sources */,
|
||||||
916353142C12B6D400593047 /* DGActivityIndicatorBallClipRotateMultipleAnimation.m in Sources */,
|
916353142C12B6D400593047 /* DGActivityIndicatorBallClipRotateMultipleAnimation.m in Sources */,
|
||||||
|
@ -1,5 +1,16 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict/>
|
<dict>
|
||||||
|
<key>NSAppTransportSecurity</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
|
<true/>
|
||||||
|
<key>NSExceptionDomains</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -6,11 +6,44 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import "HBViewController.h"
|
#import "HBViewController.h"
|
||||||
|
#import "GKDYVideoModel.h"
|
||||||
|
#import <JXCategoryView/JXCategoryView.h>
|
||||||
|
#import "GKDYVideoScrollView.h"
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@interface HBHomeViewController : HBViewController
|
@class HBHomeViewController;
|
||||||
|
|
||||||
|
@protocol HBHomeViewControllerDelegate <NSObject>
|
||||||
|
|
||||||
|
@optional;
|
||||||
|
|
||||||
|
- (void)playerVCDidClickShoot:(HBHomeViewController *)playerVC;
|
||||||
|
|
||||||
|
//- (void)playerVC:(HBHomeViewController *)playerVC controlView:(GKDYVideoControlView *)controlView isCritical:(BOOL)isCritical;
|
||||||
|
|
||||||
|
- (void)playerVC:(HBHomeViewController *)playerVC didDragDistance:(CGFloat)distance isEnd:(BOOL)isEnd;
|
||||||
|
|
||||||
|
- (void)playerVC:(HBHomeViewController *)playerVC cellZoomBegan:(GKDYVideoModel *)model;
|
||||||
|
|
||||||
|
- (void)playerVC:(HBHomeViewController *)playerVC cellZoomEnded:(GKDYVideoModel *)model isFullscreen:(BOOL)isFullscreen;
|
||||||
|
|
||||||
|
- (void)playerVC:(HBHomeViewController *)playerVC commentShowOrHide:(BOOL)show;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@interface HBHomeViewController : HBViewController
|
||||||
|
|
||||||
|
@property (nonatomic, weak) id<HBHomeViewControllerDelegate> delegate;
|
||||||
|
|
||||||
|
@property (nonatomic, copy) NSString *tab;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) GKDYVideoModel * model;
|
||||||
|
|
||||||
|
|
||||||
|
- (void)refreshData:(nullable void(^)(void))completion;
|
||||||
|
|
||||||
|
-(instancetype)initWithVideoId:(NSInteger)sid;
|
||||||
|
|
||||||
|
@end
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
@ -7,25 +7,247 @@
|
|||||||
|
|
||||||
#import "HBHomeViewController.h"
|
#import "HBHomeViewController.h"
|
||||||
|
|
||||||
@interface HBHomeViewController ()
|
//#import "QJShereModalView.h"
|
||||||
|
//#import "QJVideoEpisodesModalView.h"
|
||||||
|
|
||||||
|
#import "GKBallLoadingView.h"
|
||||||
|
#import "GKLikeView.h"
|
||||||
|
#import "GKDYVideoScrollView.h"
|
||||||
|
#import "GKDYVideoCell.h"
|
||||||
|
#import "GKDYPlayerManager.h"
|
||||||
|
#import "GKDYVideoPortraitCell.h"
|
||||||
|
#import "GKDYVideoLandscapeCell.h"
|
||||||
|
|
||||||
|
|
||||||
|
@interface HBHomeViewController ()<GKDYPlayerManagerDelegate> //,QJVideoEpisodesModalViewDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic, strong) GKDYPlayerManager * manager;
|
||||||
|
@property (assign, nonatomic) BOOL isDetails;
|
||||||
|
@property (assign, nonatomic) NSInteger sid;
|
||||||
|
|
||||||
|
//@property (nonatomic, strong) QJVideoEpisodesModalView * episodesModalView;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation HBHomeViewController
|
@implementation HBHomeViewController
|
||||||
|
|
||||||
|
- (instancetype)initWithVideoId:(NSInteger)sid {
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
self.isDetails = YES;
|
||||||
|
self.sid = sid;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)viewDidLoad {
|
- (void)viewDidLoad {
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
// Do any additional setup after loading the view.
|
self.hbd_barAlpha = 0.0;
|
||||||
|
self.edgesForExtendedLayout = UIRectEdgeNone;
|
||||||
|
|
||||||
|
[self initUI];
|
||||||
|
[self setupRefresh];
|
||||||
|
[self requestData];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
- (void)viewWillDisappear:(BOOL)animated {
|
||||||
#pragma mark - Navigation
|
[super viewWillDisappear:animated];
|
||||||
|
self.manager.player.viewControllerDisappear = YES;
|
||||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
|
||||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
|
||||||
// Get the new view controller using [segue destinationViewController].
|
|
||||||
// Pass the selected object to the new view controller.
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
- (void)viewDidAppear:(BOOL)animated {
|
||||||
|
[super viewDidAppear:animated];
|
||||||
|
self.manager.player.viewControllerDisappear = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
NSLog(@"playerVC dealloc");
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)initUI {
|
||||||
|
|
||||||
|
[self.view addSubview:self.manager.scrollView];
|
||||||
|
|
||||||
|
[self.manager.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.edges.equalTo(self.view);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setupRefresh {
|
||||||
|
if (self.isDetails) return; // 详情也 不需要加载更多
|
||||||
|
|
||||||
|
@weakify(self);
|
||||||
|
self.manager.scrollView.mj_footer = [HBRefreshAutoNormalFooter footerWithRefreshingBlock:^{
|
||||||
|
@strongify(self);
|
||||||
|
[self requestMore];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)requestData {
|
||||||
|
GKBallLoadingView *loadingView = [GKBallLoadingView loadingViewInView:self.view];
|
||||||
|
[loadingView startLoading];
|
||||||
|
|
||||||
|
self.manager.page = 1;
|
||||||
|
@weakify(loadingView);
|
||||||
|
[self requestData:^{
|
||||||
|
@strongify(loadingView);
|
||||||
|
[loadingView stopLoading];
|
||||||
|
[loadingView removeFromSuperview];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)requestMore {
|
||||||
|
self.manager.page++;
|
||||||
|
[self requestData:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)refreshData:(void (^)(void))completion {
|
||||||
|
self.manager.page = 1;
|
||||||
|
[self requestData:completion];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)requestData:(nullable void (^)(void))completion {
|
||||||
|
HBWeakSelf
|
||||||
|
|
||||||
|
if (self.isDetails) {
|
||||||
|
|
||||||
|
[HBNetWorkingUtility videos_fetchVideoDetailsWithSid:self.sid
|
||||||
|
complateBlock:^(BOOL success, id _Nonnull data, NSString * _Nonnull message) {
|
||||||
|
if (completion) completion();
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
GKDYVideoModel * model = [GKDYVideoModel mj_objectWithKeyValues:data[@"shortVideoInfo"]];
|
||||||
|
NSArray * videoInfoModels = [GKDUVideoInfoModel mj_objectArrayWithKeyValuesArray:data[@"episode_list"]];
|
||||||
|
GKDUVideoInfoModel * formModel = [GKDUVideoInfoModel mj_objectWithKeyValues:data[@"video_info"]];
|
||||||
|
|
||||||
|
for (GKDUVideoInfoModel * videoInfoModel in videoInfoModels) {
|
||||||
|
GKDYVideoModel * tempModel = [model copy];
|
||||||
|
tempModel.videoInfo = videoInfoModel;
|
||||||
|
[weakSelf.manager.dataSources addObject:tempModel];
|
||||||
|
}
|
||||||
|
// weakSelf.episodesModalView.models = weakSelf.manager.dataSources;
|
||||||
|
// weakSelf.episodesModalView.indexModel = formModel;
|
||||||
|
[weakSelf.manager.scrollView reloadData];
|
||||||
|
[weakSelf.manager.scrollView scrollToPageWithIndex:(formModel.episode -1)];
|
||||||
|
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
} else {
|
||||||
|
[HBNetWorkingUtility discover_fetchRecommandsWithPage:self.manager.page
|
||||||
|
size:20
|
||||||
|
complateBlock:^(BOOL success, id _Nonnull data, NSString * _Nonnull message) {
|
||||||
|
if (completion) completion();
|
||||||
|
if (success) {
|
||||||
|
NSArray * models = [GKDYVideoModel mj_objectArrayWithKeyValuesArray:data[@"list"]];
|
||||||
|
|
||||||
|
if (weakSelf.manager.page == 1) {
|
||||||
|
[weakSelf.manager.dataSources removeAllObjects];
|
||||||
|
}
|
||||||
|
[weakSelf.manager.dataSources addObjectsFromArray:models];
|
||||||
|
[weakSelf.manager.scrollView reloadData];
|
||||||
|
}
|
||||||
|
[weakSelf.manager.scrollView.mj_footer endRefreshingWithNoMoreData];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKDYVideoModel *)model {
|
||||||
|
return self.manager.currentCell.model;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - GKDYPlayerManagerDelegate
|
||||||
|
- (void)scrollViewShouldLoadMore {
|
||||||
|
[self requestMore];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollViewDidPanDistance:(CGFloat)distance isEnd:(BOOL)isEnd {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(playerVC:didDragDistance:isEnd:)]) {
|
||||||
|
[self.delegate playerVC:self didDragDistance:distance isEnd:isEnd];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)cellZoomBegan:(GKDYVideoModel *)model {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(playerVC:cellZoomBegan:)]) {
|
||||||
|
[self.delegate playerVC:self cellZoomBegan:model];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)cellZoomEnded:(GKDYVideoModel *)model isFullscreen:(BOOL)isFullscreen {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(playerVC:cellZoomEnded:isFullscreen:)]) {
|
||||||
|
[self.delegate playerVC:self cellZoomEnded:model isFullscreen:isFullscreen];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)celldidClickShare:(GKDYVideoModel *)model cell:(GKDYVideoPortraitCell *)cell {
|
||||||
|
// [[QJShereModalView new] presentInView:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)celldidClickFavorite:(GKDYVideoModel *)model cell:(GKDYVideoPortraitCell *)cell {
|
||||||
|
if (self.isDetails) return;
|
||||||
|
|
||||||
|
if (model.is_collect) {
|
||||||
|
[HBNetWorkingUtility customer_favoriteWithVideoId:model.cid complateBlock:nil];
|
||||||
|
} else {
|
||||||
|
[HBNetWorkingUtility customer_unFavoriteWithVideoId:model.cid complateBlock:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)celldidClickEpiscode:(GKDYVideoModel *)model cell:(GKDYVideoPortraitCell *)cell {
|
||||||
|
if (!self.isDetails) {
|
||||||
|
HBHomeViewController * controller = [[HBHomeViewController alloc]initWithVideoId:model.cid];
|
||||||
|
[self.navigationController pushViewController:controller animated:YES];
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// self.episodesModalView.indexModel = self.manager.currentCell.model.videoInfo;
|
||||||
|
// [self.episodesModalView presentInView:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)videoEpisodesModalViewDidSelectItemWithModel:(GKDUVideoInfoModel *)model {
|
||||||
|
|
||||||
|
if (self.isDetails) {
|
||||||
|
|
||||||
|
|
||||||
|
NSInteger row = 0;
|
||||||
|
for (int index = 0; index < self.manager.dataSources.count; index ++ ) {
|
||||||
|
GKDYVideoModel * tempModel = self.manager.dataSources[index];
|
||||||
|
if (model.vid == tempModel.videoInfo.vid) {
|
||||||
|
row = index;
|
||||||
|
break;;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[self.manager.scrollView scrollToPageWithIndex:row];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)cellSwitchWithModel:(GKDYVideoModel *)model {
|
||||||
|
if (!self.isDetails) return;
|
||||||
|
[HBNetWorkingUtility videos_uploadPlayHistoryWithSid:model.cid
|
||||||
|
vId:model.videoInfo.vid
|
||||||
|
complateBlock:^(BOOL success, id _Nonnull data, NSString * _Nonnull message) {
|
||||||
|
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - 懒加载
|
||||||
|
- (GKDYPlayerManager *)manager {
|
||||||
|
if (!_manager) {
|
||||||
|
_manager = [[GKDYPlayerManager alloc] init];
|
||||||
|
_manager.delegate = self;
|
||||||
|
}
|
||||||
|
return _manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- (QJVideoEpisodesModalView *)episodesModalView{
|
||||||
|
// if (!_episodesModalView) {
|
||||||
|
// _episodesModalView = [QJVideoEpisodesModalView new];
|
||||||
|
// _episodesModalView.delegate = self;
|
||||||
|
// }
|
||||||
|
// return _episodesModalView;
|
||||||
|
//}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
29
HiBit/Project/Player/Common/Category/UIButton+GKEnlarge.h
Executable file
29
HiBit/Project/Player/Common/Category/UIButton+GKEnlarge.h
Executable file
@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// UIButton+GKEnlarge.h
|
||||||
|
// Example
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/15.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface UIButton (GKEnlarge)
|
||||||
|
|
||||||
|
/*
|
||||||
|
扩大UIButton响应区域
|
||||||
|
|
||||||
|
使用
|
||||||
|
[enlargeButton setEnlargeEdge:20.0];
|
||||||
|
或者
|
||||||
|
[enlargeButton setEnlargeEdgeWithTop:20 right:20 bottom:20 left:10];
|
||||||
|
*/
|
||||||
|
|
||||||
|
- (void)setEnlargeEdge:(CGFloat)size;
|
||||||
|
- (void)setEnlargeEdgeWithTop:(CGFloat)top left:(CGFloat)left bottom:(CGFloat)bottom right:(CGFloat)right;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
64
HiBit/Project/Player/Common/Category/UIButton+GKEnlarge.m
Executable file
64
HiBit/Project/Player/Common/Category/UIButton+GKEnlarge.m
Executable file
@ -0,0 +1,64 @@
|
|||||||
|
//
|
||||||
|
// UIButton+GKEnlarge.m
|
||||||
|
// Example
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/15.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "UIButton+GKEnlarge.h"
|
||||||
|
#import <objc/runtime.h>
|
||||||
|
|
||||||
|
@implementation UIButton (GKEnlarge)
|
||||||
|
|
||||||
|
static char topNameKey;
|
||||||
|
static char rightNameKey;
|
||||||
|
static char bottomNameKey;
|
||||||
|
static char leftNameKey;
|
||||||
|
|
||||||
|
- (void)setEnlargeEdge:(CGFloat)size
|
||||||
|
{
|
||||||
|
objc_setAssociatedObject(self, &topNameKey, [NSNumber numberWithFloat:size], OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||||
|
objc_setAssociatedObject(self, &rightNameKey, [NSNumber numberWithFloat:size], OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||||
|
objc_setAssociatedObject(self, &bottomNameKey, [NSNumber numberWithFloat:size], OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||||
|
objc_setAssociatedObject(self, &leftNameKey, [NSNumber numberWithFloat:size], OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setEnlargeEdgeWithTop:(CGFloat)top left:(CGFloat)left bottom:(CGFloat)bottom right:(CGFloat)right
|
||||||
|
{
|
||||||
|
objc_setAssociatedObject(self, &topNameKey, [NSNumber numberWithFloat:top], OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||||
|
objc_setAssociatedObject(self, &rightNameKey, [NSNumber numberWithFloat:right], OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||||
|
objc_setAssociatedObject(self, &bottomNameKey, [NSNumber numberWithFloat:bottom], OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||||
|
objc_setAssociatedObject(self, &leftNameKey, [NSNumber numberWithFloat:left], OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGRect)enlargedRect
|
||||||
|
{
|
||||||
|
NSNumber* topEdge = objc_getAssociatedObject(self, &topNameKey);
|
||||||
|
NSNumber* rightEdge = objc_getAssociatedObject(self, &rightNameKey);
|
||||||
|
NSNumber* bottomEdge = objc_getAssociatedObject(self, &bottomNameKey);
|
||||||
|
NSNumber* leftEdge = objc_getAssociatedObject(self, &leftNameKey);
|
||||||
|
if (topEdge && rightEdge && bottomEdge && leftEdge)
|
||||||
|
{
|
||||||
|
return CGRectMake(self.bounds.origin.x - leftEdge.floatValue,
|
||||||
|
self.bounds.origin.y - topEdge.floatValue,
|
||||||
|
self.bounds.size.width + leftEdge.floatValue + rightEdge.floatValue,
|
||||||
|
self.bounds.size.height + topEdge.floatValue + bottomEdge.floatValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return self.bounds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
|
||||||
|
{
|
||||||
|
CGRect rect = [self enlargedRect];
|
||||||
|
if (CGRectEqualToRect(rect, self.bounds))
|
||||||
|
{
|
||||||
|
return [super pointInside:point withEvent:event];
|
||||||
|
}
|
||||||
|
return CGRectContainsPoint(rect, point) ? YES : NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
21
HiBit/Project/Player/Common/GKLikeView/GKDoubleLikeView.h
Executable file
21
HiBit/Project/Player/Common/GKLikeView/GKDoubleLikeView.h
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// GKDoubleLikeView.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by gaokun on 2019/6/19.
|
||||||
|
// Copyright © 2019 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GKDoubleLikeView : NSObject
|
||||||
|
|
||||||
|
- (void)createAnimationWithTouch:(UITouch *)touch;
|
||||||
|
|
||||||
|
- (void)createAnimationWithPoint:(CGPoint)point view:(UIView *)view completion:(nullable void(^)(void))completion;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
73
HiBit/Project/Player/Common/GKLikeView/GKDoubleLikeView.m
Executable file
73
HiBit/Project/Player/Common/GKLikeView/GKDoubleLikeView.m
Executable file
@ -0,0 +1,73 @@
|
|||||||
|
//
|
||||||
|
// GKDoubleLikeView.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by gaokun on 2019/6/19.
|
||||||
|
// Copyright © 2019 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDoubleLikeView.h"
|
||||||
|
|
||||||
|
@interface GKDoubleLikeView()
|
||||||
|
|
||||||
|
@property (nonatomic, copy) void(^completion)(void);
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKDoubleLikeView
|
||||||
|
|
||||||
|
- (void)createAnimationWithTouch:(UITouch *)touch {
|
||||||
|
if (touch.tapCount <= 1.0f) return;
|
||||||
|
|
||||||
|
[self createAnimationWithPoint:[touch locationInView:touch.view] view:touch.view completion:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)createAnimationWithPoint:(CGPoint)point view:(UIView *)view completion:(nullable void (^)(void))completion {
|
||||||
|
self.completion = completion;
|
||||||
|
|
||||||
|
UIImage *image = [UIImage imageNamed:@"player_favorite_selected"];
|
||||||
|
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 80, 80)];
|
||||||
|
imgView.image = image;
|
||||||
|
imgView.contentMode = UIViewContentModeScaleAspectFill;
|
||||||
|
imgView.center = point;
|
||||||
|
|
||||||
|
// 随机左右显示
|
||||||
|
int leftOrRight = arc4random() % 2;
|
||||||
|
leftOrRight = leftOrRight ? leftOrRight : -1;
|
||||||
|
imgView.transform = CGAffineTransformRotate(imgView.transform, M_PI / 9.0f * leftOrRight);
|
||||||
|
[view addSubview:imgView];
|
||||||
|
|
||||||
|
// 出现的时候回弹一下
|
||||||
|
__block UIImageView *blockImgV = imgView;
|
||||||
|
__block UIImage *blockImage = image;
|
||||||
|
|
||||||
|
[UIView animateWithDuration:0.1 animations:^{
|
||||||
|
blockImgV.transform = CGAffineTransformScale(blockImgV.transform, 1.2f, 1.2f);
|
||||||
|
} completion:^(BOOL finished) {
|
||||||
|
blockImgV.transform = CGAffineTransformScale(blockImgV.transform, 0.8f, 0.8f);
|
||||||
|
|
||||||
|
// 向上飘,放大,透明
|
||||||
|
[self performSelector:@selector(animationToTop:) withObject:@[blockImgV, blockImage] afterDelay:0.3f];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)animationToTop:(NSArray *)imgObjects {
|
||||||
|
if (imgObjects && imgObjects.count > 0) {
|
||||||
|
__block UIImageView *imgView = (UIImageView *)imgObjects.firstObject;
|
||||||
|
__block UIImage *image = (UIImage *)imgObjects.lastObject;
|
||||||
|
[UIView animateWithDuration:1.0f animations:^{
|
||||||
|
CGRect imgViewFrame = imgView.frame;
|
||||||
|
imgViewFrame.origin.y -= 100.0f;
|
||||||
|
imgView.frame = imgViewFrame;
|
||||||
|
imgView.transform = CGAffineTransformScale(imgView.transform, 1.8f, 1.8f);
|
||||||
|
imgView.alpha = 0.0f;
|
||||||
|
} completion:^(BOOL finished) {
|
||||||
|
[imgView removeFromSuperview];
|
||||||
|
imgView = nil;
|
||||||
|
image = nil;
|
||||||
|
!self.completion ?: self.completion();
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
27
HiBit/Project/Player/Common/GKLikeView/GKLikeView.h
Executable file
27
HiBit/Project/Player/Common/GKLikeView/GKLikeView.h
Executable file
@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// GKLikeView.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by gaokun on 2019/5/27.
|
||||||
|
// Copyright © 2019 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GKLikeView : UIView
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL isLike;
|
||||||
|
|
||||||
|
@property (nonatomic, copy) void(^likeBlock)(void);
|
||||||
|
|
||||||
|
- (void)startAnimationWithIsLike:(BOOL)isLike;
|
||||||
|
|
||||||
|
- (void)setupLikeState:(BOOL)isLike;
|
||||||
|
|
||||||
|
- (void)setupLikeCount:(NSString *)count;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
189
HiBit/Project/Player/Common/GKLikeView/GKLikeView.m
Executable file
189
HiBit/Project/Player/Common/GKLikeView/GKLikeView.m
Executable file
@ -0,0 +1,189 @@
|
|||||||
|
//
|
||||||
|
// GKLikeView.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by gaokun on 2019/5/27.
|
||||||
|
// Copyright © 2019 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKLikeView.h"
|
||||||
|
|
||||||
|
@interface GKLikeView()
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIImageView *likeBeforeImgView;
|
||||||
|
@property (nonatomic, strong) UIImageView *likeAfterImgView;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UILabel *countLabel;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKLikeView
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
if (self = [super init]) {
|
||||||
|
[self addSubview:self.likeBeforeImgView];
|
||||||
|
[self addSubview:self.likeAfterImgView];
|
||||||
|
[self addSubview:self.countLabel];
|
||||||
|
|
||||||
|
// CGFloat imgWH = HBAdapt(40.0f);
|
||||||
|
// self.likeBeforeImgView.frame = CGRectMake(0, 0, imgWH, imgWH);
|
||||||
|
// self.likeAfterImgView.frame = CGRectMake(0, 0, imgWH, imgWH);
|
||||||
|
|
||||||
|
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
|
||||||
|
[self addGestureRecognizer:tapGesture];
|
||||||
|
|
||||||
|
[self.likeBeforeImgView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.top.right.equalTo(self);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.likeAfterImgView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.edges.equalTo(self.likeBeforeImgView);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.countLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.right.bottom.equalTo(self);
|
||||||
|
make.top.equalTo(self.likeBeforeImgView.mas_bottom).offset(4.0);
|
||||||
|
}];
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)layoutSubviews {
|
||||||
|
[super layoutSubviews];
|
||||||
|
//
|
||||||
|
// CGPoint imgCenter = self.likeBeforeImgView.center;
|
||||||
|
// imgCenter.x = self.frame.size.width / 2;
|
||||||
|
// self.likeBeforeImgView.center = imgCenter;
|
||||||
|
// self.likeAfterImgView.center = imgCenter;
|
||||||
|
//
|
||||||
|
// [self.countLabel sizeToFit];
|
||||||
|
//
|
||||||
|
// CGFloat countX = (self.frame.size.width - self.countLabel.frame.size.width) / 2;
|
||||||
|
// CGFloat countY = self.frame.size.height - self.countLabel.frame.size.height;
|
||||||
|
// self.countLabel.frame = CGRectMake(countX, countY, self.countLabel.frame.size.width, self.countLabel.frame.size.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setupLikeState:(BOOL)isLike {
|
||||||
|
self.isLike = isLike;
|
||||||
|
|
||||||
|
if (isLike) {
|
||||||
|
self.likeAfterImgView.hidden = NO;
|
||||||
|
}else {
|
||||||
|
self.likeAfterImgView.hidden = YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setupLikeCount:(NSString *)count {
|
||||||
|
self.countLabel.text = count;
|
||||||
|
|
||||||
|
[self layoutSubviews];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)startAnimationWithIsLike:(BOOL)isLike {
|
||||||
|
if (self.isLike == isLike) return;
|
||||||
|
|
||||||
|
self.isLike = isLike;
|
||||||
|
|
||||||
|
if (isLike) {
|
||||||
|
CGFloat length = 30;
|
||||||
|
CGFloat duration = 0.5f;
|
||||||
|
for (NSInteger i = 0; i < 6; i++) {
|
||||||
|
CAShapeLayer *layer = [CAShapeLayer layer];
|
||||||
|
layer.position = self.likeBeforeImgView.center;
|
||||||
|
layer.fillColor = [UIColor colorWithRed:232.0/255.0 green:50.0/255.0 blue:85.0/255.0 alpha:1.0].CGColor;
|
||||||
|
|
||||||
|
UIBezierPath *startPath = [UIBezierPath bezierPath];
|
||||||
|
[startPath moveToPoint:CGPointMake(-2, -length)];
|
||||||
|
[startPath addLineToPoint:CGPointMake(2, -length)];
|
||||||
|
[startPath addLineToPoint:CGPointMake(0, 0)];
|
||||||
|
layer.path = startPath.CGPath;
|
||||||
|
|
||||||
|
layer.transform = CATransform3DMakeRotation(M_PI / 3.0f * i, 0, 0, 1.0);
|
||||||
|
[self.layer addSublayer:layer];
|
||||||
|
|
||||||
|
CAAnimationGroup *group = [CAAnimationGroup animation];
|
||||||
|
group.removedOnCompletion = NO;
|
||||||
|
group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
|
||||||
|
group.fillMode = kCAFillModeForwards;
|
||||||
|
group.duration = duration;
|
||||||
|
|
||||||
|
CABasicAnimation *scaleAnim = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
|
||||||
|
scaleAnim.fromValue = @(0.0f);
|
||||||
|
scaleAnim.toValue = @(1.0f);
|
||||||
|
scaleAnim.duration = duration * 0.2f;
|
||||||
|
|
||||||
|
UIBezierPath *endPath = [UIBezierPath bezierPath];
|
||||||
|
[endPath moveToPoint:CGPointMake(-2, -length)];
|
||||||
|
[endPath addLineToPoint:CGPointMake(2, -length)];
|
||||||
|
[endPath addLineToPoint:CGPointMake(0, -length)];
|
||||||
|
|
||||||
|
CABasicAnimation *pathAnim = [CABasicAnimation animationWithKeyPath:@"path"];
|
||||||
|
pathAnim.fromValue = (__bridge id)layer.path;
|
||||||
|
pathAnim.toValue = (__bridge id)endPath.CGPath;
|
||||||
|
pathAnim.beginTime = duration * 0.2f;
|
||||||
|
pathAnim.duration = duration * 0.8f;
|
||||||
|
|
||||||
|
[group setAnimations:@[scaleAnim, pathAnim]];
|
||||||
|
[layer addAnimation:group forKey:nil];
|
||||||
|
}
|
||||||
|
self.likeAfterImgView.hidden = NO;
|
||||||
|
self.likeAfterImgView.alpha = 0.0f;
|
||||||
|
|
||||||
|
self.likeAfterImgView.transform = CGAffineTransformMakeScale(0.1f, 0.1f);
|
||||||
|
|
||||||
|
[UIView animateWithDuration:0.15 animations:^{
|
||||||
|
self.likeAfterImgView.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
|
||||||
|
self.likeAfterImgView.alpha = 1.0f;
|
||||||
|
self.likeBeforeImgView.alpha = 0.0f;
|
||||||
|
} completion:^(BOOL finished) {
|
||||||
|
self.likeAfterImgView.transform = CGAffineTransformIdentity;
|
||||||
|
self.likeBeforeImgView.alpha = 1.0f;
|
||||||
|
}];
|
||||||
|
}else {
|
||||||
|
self.likeAfterImgView.alpha = 1.0f;
|
||||||
|
self.likeAfterImgView.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
|
||||||
|
[UIView animateWithDuration:0.15 animations:^{
|
||||||
|
self.likeAfterImgView.transform = CGAffineTransformMakeScale(0.3f, 0.3f);
|
||||||
|
} completion:^(BOOL finished) {
|
||||||
|
self.likeAfterImgView.transform = CGAffineTransformIdentity;
|
||||||
|
self.likeAfterImgView.hidden = YES;
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - UITapGestureRecognizer
|
||||||
|
- (void)tapAction:(UITapGestureRecognizer *)tap {
|
||||||
|
[self startAnimationWithIsLike:!self.isLike];
|
||||||
|
!self.likeBlock ?: self.likeBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - 懒加载
|
||||||
|
- (UIImageView *)likeBeforeImgView {
|
||||||
|
if (!_likeBeforeImgView) {
|
||||||
|
_likeBeforeImgView = [UIImageView new];
|
||||||
|
_likeBeforeImgView.image = [UIImage imageNamed:@"player_favorite_normal"];
|
||||||
|
}
|
||||||
|
return _likeBeforeImgView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIImageView *)likeAfterImgView {
|
||||||
|
if (!_likeAfterImgView) {
|
||||||
|
_likeAfterImgView = [UIImageView new];
|
||||||
|
_likeAfterImgView.image = [UIImage imageNamed:@"player_favorite_selected"];
|
||||||
|
}
|
||||||
|
return _likeAfterImgView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)countLabel {
|
||||||
|
if (!_countLabel) {
|
||||||
|
_countLabel = [UILabel new];
|
||||||
|
_countLabel.textColor = [UIColor whiteColor];
|
||||||
|
_countLabel.font = [UIFont systemFontOfSize:12.0f weight:UIFontWeightRegular];
|
||||||
|
_countLabel.textAlignment = NSTextAlignmentCenter;
|
||||||
|
}
|
||||||
|
return _countLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
24
HiBit/Project/Player/Common/GKLoadingView/GKBallLoadingView.h
Executable file
24
HiBit/Project/Player/Common/GKLoadingView/GKBallLoadingView.h
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
//
|
||||||
|
// GKBallLoadingView.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by gaokun on 2019/5/7.
|
||||||
|
// Copyright © 2019 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GKBallLoadingView : UIView
|
||||||
|
|
||||||
|
+ (instancetype)loadingViewInView:(UIView *)view;
|
||||||
|
|
||||||
|
- (void)startLoadingWithProgress:(CGFloat)progress;
|
||||||
|
|
||||||
|
- (void)startLoading;
|
||||||
|
- (void)stopLoading;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
261
HiBit/Project/Player/Common/GKLoadingView/GKBallLoadingView.m
Executable file
261
HiBit/Project/Player/Common/GKLoadingView/GKBallLoadingView.m
Executable file
@ -0,0 +1,261 @@
|
|||||||
|
//
|
||||||
|
// GKBallLoadingView.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by gaokun on 2019/5/7.
|
||||||
|
// Copyright © 2019 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKBallLoadingView.h"
|
||||||
|
|
||||||
|
#define kBallWidth 12.0f
|
||||||
|
#define kBallSpeed 0.7f
|
||||||
|
#define kBallZoomScale 0.25
|
||||||
|
#define kBallPauseTime 0.18
|
||||||
|
|
||||||
|
#define GKColorRGBA(r, g, b, a) [UIColor colorWithRed:(r / 255.0) green:(g / 255.0) blue:(b / 255.0) alpha:a]
|
||||||
|
#define GKColorRGB(r, g, b) GKColorRGBA(r, g, b, 1.0)
|
||||||
|
|
||||||
|
// 球的运动方向,以绿球向右、红球向左运动为正向
|
||||||
|
typedef NS_ENUM(NSUInteger, GKBallMoveDirection) {
|
||||||
|
GKBallMoveDirectionPositive = 1, // 正向运动
|
||||||
|
GKBallMoveDirectionNegative = -1 // 逆向运动
|
||||||
|
};
|
||||||
|
|
||||||
|
@interface GKBallLoadingView()
|
||||||
|
|
||||||
|
// 球容器视图
|
||||||
|
@property (nonatomic, strong) UIView *containerView;
|
||||||
|
|
||||||
|
// 绿球
|
||||||
|
@property (nonatomic, strong) UIView *greenBall;
|
||||||
|
|
||||||
|
// 红球
|
||||||
|
@property (nonatomic, strong) UIView *redBall;
|
||||||
|
|
||||||
|
// 黑球
|
||||||
|
@property (nonatomic, strong) UIView *blackBall;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) GKBallMoveDirection moveDirection;
|
||||||
|
|
||||||
|
// 定时器
|
||||||
|
@property (nonatomic, strong) CADisplayLink *displayLink;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKBallLoadingView
|
||||||
|
|
||||||
|
+ (instancetype)loadingViewInView:(UIView *)view {
|
||||||
|
GKBallLoadingView *loadingView = [[GKBallLoadingView alloc] initWithFrame:view.bounds];
|
||||||
|
[view addSubview:loadingView];
|
||||||
|
return loadingView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)startLoadingWithProgress:(CGFloat)progress {
|
||||||
|
[self updateBallPositionWithProgress:progress];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)startLoading {
|
||||||
|
[self startAnimation];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)stopLoading {
|
||||||
|
[self stopAnimation];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithFrame:(CGRect)frame {
|
||||||
|
if (self = [super initWithFrame:frame]) {
|
||||||
|
[self setupUI];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setupUI {
|
||||||
|
self.containerView = [[UIView alloc] init];
|
||||||
|
self.containerView.center = self.center;
|
||||||
|
self.containerView.bounds = CGRectMake(0, 0, 2.1f * kBallWidth, 2.0f * kBallWidth);
|
||||||
|
[self addSubview:self.containerView];
|
||||||
|
|
||||||
|
// 绿球
|
||||||
|
self.greenBall = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kBallWidth, kBallWidth)];
|
||||||
|
self.greenBall.center = CGPointMake(kBallWidth * 0.5f, self.containerView.bounds.size.height * 0.5f);
|
||||||
|
self.greenBall.layer.cornerRadius = kBallWidth * 0.5f;
|
||||||
|
self.greenBall.layer.masksToBounds = YES;
|
||||||
|
self.greenBall.backgroundColor = GKColorRGB(35, 246, 235);
|
||||||
|
[self.containerView addSubview:self.greenBall];
|
||||||
|
|
||||||
|
// 红球
|
||||||
|
self.redBall = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kBallWidth, kBallWidth)];
|
||||||
|
self.redBall.center = CGPointMake(self.containerView.bounds.size.width - kBallWidth * 0.5f, self.containerView.bounds.size.height * 0.5f);
|
||||||
|
self.redBall.layer.cornerRadius = kBallWidth * 0.5f;
|
||||||
|
self.redBall.layer.masksToBounds = YES;
|
||||||
|
self.redBall.backgroundColor = GKColorRGB(255, 46, 86);
|
||||||
|
[self.containerView addSubview:self.redBall];
|
||||||
|
|
||||||
|
// 黑球
|
||||||
|
// 第一次动画是正向,绿球在上,红球在下,阴影显示在绿球上
|
||||||
|
self.blackBall = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kBallWidth, kBallWidth)];
|
||||||
|
self.blackBall.backgroundColor = GKColorRGB(12, 11, 17);
|
||||||
|
self.blackBall.layer.cornerRadius = kBallWidth * 0.5f;
|
||||||
|
self.blackBall.layer.masksToBounds = YES;
|
||||||
|
[self.greenBall addSubview:self.blackBall];
|
||||||
|
|
||||||
|
// 方向
|
||||||
|
self.moveDirection = GKBallMoveDirectionPositive;
|
||||||
|
[self.containerView bringSubviewToFront:self.greenBall];
|
||||||
|
[self updateBallPositionWithProgress:0];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)startAnimation {
|
||||||
|
[self pauseAnimation];
|
||||||
|
|
||||||
|
// 创建并开启定时器
|
||||||
|
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateBallAnimations)];
|
||||||
|
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)pauseAnimation {
|
||||||
|
if (self.displayLink) {
|
||||||
|
[self.displayLink invalidate];
|
||||||
|
self.displayLink = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)stopAnimation {
|
||||||
|
if (self.displayLink) {
|
||||||
|
[self.displayLink invalidate];
|
||||||
|
self.displayLink = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消延时方法
|
||||||
|
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(startAnimation) object:nil];
|
||||||
|
|
||||||
|
// 恢复初始化位置
|
||||||
|
[self.greenBall addSubview:self.blackBall];
|
||||||
|
[self.containerView bringSubviewToFront:self.greenBall];
|
||||||
|
self.moveDirection = GKBallMoveDirectionPositive;
|
||||||
|
[self updateBallPositionWithProgress:0];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)resetAnimation {
|
||||||
|
[self pauseAnimation];
|
||||||
|
// 延时执行方法
|
||||||
|
[self performSelector:@selector(startAnimation) withObject:nil afterDelay:kBallPauseTime];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)updateBallPositionWithProgress:(CGFloat)progress {
|
||||||
|
CGPoint center = self.greenBall.center;
|
||||||
|
center.x = kBallWidth * 0.5 + 1.1 * kBallWidth * progress;
|
||||||
|
self.greenBall.center = center;
|
||||||
|
|
||||||
|
center = self.redBall.center;
|
||||||
|
center.x = kBallWidth * 1.6 - 1.1 * kBallWidth * progress;
|
||||||
|
self.redBall.center = center;
|
||||||
|
|
||||||
|
// 缩放动画,绿球放大,红球缩小
|
||||||
|
if (progress != 0 && progress != 1) {
|
||||||
|
self.greenBall.transform = [self ballLargerTransformOfCenterX:center.x];
|
||||||
|
self.redBall.transform = [self ballSmallerTransformOfCenterX:center.x];
|
||||||
|
}else {
|
||||||
|
self.greenBall.transform = CGAffineTransformIdentity;
|
||||||
|
self.redBall.transform = CGAffineTransformIdentity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新黑球位置
|
||||||
|
CGRect blackBallFrame = [self.redBall convertRect:self.redBall.bounds toCoordinateSpace:self.greenBall];
|
||||||
|
self.blackBall.frame = blackBallFrame;
|
||||||
|
self.blackBall.layer.cornerRadius = self.blackBall.bounds.size.width * 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)updateBallAnimations {
|
||||||
|
if (self.moveDirection == GKBallMoveDirectionPositive) { // 正向
|
||||||
|
CGPoint center = self.greenBall.center;
|
||||||
|
center.x += kBallSpeed;
|
||||||
|
self.greenBall.center = center;
|
||||||
|
|
||||||
|
center = self.redBall.center;
|
||||||
|
center.x -= kBallSpeed;
|
||||||
|
self.redBall.center = center;
|
||||||
|
|
||||||
|
// 缩放动画,绿球放大,红球缩小
|
||||||
|
self.greenBall.transform = [self ballLargerTransformOfCenterX:center.x];
|
||||||
|
self.redBall.transform = [self ballSmallerTransformOfCenterX:center.x];
|
||||||
|
|
||||||
|
// 更新黑球位置
|
||||||
|
CGRect blackBallFrame = [self.redBall convertRect:self.redBall.bounds toCoordinateSpace:self.greenBall];
|
||||||
|
self.blackBall.frame = blackBallFrame;
|
||||||
|
self.blackBall.layer.cornerRadius = self.blackBall.bounds.size.width * 0.5f;
|
||||||
|
|
||||||
|
// 更新方向 改变三个球的相对位置
|
||||||
|
if (CGRectGetMaxX(self.greenBall.frame) >= self.containerView.bounds.size.width || CGRectGetMinX(self.redBall.frame) <= 0) {
|
||||||
|
// 切换为反向
|
||||||
|
self.moveDirection = GKBallMoveDirectionNegative;
|
||||||
|
|
||||||
|
// 反向运动时,红球在上,绿球在下
|
||||||
|
[self.containerView bringSubviewToFront:self.redBall];
|
||||||
|
|
||||||
|
// 黑球放在红球上面
|
||||||
|
[self.redBall addSubview:self.blackBall];
|
||||||
|
|
||||||
|
// 重置动画
|
||||||
|
[self resetAnimation];
|
||||||
|
}
|
||||||
|
}else if (self.moveDirection == GKBallMoveDirectionNegative) { // 反向
|
||||||
|
// 更新绿球位置
|
||||||
|
CGPoint center = self.greenBall.center;
|
||||||
|
center.x -= kBallSpeed;
|
||||||
|
self.greenBall.center = center;
|
||||||
|
|
||||||
|
// 更新红球位置
|
||||||
|
center = self.redBall.center;
|
||||||
|
center.x += kBallSpeed;
|
||||||
|
self.redBall.center = center;
|
||||||
|
|
||||||
|
// 缩放动画 红球放大 绿球缩小
|
||||||
|
self.redBall.transform = [self ballLargerTransformOfCenterX:center.x];
|
||||||
|
self.greenBall.transform = [self ballSmallerTransformOfCenterX:center.x];
|
||||||
|
|
||||||
|
// 更新黑球位置
|
||||||
|
CGRect blackBallFrame = [self.greenBall convertRect:self.greenBall.bounds toCoordinateSpace:self.redBall];
|
||||||
|
self.blackBall.frame = blackBallFrame;
|
||||||
|
self.blackBall.layer.cornerRadius = self.blackBall.bounds.size.width * 0.5f;
|
||||||
|
|
||||||
|
// 更新方向 改变三个球的相对位置
|
||||||
|
if (CGRectGetMinX(self.greenBall.frame) <= 0 || CGRectGetMaxX(self.redBall.frame) >= self.containerView.bounds.size.width) {
|
||||||
|
// 切换为正向
|
||||||
|
self.moveDirection = GKBallMoveDirectionPositive;
|
||||||
|
// 正向运动 绿球在上 红球在下
|
||||||
|
[self.containerView bringSubviewToFront:self.greenBall];
|
||||||
|
// 黑球放在绿球上面
|
||||||
|
[self.greenBall addSubview:self.blackBall];
|
||||||
|
// 重置动画
|
||||||
|
[self resetAnimation];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 放大动画
|
||||||
|
- (CGAffineTransform)ballLargerTransformOfCenterX:(CGFloat)centerX {
|
||||||
|
CGFloat cosValue = [self cosValueOfCenterX:centerX];
|
||||||
|
return CGAffineTransformMakeScale(1 + cosValue * kBallZoomScale, 1 + cosValue * kBallZoomScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 缩小动画
|
||||||
|
- (CGAffineTransform)ballSmallerTransformOfCenterX:(CGFloat)centerX {
|
||||||
|
CGFloat cosValue = [self cosValueOfCenterX:centerX];
|
||||||
|
return CGAffineTransformMakeScale(1 - cosValue * kBallZoomScale, 1 - cosValue * kBallZoomScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据余弦函数获取变化区间 变化范围是0~1~0
|
||||||
|
- (CGFloat)cosValueOfCenterX:(CGFloat)centerX {
|
||||||
|
// 移动距离
|
||||||
|
CGFloat apart = centerX - self.containerView.bounds.size.width * 0.5f;
|
||||||
|
// 最大距离(球心距离Container中心距离)
|
||||||
|
CGFloat maxAppart = (self.containerView.bounds.size.width - kBallWidth) * 0.5f;
|
||||||
|
// 移动距离和最大距离的比例
|
||||||
|
CGFloat angle = apart / maxAppart * M_PI_2;
|
||||||
|
// 获取比例对应余弦曲线的Y值
|
||||||
|
return cos(angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// GKLandscapeNavigationController.h
|
||||||
|
// Example
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/31.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@protocol GKLandscapeNavigationControllerDelegate;
|
||||||
|
|
||||||
|
@interface GKLandscapeNavigationController : UINavigationController
|
||||||
|
- (instancetype)initWithRootViewController:(UIViewController *)rootViewController delegate:(nullable id<GKLandscapeNavigationControllerDelegate>)delegate;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@protocol GKLandscapeNavigationControllerDelegate <NSObject>
|
||||||
|
|
||||||
|
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,62 @@
|
|||||||
|
//
|
||||||
|
// GKLandscapeNavigationController.m
|
||||||
|
// Example
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/31.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKLandscapeNavigationController.h"
|
||||||
|
|
||||||
|
@implementation GKLandscapeNavigationController {
|
||||||
|
__weak id<GKLandscapeNavigationControllerDelegate> _delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithRootViewController:(UIViewController *)rootViewController delegate:(id<GKLandscapeNavigationControllerDelegate>)delegate {
|
||||||
|
if (self = [super initWithRootViewController:rootViewController]) {
|
||||||
|
_delegate = delegate;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewDidLoad {
|
||||||
|
[super viewDidLoad];
|
||||||
|
[super setNavigationBarHidden:YES animated:NO];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setNavigationBarHidden:(BOOL)navigationBarHidden {}
|
||||||
|
- (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated {}
|
||||||
|
|
||||||
|
- (BOOL)shouldAutorotate {
|
||||||
|
return self.topViewController.shouldAutorotate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
|
||||||
|
return self.topViewController.supportedInterfaceOrientations;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
|
||||||
|
return self.topViewController.preferredInterfaceOrientationForPresentation;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIViewController *)childViewControllerForStatusBarStyle {
|
||||||
|
return self.topViewController;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIViewController *)childViewControllerForStatusBarHidden {
|
||||||
|
return self.topViewController;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)prefersHomeIndicatorAutoHidden {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
|
||||||
|
if (self.viewControllers.count < 1) {
|
||||||
|
[super pushViewController:viewController animated:animated];
|
||||||
|
}else if ([_delegate respondsToSelector:@selector(pushViewController:animated:)]) {
|
||||||
|
[_delegate pushViewController:viewController animated:animated];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
37
HiBit/Project/Player/Common/GKRotationManager/GKLandscapeViewController.h
Executable file
37
HiBit/Project/Player/Common/GKRotationManager/GKLandscapeViewController.h
Executable file
@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// GKLandscapeViewController.h
|
||||||
|
// Example
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/31.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@protocol GKLandscapeViewControllerDelegate;
|
||||||
|
|
||||||
|
@interface GKLandscapeViewController : UIViewController
|
||||||
|
|
||||||
|
@property (nonatomic, weak, nullable) id<GKLandscapeViewControllerDelegate> delegate;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL disableAnimations;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL statusBarHidden;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) UIStatusBarStyle statusBarStyle;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) UIStatusBarAnimation statusBarAnimation;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@protocol GKLandscapeViewControllerDelegate <NSObject>
|
||||||
|
|
||||||
|
@optional
|
||||||
|
- (BOOL)viewControllerShouldAutorotate:(GKLandscapeViewController *)viewController;
|
||||||
|
- (void)viewController:(GKLandscapeViewController *)viewController viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
47
HiBit/Project/Player/Common/GKRotationManager/GKLandscapeViewController.m
Executable file
47
HiBit/Project/Player/Common/GKRotationManager/GKLandscapeViewController.m
Executable file
@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// GKLandscapeViewController.m
|
||||||
|
// Example
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/31.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKLandscapeViewController.h"
|
||||||
|
|
||||||
|
@implementation GKLandscapeViewController
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
if (self = [super init]) {
|
||||||
|
_statusBarStyle = UIStatusBarStyleLightContent;
|
||||||
|
_statusBarAnimation = UIStatusBarAnimationSlide;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(viewController:viewWillTransitionToSize:withTransitionCoordinator:)]) {
|
||||||
|
[self.delegate viewController:self viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
|
||||||
|
return UIInterfaceOrientationMaskAllButUpsideDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)prefersHomeIndicatorAutoHidden {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIStatusBarStyle)preferredStatusBarStyle {
|
||||||
|
return self.statusBarHidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)prefersStatusBarHidden {
|
||||||
|
return self.statusBarStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
|
||||||
|
return self.statusBarAnimation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
21
HiBit/Project/Player/Common/GKRotationManager/GKLandscapeWindow.h
Executable file
21
HiBit/Project/Player/Common/GKRotationManager/GKLandscapeWindow.h
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// GKLandscapeWindow.h
|
||||||
|
// Example
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/31.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@class GKRotationManager;
|
||||||
|
|
||||||
|
@interface GKLandscapeWindow : UIWindow
|
||||||
|
|
||||||
|
@property (nonatomic, weak, nullable) GKRotationManager *rotationManager;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
76
HiBit/Project/Player/Common/GKRotationManager/GKLandscapeWindow.m
Executable file
76
HiBit/Project/Player/Common/GKRotationManager/GKLandscapeWindow.m
Executable file
@ -0,0 +1,76 @@
|
|||||||
|
//
|
||||||
|
// GKLandscapeWindow.m
|
||||||
|
// Example
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/31.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKLandscapeWindow.h"
|
||||||
|
|
||||||
|
@implementation GKLandscapeWindow {
|
||||||
|
CGRect _old_bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithFrame:(CGRect)frame {
|
||||||
|
if (self = [super initWithFrame:frame]) {
|
||||||
|
self.frame = UIScreen.mainScreen.bounds;
|
||||||
|
self.windowLevel = UIWindowLevelStatusBar - 1;
|
||||||
|
if (@available(iOS 13.0, *)) {
|
||||||
|
if (self.windowScene == nil) {
|
||||||
|
self.windowScene = UIApplication.sharedApplication.keyWindow.windowScene;
|
||||||
|
}
|
||||||
|
if (self.windowScene == nil) {
|
||||||
|
self.windowScene = (UIWindowScene *) UIApplication.sharedApplication.connectedScenes.anyObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.hidden = YES;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
- (void)dealloc {
|
||||||
|
NSLog(@"%d \t %s", (int)__LINE__, __func__);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- (void)setRootViewController:(UIViewController *)rootViewController {
|
||||||
|
[super setRootViewController:rootViewController];
|
||||||
|
rootViewController.view.frame = self.bounds;
|
||||||
|
rootViewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setBackgroundColor:(UIColor *)backgroundColor {}
|
||||||
|
|
||||||
|
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)layoutSubviews {
|
||||||
|
[super layoutSubviews];
|
||||||
|
|
||||||
|
// 如果是大屏转大屏 就不需要修改了
|
||||||
|
if (!CGRectEqualToRect(_old_bounds, self.bounds)) {
|
||||||
|
_old_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
self.rootViewController.view.frame = self.bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
118
HiBit/Project/Player/Common/GKRotationManager/GKRotationManager.h
Executable file
118
HiBit/Project/Player/Common/GKRotationManager/GKRotationManager.h
Executable file
@ -0,0 +1,118 @@
|
|||||||
|
//
|
||||||
|
// GKRotationManager.h
|
||||||
|
// Example
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/31.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKLandscapeWindow.h"
|
||||||
|
#import "GKLandscapeViewController.h"
|
||||||
|
|
||||||
|
typedef NS_OPTIONS(NSUInteger, GKInterfaceOrientationMask) {
|
||||||
|
GKInterfaceOrientationMaskUnknow = 0,
|
||||||
|
GKInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait),
|
||||||
|
GKInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft),
|
||||||
|
GKInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight),
|
||||||
|
GKInterfaceOrientationMaskPortraitUpsideDown = ( 1 << UIInterfaceOrientationPortraitUpsideDown),
|
||||||
|
GKInterfaceOrientationMaskLandscape = (GKInterfaceOrientationMaskLandscapeLeft | GKInterfaceOrientationMaskLandscapeRight),
|
||||||
|
GKInterfaceOrientationMaskAll = (GKInterfaceOrientationMaskPortrait | GKInterfaceOrientationMaskLandscapeLeft | GKInterfaceOrientationMaskLandscapeRight | GKInterfaceOrientationMaskPortraitUpsideDown),
|
||||||
|
GKInterfaceOrientationMaskAllButUpsideDown = (GKInterfaceOrientationMaskPortrait | GKInterfaceOrientationMaskLandscapeLeft | GKInterfaceOrientationMaskLandscapeRight)
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GKRotationManager : NSObject
|
||||||
|
|
||||||
|
+ (GKInterfaceOrientationMask)supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window;
|
||||||
|
+ (instancetype)rotationManager;
|
||||||
|
- (instancetype)init NS_UNAVAILABLE;
|
||||||
|
- (instancetype)new NS_UNAVAILABLE;
|
||||||
|
|
||||||
|
/// 横屏时的window
|
||||||
|
@property (nonatomic, strong, nullable) GKLandscapeWindow *window;
|
||||||
|
|
||||||
|
/// 需要旋转的内容视图
|
||||||
|
@property (nonatomic, weak) UIView *contentView;
|
||||||
|
|
||||||
|
/// 旋转内容原来的父视图
|
||||||
|
@property (nonatomic, weak) UIView *containerView;
|
||||||
|
|
||||||
|
/// 是否允许自动旋转
|
||||||
|
@property (nonatomic, assign) BOOL allowOrientationRotation;
|
||||||
|
|
||||||
|
/// 自动旋转支持的方向
|
||||||
|
@property (nonatomic, assign) GKInterfaceOrientationMask supportInterfaceOrientation;
|
||||||
|
|
||||||
|
/// 当前的方向
|
||||||
|
@property (nonatomic, assign) UIInterfaceOrientation currentOrientation;
|
||||||
|
|
||||||
|
/// 是否全屏
|
||||||
|
@property (nonatomic, assign, readonly) BOOL isFullscreen;
|
||||||
|
|
||||||
|
/// 即将旋转回调
|
||||||
|
@property (nonatomic, copy, nullable) void(^orientationWillChange)(BOOL isFullscreen);
|
||||||
|
|
||||||
|
/// 结束旋转回调
|
||||||
|
@property (nonatomic, copy, nullable) void(^orientationDidChanged)(BOOL isFullscreen);
|
||||||
|
|
||||||
|
/// 旋转
|
||||||
|
- (void)rotate;
|
||||||
|
|
||||||
|
/// 旋转到指定方向
|
||||||
|
- (void)rotateToOrientation:(UIInterfaceOrientation)orientation animated:(BOOL)animated;
|
||||||
|
|
||||||
|
/// 旋转到指定方向
|
||||||
|
- (void)rotateToOrientation:(UIInterfaceOrientation)orientation animated:(BOOL)animated completion:(void(^ __nullable)(void))completion;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface GKRotationManager (Internal)
|
||||||
|
|
||||||
|
/// 当前设备方向
|
||||||
|
@property (nonatomic, assign, readonly) UIInterfaceOrientation currentDeviceOrientation;
|
||||||
|
|
||||||
|
/// 旋转时是否禁止动画
|
||||||
|
@property (nonatomic, assign) BOOL disableAnimations;
|
||||||
|
|
||||||
|
- (UIInterfaceOrientationMask)supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window;
|
||||||
|
|
||||||
|
- (UIInterfaceOrientation)getCurrentOrientation;
|
||||||
|
|
||||||
|
- (__kindof GKLandscapeViewController *)landscapeViewController;
|
||||||
|
|
||||||
|
- (void)interfaceOrientation:(UIInterfaceOrientation)orientation completion:(void (^ __nullable)(void))completion;
|
||||||
|
|
||||||
|
- (void)handleDeviceOrientationChange;
|
||||||
|
|
||||||
|
- (BOOL)isSupportInterfaceOrientation:(UIInterfaceOrientation)orientation;
|
||||||
|
|
||||||
|
- (void)willChangeOrientation:(UIInterfaceOrientation)orientation;
|
||||||
|
|
||||||
|
- (void)didChangeOrientation:(UIInterfaceOrientation)orientation;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
||||||
|
#pragma mark - fix safe area
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
typedef NS_OPTIONS(NSUInteger, GKSafeAreaInsetsMask) {
|
||||||
|
GKSafeAreaInsetsMaskNone = 0,
|
||||||
|
GKSafeAreaInsetsMaskTop = 1 << 0,
|
||||||
|
GKSafeAreaInsetsMaskLeft = 1 << 1,
|
||||||
|
GKSafeAreaInsetsMaskBottom = 1 << 2,
|
||||||
|
GKSafeAreaInsetsMaskRight = 1 << 3,
|
||||||
|
|
||||||
|
GKSafeAreaInsetsMaskHorizontal = GKSafeAreaInsetsMaskLeft | GKSafeAreaInsetsMaskRight,
|
||||||
|
GKSafeAreaInsetsMaskVertical = GKSafeAreaInsetsMaskTop | GKSafeAreaInsetsMaskBottom,
|
||||||
|
GKSafeAreaInsetsMaskAll = GKSafeAreaInsetsMaskHorizontal | GKSafeAreaInsetsMaskVertical
|
||||||
|
}API_DEPRECATED("deprecated!", ios(13.0, 16.0));
|
||||||
|
|
||||||
|
API_DEPRECATED("deprecated!", ios(13.0, 16.0)) @interface UIViewController (GKRotationSafeAreaFixing)
|
||||||
|
/// 禁止调整哪些方向的安全区域
|
||||||
|
@property (nonatomic) GKSafeAreaInsetsMask disabledAdjustSafeAreaInsetsMask;
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
275
HiBit/Project/Player/Common/GKRotationManager/GKRotationManager.m
Executable file
275
HiBit/Project/Player/Common/GKRotationManager/GKRotationManager.m
Executable file
@ -0,0 +1,275 @@
|
|||||||
|
//
|
||||||
|
// GKRotationManager.m
|
||||||
|
// Example
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/31.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKRotationManager.h"
|
||||||
|
#import "GKLandscapeWindow.h"
|
||||||
|
#import "GKLandscapeViewController.h"
|
||||||
|
#import "GKRotationManager_iOS_9_15.h"
|
||||||
|
#import "GKRotationManager_iOS_16_Later.h"
|
||||||
|
#import <objc/message.h>
|
||||||
|
|
||||||
|
@interface GKRotationManager()<GKLandscapeViewControllerDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL isGeneratingDeviceOrientation;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKRotationManager
|
||||||
|
|
||||||
|
+ (GKInterfaceOrientationMask)supportedInterfaceOrientationsForWindow:(UIWindow *)window {
|
||||||
|
if ([window isKindOfClass:GKLandscapeWindow.class]) {
|
||||||
|
GKRotationManager *manager = [(GKLandscapeWindow *)window rotationManager];
|
||||||
|
if (manager != nil) {
|
||||||
|
return (GKInterfaceOrientationMask)[manager supportedInterfaceOrientationsForWindow:window];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return GKInterfaceOrientationMaskUnknow;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (instancetype)rotationManager {
|
||||||
|
if (@available(iOS 16.0, *)) {
|
||||||
|
return [[GKRotationManager_iOS_16_Later alloc] _init];
|
||||||
|
}else {
|
||||||
|
return [[GKRotationManager_iOS_9_15 alloc] _init];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)_init {
|
||||||
|
if (self = [super init]) {
|
||||||
|
self.currentOrientation = UIInterfaceOrientationPortrait;
|
||||||
|
self.supportInterfaceOrientation = GKInterfaceOrientationMaskAll;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)addDeviceOrientationObserver {
|
||||||
|
self.isGeneratingDeviceOrientation = UIDevice.currentDevice.isGeneratingDeviceOrientationNotifications;
|
||||||
|
if (!self.isGeneratingDeviceOrientation) {
|
||||||
|
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
|
||||||
|
}
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDeviceOrientationChange) name:UIDeviceOrientationDidChangeNotification object:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)removeDeviceOrientationObserver {
|
||||||
|
if (!self.isGeneratingDeviceOrientation) {
|
||||||
|
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
|
||||||
|
}
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
#ifdef DEBUG
|
||||||
|
NSLog(@"%d -- [%@ %s]", (int)__LINE__, NSStringFromClass(self.class), sel_getName(_cmd));
|
||||||
|
#endif
|
||||||
|
[_window setHidden:YES];
|
||||||
|
[self removeDeviceOrientationObserver];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setAllowOrientationRotation:(BOOL)allowOrientationRotation {
|
||||||
|
_allowOrientationRotation = allowOrientationRotation;
|
||||||
|
|
||||||
|
if (allowOrientationRotation) {
|
||||||
|
[self addDeviceOrientationObserver];
|
||||||
|
}else {
|
||||||
|
[self removeDeviceOrientationObserver];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIInterfaceOrientation)currentDeviceOrientation {
|
||||||
|
return (UIInterfaceOrientation)UIDevice.currentDevice.orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)rotate {
|
||||||
|
UIInterfaceOrientation orientation = self.currentOrientation == UIInterfaceOrientationPortrait ? UIInterfaceOrientationLandscapeRight : UIInterfaceOrientationPortrait;
|
||||||
|
[self rotateToOrientation:orientation animated:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)rotateToOrientation:(UIInterfaceOrientation)orientation animated:(BOOL)animated {
|
||||||
|
[self rotateToOrientation:orientation animated:animated completion:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)rotateToOrientation:(UIInterfaceOrientation)orientation animated:(BOOL)animated completion:(void (^)(void))completion {
|
||||||
|
self.currentOrientation = orientation;
|
||||||
|
if (UIInterfaceOrientationIsLandscape(orientation)) {
|
||||||
|
if (!self.window) {
|
||||||
|
self.window = [[GKLandscapeWindow alloc] init];
|
||||||
|
self.window.rootViewController = self.landscapeViewController;
|
||||||
|
self.window.rotationManager = self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.disableAnimations = !animated;
|
||||||
|
if (UIDevice.currentDevice.systemVersion.doubleValue < 16.0) {
|
||||||
|
[self interfaceOrientation:UIInterfaceOrientationUnknown completion:nil];
|
||||||
|
}
|
||||||
|
[self interfaceOrientation:orientation completion:completion];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKRotationManager (Internal)
|
||||||
|
|
||||||
|
@dynamic disableAnimations;
|
||||||
|
|
||||||
|
- (void)setDisableAnimations:(BOOL)disableAnimations {
|
||||||
|
objc_setAssociatedObject(self, @selector(disableAnimations), @(disableAnimations), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)disableAnimations {
|
||||||
|
return [objc_getAssociatedObject(self, _cmd) boolValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIInterfaceOrientationMask)supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window {
|
||||||
|
@throw [NSException exceptionWithName:NSInternalInconsistencyException
|
||||||
|
reason:[NSString stringWithFormat:@"You must override %@ in a subclass.", NSStringFromSelector(_cmd)]
|
||||||
|
userInfo:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIInterfaceOrientation)getCurrentOrientation {
|
||||||
|
if (@available(iOS 16.0, *)) {
|
||||||
|
NSArray *array = UIApplication.sharedApplication.connectedScenes.allObjects;
|
||||||
|
UIWindowScene *scene = array.firstObject;
|
||||||
|
return scene.interfaceOrientation;
|
||||||
|
}else {
|
||||||
|
return self.currentDeviceOrientation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKLandscapeViewController *)landscapeViewController {
|
||||||
|
@throw [NSException exceptionWithName:NSInternalInconsistencyException
|
||||||
|
reason:[NSString stringWithFormat:@"You must override %@ in a subclass.", NSStringFromSelector(_cmd)]
|
||||||
|
userInfo:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)interfaceOrientation:(UIInterfaceOrientation)orientation completion:(void (^)(void))completion {
|
||||||
|
// subclass implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handleDeviceOrientationChange {
|
||||||
|
if (!self.allowOrientationRotation) return;
|
||||||
|
if (!UIDeviceOrientationIsValidInterfaceOrientation([UIDevice currentDevice].orientation)) return;
|
||||||
|
UIInterfaceOrientation currentOrientation = self.currentDeviceOrientation;
|
||||||
|
if (currentOrientation == self.currentOrientation) return;
|
||||||
|
self.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isSupportInterfaceOrientation:(UIInterfaceOrientation)orientation {
|
||||||
|
if (orientation == UIInterfaceOrientationPortrait) {
|
||||||
|
return [self _isSupportedPortrait];
|
||||||
|
}else if (orientation == UIInterfaceOrientationLandscapeLeft) {
|
||||||
|
return [self _isSupportedLandscapeLeft];
|
||||||
|
}else if (orientation == UIInterfaceOrientationLandscapeRight) {
|
||||||
|
return [self _isSupportedLandscapeRight];
|
||||||
|
}else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
|
||||||
|
return [self _isSupportedPortraitUpsideDown];
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)willChangeOrientation:(UIInterfaceOrientation)orientation {
|
||||||
|
_isFullscreen = UIInterfaceOrientationIsLandscape(orientation);
|
||||||
|
!self.orientationWillChange ?: self.orientationWillChange(_isFullscreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)didChangeOrientation:(UIInterfaceOrientation)orientation {
|
||||||
|
_isFullscreen = UIInterfaceOrientationIsLandscape(orientation);
|
||||||
|
!self.orientationDidChanged ?: self.orientationDidChanged(_isFullscreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)_isSupportedPortrait {
|
||||||
|
return self.supportInterfaceOrientation & GKInterfaceOrientationMaskPortrait;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)_isSupportedPortraitUpsideDown {
|
||||||
|
return self.supportInterfaceOrientation & GKInterfaceOrientationMaskPortraitUpsideDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)_isSupportedLandscapeLeft {
|
||||||
|
return self.supportInterfaceOrientation & GKInterfaceOrientationMaskLandscapeLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)_isSupportedLandscapeRight {
|
||||||
|
return self.supportInterfaceOrientation & GKInterfaceOrientationMaskLandscapeRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark - fix safe area
|
||||||
|
|
||||||
|
API_DEPRECATED("deprecated!", ios(13.0, 16.0)) @implementation GKRotationManager (GKRotationSafeAreaFixing)
|
||||||
|
+ (void)initialize {
|
||||||
|
if (@available(iOS 16.0, *)) return;
|
||||||
|
if (@available(iOS 13.0, *)) {
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
Class cls = UIViewController.class;
|
||||||
|
NSData *data = [NSData.alloc initWithBase64EncodedString:@"X3NldENvbnRlbnRPdmVybGF5SW5zZXRzOmFuZExlZnRNYXJnaW46cmlnaHRNYXJnaW46" options:kNilOptions];
|
||||||
|
NSString *method = [NSString.alloc initWithData:data encoding:NSUTF8StringEncoding];
|
||||||
|
SEL originalSelector = NSSelectorFromString(method);
|
||||||
|
SEL swizzledSelector = NSSelectorFromString([@"gk" stringByAppendingString:method]);
|
||||||
|
|
||||||
|
Method originalMethod = class_getInstanceMethod(cls, originalSelector);
|
||||||
|
Method swizzledMethod = class_getInstanceMethod(cls, swizzledSelector);
|
||||||
|
if ( originalMethod != NULL ) method_exchangeImplementations(originalMethod, swizzledMethod);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
API_DEPRECATED("deprecated!", ios(13.0, 16.0)) @implementation UIViewController (GKRotationSafeAreaFixing)
|
||||||
|
- (void)gk_setContentOverlayInsets:(UIEdgeInsets)insets andLeftMargin:(CGFloat)leftMargin rightMargin:(CGFloat)rightMargin {
|
||||||
|
GKSafeAreaInsetsMask mask = self.disabledAdjustSafeAreaInsetsMask;
|
||||||
|
if (mask & GKSafeAreaInsetsMaskTop) insets.top = 0;
|
||||||
|
if (mask & GKSafeAreaInsetsMaskLeft) insets.left = 0;
|
||||||
|
if (mask & GKSafeAreaInsetsMaskBottom) insets.bottom = 0;
|
||||||
|
if (mask & GKSafeAreaInsetsMaskRight) insets.right = 0;
|
||||||
|
|
||||||
|
UIWindow *keyWindow = UIApplication.sharedApplication.keyWindow;
|
||||||
|
UIWindow *otherWindow = self.view.window;
|
||||||
|
if ([keyWindow isKindOfClass:GKLandscapeWindow.class] && otherWindow != nil) {
|
||||||
|
GKRotationManager *manager = ((GKLandscapeWindow *)keyWindow).rotationManager;
|
||||||
|
UIWindow *superviewWindow = manager.containerView.window;
|
||||||
|
if (superviewWindow != otherWindow) {
|
||||||
|
[self gk_setContentOverlayInsets:insets andLeftMargin:leftMargin rightMargin:rightMargin];
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
[self gk_setContentOverlayInsets:insets andLeftMargin:leftMargin rightMargin:rightMargin];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setDisabledAdjustSafeAreaInsetsMask:(GKSafeAreaInsetsMask)disabledAdjustSafeAreaInsetsMask {
|
||||||
|
objc_setAssociatedObject(self, @selector(disabledAdjustSafeAreaInsetsMask), @(disabledAdjustSafeAreaInsetsMask), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKSafeAreaInsetsMask)disabledAdjustSafeAreaInsetsMask {
|
||||||
|
return [objc_getAssociatedObject(self, _cmd) integerValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// GKRotationManager_iOS_16_Later.h
|
||||||
|
// Example
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/31.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKRotationManager.h"
|
||||||
|
|
||||||
|
API_AVAILABLE(ios(16.0)) NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GKRotationManager_iOS_16_Later : GKRotationManager
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
139
HiBit/Project/Player/Common/GKRotationManager/GKRotationManager_iOS_16_Later.m
Executable file
139
HiBit/Project/Player/Common/GKRotationManager/GKRotationManager_iOS_16_Later.m
Executable file
@ -0,0 +1,139 @@
|
|||||||
|
//
|
||||||
|
// GKRotationManager_iOS_16_Later.m
|
||||||
|
// Example
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/31.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKRotationManager_iOS_16_Later.h"
|
||||||
|
#import "GKLandscapeViewController.h"
|
||||||
|
|
||||||
|
@interface GKRotationManager_iOS_16_Later()
|
||||||
|
|
||||||
|
@property (nonatomic, strong, readonly) GKLandscapeViewController *landscapeViewController;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKRotationManager_iOS_16_Later
|
||||||
|
@synthesize landscapeViewController = _landscapeViewController;
|
||||||
|
- (__kindof GKLandscapeViewController *)landscapeViewController {
|
||||||
|
if (!_landscapeViewController) {
|
||||||
|
_landscapeViewController = [[GKLandscapeViewController alloc] init];
|
||||||
|
}
|
||||||
|
return _landscapeViewController;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setNeedsUpdateOfSupportedInterfaceOrientations {
|
||||||
|
if (@available(iOS 16.0, *)) {
|
||||||
|
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 160000
|
||||||
|
[UIApplication.sharedApplication.keyWindow.rootViewController setNeedsUpdateOfSupportedInterfaceOrientations];
|
||||||
|
[self.window.rootViewController setNeedsUpdateOfSupportedInterfaceOrientations];
|
||||||
|
#else
|
||||||
|
[(id)UIApplication.sharedApplication.keyWindow.rootViewController setNeedsUpdateOfSupportedInterfaceOrientations];
|
||||||
|
[(id)self.window.rootViewController setNeedsUpdateOfSupportedInterfaceOrientations];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)interfaceOrientation:(UIInterfaceOrientation)orientation completion:(void (^)(void))completion {
|
||||||
|
[super interfaceOrientation:orientation completion:completion];
|
||||||
|
UIInterfaceOrientation fromOrientation = [self getCurrentOrientation];
|
||||||
|
UIInterfaceOrientation toOrientation = orientation;
|
||||||
|
[self willChangeOrientation:toOrientation];
|
||||||
|
self.currentOrientation = toOrientation;
|
||||||
|
|
||||||
|
UIWindow *sourceWindow = self.containerView.window;
|
||||||
|
CGRect sourceFrame = [self.containerView convertRect:self.containerView.bounds toView:sourceWindow];
|
||||||
|
CGRect screenBounds = UIScreen.mainScreen.bounds;
|
||||||
|
CGFloat maxSize = MAX(screenBounds.size.width, screenBounds.size.height);
|
||||||
|
CGFloat minSize = MIN(screenBounds.size.width, screenBounds.size.height);
|
||||||
|
|
||||||
|
self.contentView.autoresizingMask = UIViewAutoresizingNone;
|
||||||
|
if (fromOrientation == UIInterfaceOrientationPortrait || self.contentView.superview != self.landscapeViewController.view) {
|
||||||
|
self.contentView.frame = sourceFrame;
|
||||||
|
[sourceWindow addSubview:self.contentView];
|
||||||
|
[self.contentView layoutIfNeeded];
|
||||||
|
if (!self.window.isKeyWindow) {
|
||||||
|
self.window.hidden = NO;
|
||||||
|
[self.window makeKeyAndVisible];
|
||||||
|
}
|
||||||
|
}else if (toOrientation == UIInterfaceOrientationPortrait) {
|
||||||
|
[self.contentView removeFromSuperview];
|
||||||
|
self.contentView.bounds = CGRectMake(0, 0, maxSize, minSize);
|
||||||
|
self.contentView.center = CGPointMake(minSize * 0.5, maxSize * 0.5);
|
||||||
|
self.contentView.transform = [self getRotationTransform:fromOrientation];
|
||||||
|
[sourceWindow addSubview:self.contentView];
|
||||||
|
[self.contentView layoutIfNeeded];
|
||||||
|
[self.contentView snapshotViewAfterScreenUpdates:YES];
|
||||||
|
[UIView performWithoutAnimation:^{
|
||||||
|
[sourceWindow makeKeyAndVisible];
|
||||||
|
self.window.hidden = YES;
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
[self setNeedsUpdateOfSupportedInterfaceOrientations];
|
||||||
|
|
||||||
|
CGRect rotationBounds = CGRectZero;
|
||||||
|
CGPoint rotationCenter = CGPointZero;
|
||||||
|
if (UIInterfaceOrientationIsLandscape(toOrientation)) {
|
||||||
|
rotationBounds = CGRectMake(0, 0, maxSize, minSize);
|
||||||
|
rotationCenter = (fromOrientation == UIInterfaceOrientationPortrait || self.contentView.superview != self.landscapeViewController.view) ? CGPointMake(minSize * 0.5, maxSize * 0.5) : CGPointMake(maxSize * 0.5, minSize * 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
CGAffineTransform rotationTransform = CGAffineTransformIdentity;
|
||||||
|
if (fromOrientation == UIInterfaceOrientationPortrait) {
|
||||||
|
rotationTransform = [self getRotationTransform:toOrientation];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.disableAnimations) {
|
||||||
|
[CATransaction begin];
|
||||||
|
[CATransaction setDisableActions:YES];
|
||||||
|
}
|
||||||
|
[UIView animateWithDuration:0.3 animations:^{
|
||||||
|
if (toOrientation == UIInterfaceOrientationPortrait) {
|
||||||
|
self.contentView.transform = rotationTransform;
|
||||||
|
self.contentView.frame = sourceFrame;
|
||||||
|
}else {
|
||||||
|
self.contentView.transform = rotationTransform;
|
||||||
|
self.contentView.bounds = rotationBounds;
|
||||||
|
self.contentView.center = rotationCenter;
|
||||||
|
}
|
||||||
|
[self.contentView layoutIfNeeded];
|
||||||
|
} completion:^(BOOL finished) {
|
||||||
|
if (self.disableAnimations) {
|
||||||
|
[CATransaction commit];
|
||||||
|
}
|
||||||
|
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||||
|
if (toOrientation == UIInterfaceOrientationPortrait) {
|
||||||
|
[self.containerView addSubview:self.contentView];
|
||||||
|
self.contentView.frame = self.containerView.bounds;
|
||||||
|
}else {
|
||||||
|
[self setNeedsUpdateOfSupportedInterfaceOrientations];
|
||||||
|
self.contentView.transform = CGAffineTransformIdentity;
|
||||||
|
[self.landscapeViewController.view addSubview:self.contentView];
|
||||||
|
self.contentView.frame = self.window.bounds;
|
||||||
|
[self.contentView layoutIfNeeded];
|
||||||
|
}
|
||||||
|
!completion ?: completion();
|
||||||
|
[self didChangeOrientation:toOrientation];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIInterfaceOrientationMask)supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window {
|
||||||
|
if (window == self.window) {
|
||||||
|
return 1 << self.currentOrientation;
|
||||||
|
}
|
||||||
|
return UIInterfaceOrientationMaskPortrait;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGAffineTransform)getRotationTransform:(UIInterfaceOrientation)orientation {
|
||||||
|
CGAffineTransform rotationTransform = CGAffineTransformIdentity;
|
||||||
|
if (orientation == UIInterfaceOrientationLandscapeLeft) {
|
||||||
|
rotationTransform = CGAffineTransformMakeRotation(-M_PI_2);
|
||||||
|
} else if (orientation == UIInterfaceOrientationLandscapeRight) {
|
||||||
|
rotationTransform = CGAffineTransformMakeRotation(M_PI_2);
|
||||||
|
}
|
||||||
|
return rotationTransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
17
HiBit/Project/Player/Common/GKRotationManager/GKRotationManager_iOS_9_15.h
Executable file
17
HiBit/Project/Player/Common/GKRotationManager/GKRotationManager_iOS_9_15.h
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// GKRotationManager_iOS_9_15.h
|
||||||
|
// Example
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/31.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKRotationManager.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
API_DEPRECATED("deprecated!", ios(9.0, 16.0)) @interface GKRotationManager_iOS_9_15 : GKRotationManager
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
177
HiBit/Project/Player/Common/GKRotationManager/GKRotationManager_iOS_9_15.m
Executable file
177
HiBit/Project/Player/Common/GKRotationManager/GKRotationManager_iOS_9_15.m
Executable file
@ -0,0 +1,177 @@
|
|||||||
|
//
|
||||||
|
// GKRotationManager_iOS_9_15.m
|
||||||
|
// Example
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/31.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKRotationManager_iOS_9_15.h"
|
||||||
|
#import "GKLandscapeViewController.h"
|
||||||
|
|
||||||
|
API_DEPRECATED("deprecated!", ios(9.0, 16.0)) @interface GKLandscapeViewController_iOS_9_15 : GKLandscapeViewController
|
||||||
|
@property (nonatomic, strong, readonly) UIView *playerSuperview;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKLandscapeViewController_iOS_9_15
|
||||||
|
|
||||||
|
- (void)viewDidLoad {
|
||||||
|
[super viewDidLoad];
|
||||||
|
_playerSuperview = [[UIView alloc] initWithFrame:CGRectZero];
|
||||||
|
_playerSuperview.backgroundColor = UIColor.clearColor;
|
||||||
|
[self.view addSubview:_playerSuperview];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)shouldAutorotate {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(viewControllerShouldAutorotate:)]) {
|
||||||
|
return [self.delegate viewControllerShouldAutorotate:self];
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
|
||||||
|
return UIInterfaceOrientationMaskAllButUpsideDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface GKRotationManager_iOS_9_15()<GKLandscapeViewControllerDelegate> {
|
||||||
|
void(^_rotateCompleted)(void);
|
||||||
|
}
|
||||||
|
|
||||||
|
@property (nonatomic, strong, readonly) GKLandscapeViewController_iOS_9_15 *landscapeViewController;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL forceRotation;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKRotationManager_iOS_9_15
|
||||||
|
|
||||||
|
@synthesize landscapeViewController = _landscapeViewController;
|
||||||
|
- (GKLandscapeViewController *)landscapeViewController {
|
||||||
|
if (!_landscapeViewController) {
|
||||||
|
_landscapeViewController = [[GKLandscapeViewController_iOS_9_15 alloc] init];
|
||||||
|
_landscapeViewController.delegate = self;
|
||||||
|
}
|
||||||
|
return _landscapeViewController;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)interfaceOrientation:(UIInterfaceOrientation)orientation completion:(void (^)(void))completion {
|
||||||
|
[super interfaceOrientation:orientation completion:completion];
|
||||||
|
_rotateCompleted = completion;
|
||||||
|
self.forceRotation = YES;
|
||||||
|
[UIDevice.currentDevice setValue:@(UIDeviceOrientationUnknown) forKey:@"orientation"];
|
||||||
|
[UIDevice.currentDevice setValue:@(orientation) forKey:@"orientation"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)rotationBegin {
|
||||||
|
if (self.window.isHidden) {
|
||||||
|
self.window.hidden = NO;
|
||||||
|
[self.window makeKeyAndVisible];
|
||||||
|
}
|
||||||
|
[UIView animateWithDuration:0.0 animations:^{} completion:^(BOOL finished) {
|
||||||
|
[self.window.rootViewController setNeedsStatusBarAppearanceUpdate];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)rotationEnd {
|
||||||
|
if (!self.window.isHidden && !UIInterfaceOrientationIsLandscape(self.currentOrientation)) {
|
||||||
|
self.window.hidden = YES;
|
||||||
|
[self.containerView.window makeKeyAndVisible];
|
||||||
|
}
|
||||||
|
self.disableAnimations = NO;
|
||||||
|
if (_rotateCompleted) {
|
||||||
|
_rotateCompleted();
|
||||||
|
_rotateCompleted = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)allowsRotation {
|
||||||
|
if (UIDeviceOrientationIsValidInterfaceOrientation(UIDevice.currentDevice.orientation)) {
|
||||||
|
UIInterfaceOrientation toOrientation = self.currentDeviceOrientation;
|
||||||
|
if (![self isSupportInterfaceOrientation:toOrientation]) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (self.forceRotation) return YES;
|
||||||
|
if (self.allowOrientationRotation) return YES;
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - GKLandscapeViewControllerDelegate
|
||||||
|
- (BOOL)viewControllerShouldAutorotate:(GKLandscapeViewController *)viewController {
|
||||||
|
if ([self allowsRotation]) {
|
||||||
|
[self rotationBegin];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewController:(GKLandscapeViewController *)viewController viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
|
||||||
|
UIInterfaceOrientation toOrientation = self.currentDeviceOrientation;
|
||||||
|
if (![self isSupportInterfaceOrientation:toOrientation]) return;
|
||||||
|
[self willChangeOrientation:toOrientation];
|
||||||
|
self.currentOrientation = toOrientation;
|
||||||
|
if (self.currentOrientation != UIInterfaceOrientationPortrait) {
|
||||||
|
if (self.contentView.superview != self.landscapeViewController.playerSuperview) {
|
||||||
|
CGRect frame = [self.contentView convertRect:self.contentView.bounds toView:self.contentView.window];
|
||||||
|
self.landscapeViewController.playerSuperview.frame = frame;
|
||||||
|
self.contentView.frame = CGRectMake(0, 0, frame.size.width, frame.size.height);
|
||||||
|
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||||
|
[self.landscapeViewController.playerSuperview addSubview:self.contentView];
|
||||||
|
[self.contentView layoutIfNeeded];
|
||||||
|
}
|
||||||
|
if (self.disableAnimations) {
|
||||||
|
[CATransaction begin];
|
||||||
|
[CATransaction setDisableActions:YES];
|
||||||
|
}
|
||||||
|
[UIView animateWithDuration:0.0 animations:^{ /** preparing */} completion:^(BOOL finished) {
|
||||||
|
[UIView animateWithDuration:0.3 animations:^{
|
||||||
|
self.landscapeViewController.playerSuperview.frame = (CGRect){CGPointZero, size};
|
||||||
|
[self.contentView layoutIfNeeded];
|
||||||
|
} completion:^(BOOL finished) {
|
||||||
|
if (self.disableAnimations) {
|
||||||
|
[CATransaction commit];
|
||||||
|
}
|
||||||
|
self.forceRotation = NO;
|
||||||
|
[self rotationEnd];
|
||||||
|
[self didChangeOrientation:toOrientation];
|
||||||
|
}];
|
||||||
|
}];
|
||||||
|
}else {
|
||||||
|
if (self.disableAnimations) {
|
||||||
|
[CATransaction begin];
|
||||||
|
[CATransaction setDisableActions:YES];
|
||||||
|
}
|
||||||
|
[UIView animateWithDuration:0.0 animations:^{ /** preparing */ } completion:^(BOOL finished) {
|
||||||
|
[UIView animateWithDuration:0.3 animations:^{
|
||||||
|
self.landscapeViewController.playerSuperview.frame = [self.containerView convertRect:self.containerView.bounds toView:self.containerView.window];
|
||||||
|
[self.contentView layoutIfNeeded];
|
||||||
|
} completion:^(BOOL finished) {
|
||||||
|
if (self.disableAnimations) {
|
||||||
|
[CATransaction commit];
|
||||||
|
}
|
||||||
|
self.forceRotation = NO;
|
||||||
|
UIView *snapshot = [self.contentView snapshotViewAfterScreenUpdates:NO];
|
||||||
|
snapshot.frame = self.containerView.bounds;
|
||||||
|
snapshot.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||||
|
[self.containerView addSubview:snapshot];
|
||||||
|
[UIView animateWithDuration:0.0 animations:^{} completion:^(BOOL finished) {
|
||||||
|
self.contentView.frame = self.containerView.bounds;
|
||||||
|
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||||
|
[self.containerView addSubview:self.contentView];
|
||||||
|
[self.contentView layoutIfNeeded];
|
||||||
|
[snapshot removeFromSuperview];
|
||||||
|
[self rotationEnd];
|
||||||
|
[self didChangeOrientation:toOrientation];
|
||||||
|
}];
|
||||||
|
}];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIInterfaceOrientationMask)supportedInterfaceOrientationsForWindow:(UIWindow *)window {
|
||||||
|
return UIInterfaceOrientationMaskAllButUpsideDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
84
HiBit/Project/Player/Manager/GKDYPlayerManager.h
Executable file
84
HiBit/Project/Player/Manager/GKDYPlayerManager.h
Executable file
@ -0,0 +1,84 @@
|
|||||||
|
//
|
||||||
|
// GKDYPlayerManager.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/17.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "GKDYVideoScrollView.h"
|
||||||
|
#import "GKDYVideoPortraitView.h"
|
||||||
|
#import "GKDYVideoLandscapeView.h"
|
||||||
|
#import <ZFPlayer/ZFPlayer.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@class GKDYVideoCell, GKDYVideoPortraitCell, GKDYVideoLandscapeCell;
|
||||||
|
|
||||||
|
@protocol GKDYPlayerManagerDelegate <NSObject>
|
||||||
|
|
||||||
|
- (void)scrollViewShouldLoadMore;
|
||||||
|
|
||||||
|
- (void)scrollViewDidPanDistance:(CGFloat)distance isEnd:(BOOL)isEnd;
|
||||||
|
|
||||||
|
- (void)celldidClickShare:(GKDYVideoModel *)model cell:(GKDYVideoPortraitCell *)cell;
|
||||||
|
- (void)celldidClickEpiscode:(GKDYVideoModel *)model cell:(GKDYVideoPortraitCell *)cell;
|
||||||
|
- (void)celldidClickFavorite:(GKDYVideoModel *)model cell:(GKDYVideoPortraitCell *)cell;
|
||||||
|
- (void)cellZoomBegan:(GKDYVideoModel *)model;
|
||||||
|
- (void)cellZoomEnded:(GKDYVideoModel *)model isFullscreen:(BOOL)isFullscreen;
|
||||||
|
- (void)cellSwitchWithModel:(GKDYVideoModel *)model;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface GKDYPlayerManager : NSObject
|
||||||
|
|
||||||
|
@property (nonatomic, strong, readonly) ZFPlayerController *player;
|
||||||
|
|
||||||
|
@property (nonatomic, weak) id<GKDYPlayerManagerDelegate> delegate;
|
||||||
|
|
||||||
|
// 竖屏滑动容器
|
||||||
|
@property (nonatomic, strong) GKDYVideoScrollView *scrollView;
|
||||||
|
|
||||||
|
// 横屏滑动容器
|
||||||
|
@property (nonatomic, strong, nullable) GKDYVideoScrollView *landscapeScrollView;
|
||||||
|
|
||||||
|
@property (nonatomic, weak) GKDYVideoPortraitCell *currentCell;
|
||||||
|
|
||||||
|
@property (nonatomic, weak) GKDYVideoLandscapeCell *landscapeCell;
|
||||||
|
|
||||||
|
// 竖屏控制层
|
||||||
|
@property (nonatomic, weak) GKDYVideoPortraitView *portraitView;
|
||||||
|
|
||||||
|
// 横屏控制层
|
||||||
|
@property (nonatomic, strong) GKDYVideoLandscapeView *landscapeView;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) CGSize videoSize;
|
||||||
|
|
||||||
|
/// 页码
|
||||||
|
@property (nonatomic, assign) NSInteger page;
|
||||||
|
|
||||||
|
/// 数据源
|
||||||
|
@property (nonatomic, strong) NSMutableArray *dataSources;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL isPlaying;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL isAppeared;
|
||||||
|
|
||||||
|
/// 请求播放地址
|
||||||
|
- (void)requestPlayUrlWithModel:(GKDYVideoModel *)model completion:(nullable void(^)(void))completion;
|
||||||
|
|
||||||
|
/// 播放视频
|
||||||
|
- (void)playVideoWithCell:(GKDYVideoCell *)cell index:(NSInteger)index;
|
||||||
|
|
||||||
|
/// 停止播放
|
||||||
|
- (void)stopPlayWithCell:(GKDYVideoCell *)cell index:(NSInteger)index;
|
||||||
|
|
||||||
|
/// 旋转
|
||||||
|
- (void)rotate;
|
||||||
|
|
||||||
|
- (void)play;
|
||||||
|
- (void)pause;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
504
HiBit/Project/Player/Manager/GKDYPlayerManager.m
Executable file
504
HiBit/Project/Player/Manager/GKDYPlayerManager.m
Executable file
@ -0,0 +1,504 @@
|
|||||||
|
//
|
||||||
|
// GKDYPlayerManager.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/17.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYPlayerManager.h"
|
||||||
|
#import <AFNetworking/AFNetworking.h>
|
||||||
|
#import <ZFPlayer/ZFPlayer.h>
|
||||||
|
#import <ZFPlayer/ZFAVPlayerManager.h>
|
||||||
|
#import "GKDYVideoCell.h"
|
||||||
|
#import "GKRotationManager.h"
|
||||||
|
#import "GKDYVideoPortraitCell.h"
|
||||||
|
#import "GKDYVideoLandscapeCell.h"
|
||||||
|
#import "GKDYVideoFullscreenView.h"
|
||||||
|
|
||||||
|
@interface GKDYPlayerManager()<GKVideoScrollViewDataSource, GKDYVideoScrollViewDelegate, GKDYVideoPortraitCellDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic, strong) ZFPlayerController *player;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) GKRotationManager *rotationManager;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL isSeeking;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) GKDYVideoFullscreenView *fullscreenView;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKDYPlayerManager
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
if (self = [super init]) {
|
||||||
|
[self initPlayer];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
NSLog(@"GKDYPlayerManager dealloc");
|
||||||
|
[self stop];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)initPlayer {
|
||||||
|
// 初始化播放器
|
||||||
|
ZFAVPlayerManager *manager = [[ZFAVPlayerManager alloc] init];
|
||||||
|
|
||||||
|
ZFPlayerController *player = [[ZFPlayerController alloc] init];
|
||||||
|
player.shouldAutoPlay = YES;
|
||||||
|
player.currentPlayerManager = manager;
|
||||||
|
player.disableGestureTypes = ZFPlayerDisableGestureTypesPan | ZFPlayerDisableGestureTypesPinch;
|
||||||
|
player.allowOrentitaionRotation = NO; // 禁止自动旋转
|
||||||
|
self.player = player;
|
||||||
|
|
||||||
|
@weakify(self);
|
||||||
|
// 播放结束回调
|
||||||
|
player.playerDidToEnd = ^(id<ZFPlayerMediaPlayback> _Nonnull asset) {
|
||||||
|
@strongify(self);
|
||||||
|
[self.scrollView scrollToNextPage];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 播放失败回调
|
||||||
|
player.playerPlayFailed = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, id _Nonnull error) {
|
||||||
|
@strongify(self);
|
||||||
|
self.portraitView.resumeButton.hidden = NO;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
player.playerLoadStateChanged = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, ZFPlayerLoadState loadState) {
|
||||||
|
@strongify(self);
|
||||||
|
if ((loadState == ZFPlayerLoadStatePrepare || loadState == ZFPlayerLoadStateStalled) && self.player.currentPlayerManager.isPlaying) {
|
||||||
|
[self.portraitView.slider showLoading];
|
||||||
|
}else {
|
||||||
|
[self.portraitView.slider hideLoading];
|
||||||
|
// [self.player.currentPlayerManager play];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 播放时间
|
||||||
|
player.playerPlayTimeChanged = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, NSTimeInterval currentTime, NSTimeInterval duration) {
|
||||||
|
@strongify(self);
|
||||||
|
[self.portraitView.slider updateCurrentTime:currentTime totalTime:duration];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 方向即将改变
|
||||||
|
player.orientationWillChange = ^(ZFPlayerController * _Nonnull player, BOOL isFullScreen) {
|
||||||
|
@strongify(self);
|
||||||
|
self.player.controlView.hidden = YES;
|
||||||
|
if (player.isFullScreen) {
|
||||||
|
[self.landscapeView startTimer];
|
||||||
|
}else {
|
||||||
|
[self.landscapeView destoryTimer];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 方向已经改变
|
||||||
|
player.orientationDidChanged = ^(ZFPlayerController * _Nonnull player, BOOL isFullScreen) {
|
||||||
|
@strongify(self);
|
||||||
|
if (isFullScreen) {
|
||||||
|
self.landscapeView.hidden = NO;
|
||||||
|
self.player.controlView = self.landscapeView;
|
||||||
|
}else {
|
||||||
|
self.portraitView.hidden = NO;
|
||||||
|
self.player.controlView = self.portraitView;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.rotationManager = [GKRotationManager rotationManager];
|
||||||
|
self.rotationManager.contentView = self.player.currentPlayerManager.view;
|
||||||
|
self.landscapeView.rotationManager = self.rotationManager;
|
||||||
|
|
||||||
|
// 即将旋转时调用
|
||||||
|
self.rotationManager.orientationWillChange = ^(BOOL isFullscreen) {
|
||||||
|
@strongify(self);
|
||||||
|
self.player.controlView.hidden = YES;
|
||||||
|
if (isFullscreen) {
|
||||||
|
[self.landscapeView startTimer];
|
||||||
|
}else {
|
||||||
|
self.player.currentPlayerManager.view.backgroundColor = UIColor.clearColor;
|
||||||
|
self.portraitView.hidden = NO;
|
||||||
|
[self.landscapeView destoryTimer];
|
||||||
|
if (self.landscapeScrollView) {
|
||||||
|
UIView *superview = self.landscapeScrollView.superview;
|
||||||
|
[superview addSubview:self.rotationManager.contentView];
|
||||||
|
[self.landscapeScrollView removeFromSuperview];
|
||||||
|
self.landscapeScrollView = nil;
|
||||||
|
self.landscapeCell = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 旋转结束时调用
|
||||||
|
self.rotationManager.orientationDidChanged = ^(BOOL isFullscreen) {
|
||||||
|
@strongify(self);
|
||||||
|
if (isFullscreen) {
|
||||||
|
// self.portraitView.hidden = YES;
|
||||||
|
self.landscapeView.hidden = NO;
|
||||||
|
[self.landscapeView hideContainerView:NO];
|
||||||
|
if (!self.landscapeScrollView) {
|
||||||
|
[self initLandscapeScrollView];
|
||||||
|
UIView *superview = self.rotationManager.contentView.superview;
|
||||||
|
self.landscapeScrollView.frame = superview.bounds;
|
||||||
|
[superview addSubview:self.landscapeScrollView];
|
||||||
|
self.landscapeScrollView.defaultIndex = self.scrollView.currentIndex;
|
||||||
|
[self.landscapeScrollView reloadData];
|
||||||
|
}
|
||||||
|
self.player.controlView = self.landscapeView;
|
||||||
|
[self.currentCell resetView];
|
||||||
|
[self.landscapeCell hideTopView];
|
||||||
|
}else {
|
||||||
|
self.portraitView.hidden = NO;
|
||||||
|
self.landscapeView.hidden = YES;
|
||||||
|
self.player.controlView = self.portraitView;
|
||||||
|
if (self.player.containerView != self.currentCell.coverImgView) {
|
||||||
|
self.player.containerView = self.currentCell.coverImgView;
|
||||||
|
}
|
||||||
|
self.player.currentPlayerManager.view.backgroundColor = UIColor.blackColor;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
player.presentationSizeChanged = ^(id<ZFPlayerMediaPlayback> _Nonnull asset, CGSize size) {
|
||||||
|
@strongify(self);
|
||||||
|
self.videoSize = size;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)initLandscapeScrollView {
|
||||||
|
self.landscapeScrollView = [[GKDYVideoScrollView alloc] init];
|
||||||
|
self.landscapeScrollView.backgroundColor = UIColor.blackColor;
|
||||||
|
self.landscapeScrollView.dataSource = self;
|
||||||
|
self.landscapeScrollView.delegate = self;
|
||||||
|
[self.landscapeScrollView registerClass:GKDYVideoLandscapeCell.class forCellReuseIdentifier:@"GKDYVideoLandscapeCell"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isPlaying {
|
||||||
|
return self.player.currentPlayerManager.isPlaying;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)requestPlayUrlWithModel:(GKDYVideoModel *)model completion:(nullable void (^)(void))completion {
|
||||||
|
if (model.videoInfo.video_url.length > 0) return;
|
||||||
|
|
||||||
|
// if (model.task) {
|
||||||
|
// [model.task cancel];
|
||||||
|
// model.task = nil;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
|
||||||
|
//
|
||||||
|
// NSString *url = [NSString stringWithFormat:@"https://haokan.baidu.com/v?vid=%@&_format=json&", model.video_id];
|
||||||
|
//
|
||||||
|
// model.task = [manager GET:url parameters:nil headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
|
||||||
|
// if ([responseObject[@"errno"] integerValue] == 0) {
|
||||||
|
// NSDictionary *videoMeta = responseObject[@"data"][@"apiData"][@"curVideoMeta"];
|
||||||
|
// model.play_url = videoMeta[@"playurl"];
|
||||||
|
// model.comment = videoMeta[@"comment"];
|
||||||
|
// model.like = videoMeta[@"fmlike_num"];
|
||||||
|
//
|
||||||
|
// __block NSInteger index = 0;
|
||||||
|
// __block BOOL exist = NO;
|
||||||
|
// [self.dataSources enumerateObjectsUsingBlock:^(GKDYVideoModel *obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||||
|
// if ([obj.video_id isEqualToString:model.video_id]) {
|
||||||
|
// index = idx;
|
||||||
|
// exist = YES;
|
||||||
|
// *stop = YES;
|
||||||
|
// }
|
||||||
|
// }];
|
||||||
|
// [self.dataSources replaceObjectAtIndex:index withObject:model];
|
||||||
|
// model.task = nil;
|
||||||
|
// !completion ?: completion();
|
||||||
|
// }
|
||||||
|
// } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
|
||||||
|
// model.task = nil;
|
||||||
|
// NSLog(@"播放地址请求失败");
|
||||||
|
// }];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)playVideoWithCell:(GKDYVideoCell *)cell index:(NSInteger)index {
|
||||||
|
if (self.dataSources.count - index < 2) {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(scrollViewShouldLoadMore)]) {
|
||||||
|
[self.delegate scrollViewShouldLoadMore];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GKDYVideoModel *model = self.dataSources[index];
|
||||||
|
|
||||||
|
self.landscapeView.model = model;
|
||||||
|
|
||||||
|
if ([cell isKindOfClass:GKDYVideoPortraitCell.class]) {
|
||||||
|
self.currentCell = (GKDYVideoPortraitCell *)cell;
|
||||||
|
self.portraitView = self.currentCell.portraitView;
|
||||||
|
self.rotationManager.containerView = cell.coverImgView;
|
||||||
|
if (self.rotationManager.isFullscreen) return;
|
||||||
|
}else {
|
||||||
|
self.landscapeCell = (GKDYVideoLandscapeCell *)cell;
|
||||||
|
[self.landscapeCell autoHide];
|
||||||
|
[self.scrollView scrollToPageWithIndex:index];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置播放内容视图
|
||||||
|
if (self.player.containerView != cell.coverImgView) {
|
||||||
|
self.player.containerView = cell.coverImgView;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置播放器控制层视图
|
||||||
|
if ([cell isKindOfClass:GKDYVideoPortraitCell.class]) {
|
||||||
|
GKDYVideoPortraitCell *portraitCell = (GKDYVideoPortraitCell *)cell;
|
||||||
|
if (self.player.controlView != portraitCell.portraitView) {
|
||||||
|
self.player.controlView = portraitCell.portraitView;
|
||||||
|
self.portraitView = portraitCell.portraitView;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置封面图片
|
||||||
|
id<ZFPlayerMediaPlayback> manager = self.player.currentPlayerManager;
|
||||||
|
[manager.view.coverImageView sd_setImageWithURL:[NSURL URLWithString:model.image_url]];
|
||||||
|
|
||||||
|
if (model.videoInfo.video_url.length > 0) {
|
||||||
|
// 播放内容一致,不做处理
|
||||||
|
if ([self.player.assetURL.absoluteString isEqualToString:model.videoInfo.video_url]) return;
|
||||||
|
|
||||||
|
// 设置播放地址
|
||||||
|
self.player.assetURL = [NSURL URLWithString:model.videoInfo.video_url];
|
||||||
|
self.portraitView.resumeButton.hidden = YES;
|
||||||
|
if (self.isAppeared) {
|
||||||
|
[self.player.currentPlayerManager play];
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
@weakify(self);
|
||||||
|
[self requestPlayUrlWithModel:model completion:^{
|
||||||
|
@strongify(self);
|
||||||
|
// 播放内容一致,不做处理
|
||||||
|
if ([self.player.assetURL.absoluteString isEqualToString:model.videoInfo.video_url]) return;
|
||||||
|
|
||||||
|
// 设置播放地址
|
||||||
|
self.player.assetURL = [NSURL URLWithString:model.videoInfo.video_url];
|
||||||
|
self.portraitView.resumeButton.hidden = YES;
|
||||||
|
if (self.isAppeared) {
|
||||||
|
[self.player.currentPlayerManager play];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)stopPlayWithCell:(GKDYVideoCell *)cell index:(NSInteger)index {
|
||||||
|
GKDYVideoModel *model = self.dataSources[index];
|
||||||
|
if (![self.player.assetURL.absoluteString isEqualToString:model.videoInfo.video_url]) return;
|
||||||
|
|
||||||
|
[self.player stop];
|
||||||
|
if ([self.player.controlView isKindOfClass:GKDYVideoPortraitView.class]) {
|
||||||
|
[self.player.controlView removeFromSuperview];
|
||||||
|
self.player.controlView = nil;
|
||||||
|
}
|
||||||
|
[cell resetView];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)rotate {
|
||||||
|
[self.rotationManager rotate];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)play {
|
||||||
|
if (self.isPlaying) return;
|
||||||
|
[self.player.currentPlayerManager play];
|
||||||
|
// [self.currentCell.portraitView handleSingleTapped];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)pause {
|
||||||
|
if (!self.isPlaying) return;
|
||||||
|
[self.player.currentPlayerManager pause];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)stop {
|
||||||
|
[self.player.currentPlayerManager stop];
|
||||||
|
self.player = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Private
|
||||||
|
- (void)likeVideoWithModel:(GKDYVideoModel *)model {
|
||||||
|
if (model == nil) {
|
||||||
|
model = self.currentCell.model;
|
||||||
|
}
|
||||||
|
model.is_collect = YES;
|
||||||
|
[self.scrollView reloadData];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - GKVideoScrollViewDataSource
|
||||||
|
- (NSInteger)numberOfRowsInScrollView:(GKVideoScrollView *)scrollView {
|
||||||
|
return self.dataSources.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKVideoViewCell *)scrollView:(GKVideoScrollView *)scrollView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
GKDYVideoModel *model = self.dataSources[indexPath.row];
|
||||||
|
if (scrollView == self.scrollView) {
|
||||||
|
GKDYVideoPortraitCell *cell = [scrollView dequeueReusableCellWithIdentifier:@"GKDYVideoPortraitCell" forIndexPath:indexPath];
|
||||||
|
cell.delegate = self;
|
||||||
|
cell.manager = self;
|
||||||
|
cell.portraitView.slider.player = self.player;
|
||||||
|
[cell loadData:model];
|
||||||
|
return cell;
|
||||||
|
}else {
|
||||||
|
GKDYVideoLandscapeCell *cell = [scrollView dequeueReusableCellWithIdentifier:@"GKDYVideoLandscapeCell" forIndexPath:indexPath];
|
||||||
|
[cell loadData:model];
|
||||||
|
@weakify(self);
|
||||||
|
cell.backClickBlock = ^{
|
||||||
|
@strongify(self);
|
||||||
|
[self rotate];
|
||||||
|
};
|
||||||
|
[cell showTopView];
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - GKDYVideoScrollViewDelegate
|
||||||
|
- (void)scrollView:(GKVideoScrollView *)scrollView didEndScrollingCell:(GKVideoViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
[self playVideoWithCell:(GKDYVideoCell *)cell index:indexPath.row];
|
||||||
|
if ([self.delegate respondsToSelector:@selector(cellSwitchWithModel:)]) {
|
||||||
|
[self.delegate cellSwitchWithModel:self.dataSources[indexPath.row]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollView:(GKVideoScrollView *)scrollView didEndDisplayingCell:(GKVideoViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
[self stopPlayWithCell:(GKDYVideoCell *)cell index:indexPath.row];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
|
||||||
|
if (scrollView == self.scrollView) {
|
||||||
|
if (self.scrollView.currentIndex == 0 && scrollView.contentOffset.y < 0) {
|
||||||
|
self.scrollView.contentOffset = CGPointZero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
|
||||||
|
[self.portraitView willBeginDragging];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
|
||||||
|
[self.portraitView didEndDragging];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollView:(GKDYVideoScrollView *)scrollView didPanWithDistance:(CGFloat)distance isEnd:(BOOL)isEnd {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(scrollViewDidPanDistance:isEnd:)]) {
|
||||||
|
[self.delegate scrollViewDidPanDistance:distance isEnd:isEnd];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - GKDYVideoPortraitCellDelegate
|
||||||
|
|
||||||
|
- (void)videoCell:(GKDYVideoPortraitCell *)cell didClickFavorite:(GKDYVideoModel *)model {
|
||||||
|
[self.scrollView reloadData];
|
||||||
|
|
||||||
|
if ([self.delegate respondsToSelector:@selector(celldidClickFavorite:cell:)]) {
|
||||||
|
[self.delegate celldidClickFavorite:model cell:cell];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)videoCell:(GKDYVideoPortraitCell *)cell didClickEpiscode:(GKDYVideoModel *)model {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(celldidClickEpiscode:cell:)]) {
|
||||||
|
[self.delegate celldidClickEpiscode:model cell:cell];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)videoCell:(GKDYVideoPortraitCell *)cell didClickShare:(GKDYVideoModel *)model {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(celldidClickShare:cell:)]) {
|
||||||
|
[self.delegate celldidClickShare:model cell:cell];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)videoCell:(GKDYVideoPortraitCell *)cell didClickDanmu:(GKDYVideoModel *)model {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)videoCell:(GKDYVideoPortraitCell *)cell didClickFullscreen:(GKDYVideoModel *)model {
|
||||||
|
[self rotate];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)videoCell:(GKDYVideoPortraitCell *)cell zoomBegan:(GKDYVideoModel *)model {
|
||||||
|
self.player.controlView.hidden = YES;
|
||||||
|
if ([self.delegate respondsToSelector:@selector(cellZoomBegan:)]) {
|
||||||
|
[self.delegate cellZoomBegan:model];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)videoCell:(GKDYVideoPortraitCell *)cell zoomEnded:(GKDYVideoModel *)model isFullscreen:(BOOL)isFullscreen {
|
||||||
|
if (isFullscreen) {
|
||||||
|
self.fullscreenView.hidden = NO;
|
||||||
|
if (self.player.controlView != self.fullscreenView) {
|
||||||
|
self.player.controlView = self.fullscreenView;
|
||||||
|
self.player.disableGestureTypes = ZFPlayerDisableGestureTypesPinch;
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
self.currentCell.portraitView.hidden = NO;
|
||||||
|
if (self.player.controlView != self.currentCell.portraitView) {
|
||||||
|
self.player.controlView = self.currentCell.portraitView;
|
||||||
|
self.player.disableGestureTypes = ZFPlayerDisableGestureTypesPan | ZFPlayerDisableGestureTypesPinch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ([self.delegate respondsToSelector:@selector(cellZoomEnded:isFullscreen:)]) {
|
||||||
|
[self.delegate cellZoomEnded:model isFullscreen:isFullscreen];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Lazy
|
||||||
|
- (GKDYVideoScrollView *)scrollView {
|
||||||
|
if (!_scrollView) {
|
||||||
|
_scrollView = [[GKDYVideoScrollView alloc] init];
|
||||||
|
_scrollView.dataSource = self;
|
||||||
|
_scrollView.delegate = self;
|
||||||
|
_scrollView.backgroundColor = UIColor.blackColor;
|
||||||
|
[_scrollView registerClass:GKDYVideoPortraitCell.class forCellReuseIdentifier:@"GKDYVideoPortraitCell"];
|
||||||
|
[_scrollView addPanGesture];
|
||||||
|
}
|
||||||
|
return _scrollView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKDYVideoLandscapeView *)landscapeView {
|
||||||
|
if (!_landscapeView) {
|
||||||
|
_landscapeView = [[GKDYVideoLandscapeView alloc] initWithFrame:UIScreen.mainScreen.bounds];
|
||||||
|
|
||||||
|
@weakify(self);
|
||||||
|
_landscapeView.likeBlock = ^(GKDYVideoModel * _Nonnull model) {
|
||||||
|
@strongify(self);
|
||||||
|
[self likeVideoWithModel:model];
|
||||||
|
};
|
||||||
|
|
||||||
|
_landscapeView.singleTapBlock = ^{
|
||||||
|
@strongify(self);
|
||||||
|
if (self.landscapeCell.isShowTop) {
|
||||||
|
[self.landscapeCell hideTopView];
|
||||||
|
[self.landscapeView hideContainerView:NO];
|
||||||
|
}else {
|
||||||
|
[self.landscapeView autoHide];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return _landscapeView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKDYVideoFullscreenView *)fullscreenView {
|
||||||
|
if (!_fullscreenView) {
|
||||||
|
_fullscreenView = [[GKDYVideoFullscreenView alloc] init];
|
||||||
|
|
||||||
|
@weakify(self);
|
||||||
|
_fullscreenView.closeFullscreenBlock = ^{
|
||||||
|
@strongify(self);
|
||||||
|
[self.currentCell closeFullscreen];
|
||||||
|
};
|
||||||
|
|
||||||
|
_fullscreenView.likeBlock = ^{
|
||||||
|
@strongify(self);
|
||||||
|
[self likeVideoWithModel:nil];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return _fullscreenView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSMutableArray *)dataSources {
|
||||||
|
if (!_dataSources) {
|
||||||
|
_dataSources = [NSMutableArray array];
|
||||||
|
}
|
||||||
|
return _dataSources;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
21
HiBit/Project/Player/Model/GKDUVideoInfoModel.h
Normal file
21
HiBit/Project/Player/Model/GKDUVideoInfoModel.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// GKDUVideoInfoModel.h
|
||||||
|
// QinJiuTV
|
||||||
|
//
|
||||||
|
// Created by HI_LOSER on 2024/5/28.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GKDUVideoInfoModel : NSObject
|
||||||
|
@property (assign, nonatomic) NSInteger status;
|
||||||
|
@property (assign, nonatomic) NSInteger skits_id;
|
||||||
|
@property (assign, nonatomic) NSInteger vid;
|
||||||
|
@property (copy, nonatomic) NSString * video_url;
|
||||||
|
@property (assign, nonatomic) NSInteger episode;
|
||||||
|
@property (assign, nonatomic) BOOL is_vip;
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
14
HiBit/Project/Player/Model/GKDUVideoInfoModel.m
Normal file
14
HiBit/Project/Player/Model/GKDUVideoInfoModel.m
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// GKDUVideoInfoModel.m
|
||||||
|
// QinJiuTV
|
||||||
|
//
|
||||||
|
// Created by HI_LOSER on 2024/5/28.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDUVideoInfoModel.h"
|
||||||
|
|
||||||
|
@implementation GKDUVideoInfoModel
|
||||||
|
+ (NSDictionary *)mj_replacedKeyFromPropertyName{
|
||||||
|
return @{@"vid" : @"id"};
|
||||||
|
}
|
||||||
|
@end
|
88
HiBit/Project/Player/Model/GKDYVideoModel.h
Executable file
88
HiBit/Project/Player/Model/GKDYVideoModel.h
Executable file
@ -0,0 +1,88 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoModel.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2018/9/23.
|
||||||
|
// Copyright © 2018 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "GKDUVideoInfoModel.h"
|
||||||
|
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GKDYVideoModel : NSObject<NSCopying>
|
||||||
|
|
||||||
|
//@property (nonatomic, copy) NSString *video_id;
|
||||||
|
//@property (nonatomic, copy) NSString *poster_small;
|
||||||
|
//@property (nonatomic, copy) NSString *poster_big;
|
||||||
|
//@property (nonatomic, copy) NSString *poster_pc;
|
||||||
|
//@property (nonatomic, copy) NSString *source_name;
|
||||||
|
//@property (nonatomic, copy) NSString *play_url;
|
||||||
|
//@property (nonatomic, copy) NSString *duration;
|
||||||
|
//@property (nonatomic, copy) NSString *url;
|
||||||
|
//@property (nonatomic, copy) NSString *show_tag;
|
||||||
|
//@property (nonatomic, copy) NSString *publish_time;
|
||||||
|
//@property (nonatomic, copy) NSString *is_pay_column;
|
||||||
|
//@property (nonatomic, copy) NSString *like;
|
||||||
|
//@property (nonatomic, copy) NSString *comment;
|
||||||
|
//@property (nonatomic, copy) NSString *playcnt;
|
||||||
|
//@property (nonatomic, copy) NSString *fmplaycnt;
|
||||||
|
//@property (nonatomic, copy) NSString *fmplaycnt_2;
|
||||||
|
//@property (nonatomic, copy) NSString *outstand_tag;
|
||||||
|
//@property (nonatomic, copy) NSString *previewUrlHttp;
|
||||||
|
//@property (nonatomic, copy) NSString *third_id;
|
||||||
|
//@property (nonatomic, copy) NSString *vip;
|
||||||
|
//@property (nonatomic, copy) NSString *author_avatar;
|
||||||
|
//
|
||||||
|
//@property (nonatomic, assign) BOOL isLike;
|
||||||
|
@property (nonatomic, strong, nullable) NSURLSessionDataTask *task;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL isRequest;
|
||||||
|
@property (nonatomic, assign) BOOL requested;
|
||||||
|
|
||||||
|
|
||||||
|
/// 短剧id
|
||||||
|
@property (assign, nonatomic) NSInteger cid;
|
||||||
|
|
||||||
|
/// 收藏数量
|
||||||
|
@property (assign, nonatomic) NSInteger collect_total;
|
||||||
|
|
||||||
|
/// 集数
|
||||||
|
@property (assign, nonatomic) NSInteger episode_total;
|
||||||
|
@property (assign, nonatomic) NSInteger episode;
|
||||||
|
|
||||||
|
/// 观看数量
|
||||||
|
@property (assign, nonatomic) NSInteger watch_total;
|
||||||
|
|
||||||
|
/// 是否购买
|
||||||
|
@property (assign, nonatomic) BOOL buy_type;
|
||||||
|
|
||||||
|
/// 是否收藏
|
||||||
|
@property (assign, nonatomic) BOOL is_collect;
|
||||||
|
|
||||||
|
@property (assign, nonatomic) NSInteger process;
|
||||||
|
|
||||||
|
/// 价格
|
||||||
|
@property (strong, nonatomic) NSNumber * all_price;
|
||||||
|
|
||||||
|
|
||||||
|
/// 标题 剧名
|
||||||
|
@property (copy, nonatomic) NSString * title; // name
|
||||||
|
|
||||||
|
/// 剧情描述
|
||||||
|
@property (copy, nonatomic) NSString * detailText;
|
||||||
|
|
||||||
|
/// 封面 海报
|
||||||
|
@property (copy, nonatomic) NSString * image_url;
|
||||||
|
|
||||||
|
@property (strong, nonatomic) GKDUVideoInfoModel * videoInfo;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
||||||
|
|
77
HiBit/Project/Player/Model/GKDYVideoModel.m
Executable file
77
HiBit/Project/Player/Model/GKDYVideoModel.m
Executable file
@ -0,0 +1,77 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoModel.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2018/9/23.
|
||||||
|
// Copyright © 2018 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYVideoModel.h"
|
||||||
|
|
||||||
|
@implementation GKDYVideoModel
|
||||||
|
|
||||||
|
/*
|
||||||
|
/// 短剧id
|
||||||
|
@property (assign, nonatomic) NSInteger ;
|
||||||
|
|
||||||
|
/// 收藏数量
|
||||||
|
@property (assign, nonatomic) NSInteger ;
|
||||||
|
|
||||||
|
/// 集数
|
||||||
|
@property (assign, nonatomic) NSInteger ;
|
||||||
|
|
||||||
|
/// 是否观看
|
||||||
|
@property (assign, nonatomic) BOOL ;
|
||||||
|
|
||||||
|
/// 是否购买
|
||||||
|
@property (assign, nonatomic) BOOL ;
|
||||||
|
|
||||||
|
/// 是否收藏
|
||||||
|
@property (assign, nonatomic) BOOL ;
|
||||||
|
|
||||||
|
@property (assign, nonatomic) NSInteger ;
|
||||||
|
|
||||||
|
/// 价格
|
||||||
|
@property (strong, nonatomic) NSNumber * ;
|
||||||
|
|
||||||
|
|
||||||
|
/// 标题 剧名
|
||||||
|
@property (copy, nonatomic) NSString * ; // name
|
||||||
|
|
||||||
|
/// 剧情描述
|
||||||
|
@property (copy, nonatomic) NSString * ;
|
||||||
|
|
||||||
|
/// 封面 海报
|
||||||
|
@property (copy, nonatomic) NSString * ;
|
||||||
|
|
||||||
|
@property (strong, nonatomic) GKDUVideoInfoModel * ;
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
- (id)copyWithZone:(NSZone *)zone{
|
||||||
|
GKDYVideoModel * model = [self.class new];
|
||||||
|
model.cid = self.cid;
|
||||||
|
model.collect_total = self.collect_total;
|
||||||
|
model.episode_total = self.episode_total;
|
||||||
|
model.episode = self.episode;
|
||||||
|
model.watch_total = self.watch_total;
|
||||||
|
model.buy_type = self.buy_type;
|
||||||
|
model.is_collect = self.is_collect;
|
||||||
|
model.process = self.process;
|
||||||
|
model.all_price = self.all_price;
|
||||||
|
model.title = self.title;
|
||||||
|
model.detailText = self.detailText;
|
||||||
|
model.image_url = self.image_url;
|
||||||
|
model.videoInfo = self.videoInfo;
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+ (NSDictionary *)mj_replacedKeyFromPropertyName {
|
||||||
|
return @{@"cid" : @"id",
|
||||||
|
@"detailText" : @"description",
|
||||||
|
@"videoInfo" : @"video_info",
|
||||||
|
@"title" : @"name"};
|
||||||
|
}
|
||||||
|
@end
|
24
HiBit/Project/Player/View/GKDYPanGestureRecognizer.h
Executable file
24
HiBit/Project/Player/View/GKDYPanGestureRecognizer.h
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
//
|
||||||
|
// GKDYPanGestureRecognizer.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by gaokun on 2019/7/31.
|
||||||
|
// Copyright © 2019 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSUInteger, GKDYPanGestureRecognizerDirection) {
|
||||||
|
GKDYPanGestureRecognizerDirectionVertical,
|
||||||
|
GKDYPanGestureRecognizerDirectionHorizontal
|
||||||
|
};
|
||||||
|
|
||||||
|
@interface GKDYPanGestureRecognizer : UIPanGestureRecognizer
|
||||||
|
|
||||||
|
@property (nonatomic, assign) GKDYPanGestureRecognizerDirection direction;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
54
HiBit/Project/Player/View/GKDYPanGestureRecognizer.m
Executable file
54
HiBit/Project/Player/View/GKDYPanGestureRecognizer.m
Executable file
@ -0,0 +1,54 @@
|
|||||||
|
//
|
||||||
|
// GKDYPanGestureRecognizer.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by gaokun on 2019/7/31.
|
||||||
|
// Copyright © 2019 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYPanGestureRecognizer.h"
|
||||||
|
|
||||||
|
int const static kDirectionPanThreshold = 5;
|
||||||
|
|
||||||
|
@interface GKDYPanGestureRecognizer()
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL drag;
|
||||||
|
@property (nonatomic, assign) int moveX;
|
||||||
|
@property (nonatomic, assign) int moveY;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKDYPanGestureRecognizer
|
||||||
|
|
||||||
|
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
||||||
|
[super touchesMoved:touches withEvent:event];
|
||||||
|
if (self.state == UIGestureRecognizerStateFailed) return;
|
||||||
|
CGPoint nowPoint = [[touches anyObject] locationInView:self.view];
|
||||||
|
CGPoint prevPoint = [[touches anyObject] previousLocationInView:self.view];
|
||||||
|
_moveX += prevPoint.x - nowPoint.x;
|
||||||
|
_moveY += prevPoint.y - nowPoint.y;
|
||||||
|
if (!_drag) {
|
||||||
|
if (abs(_moveX) > kDirectionPanThreshold) {
|
||||||
|
if (_direction == GKDYPanGestureRecognizerDirectionVertical) {
|
||||||
|
self.state = UIGestureRecognizerStateFailed;
|
||||||
|
}else {
|
||||||
|
_drag = YES;
|
||||||
|
}
|
||||||
|
}else if (abs(_moveY) > kDirectionPanThreshold) {
|
||||||
|
if (_direction == GKDYPanGestureRecognizerDirectionHorizontal) {
|
||||||
|
self.state = UIGestureRecognizerStateFailed;
|
||||||
|
}else {
|
||||||
|
_drag = YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)reset {
|
||||||
|
[super reset];
|
||||||
|
_drag = NO;
|
||||||
|
_moveX = 0;
|
||||||
|
_moveY = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
17
HiBit/Project/Player/View/GKDYScrollView.h
Executable file
17
HiBit/Project/Player/View/GKDYScrollView.h
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// GKDYScrollView.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2018/9/23.
|
||||||
|
// Copyright © 2018 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GKDYScrollView : UIScrollView
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
58
HiBit/Project/Player/View/GKDYScrollView.m
Executable file
58
HiBit/Project/Player/View/GKDYScrollView.m
Executable file
@ -0,0 +1,58 @@
|
|||||||
|
//
|
||||||
|
// GKDYScrollView.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2018/9/23.
|
||||||
|
// Copyright © 2018 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYScrollView.h"
|
||||||
|
|
||||||
|
@implementation GKDYScrollView
|
||||||
|
|
||||||
|
#pragma mark - 解决全屏滑动时的手势冲突 与 左滑push手势冲突
|
||||||
|
// 当UIScrollView在水平方向滑动到第一个时,默认是不能全屏滑动返回的,通过下面的方法可实现其滑动返回。
|
||||||
|
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
|
||||||
|
if ([self panBack:gestureRecognizer]) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
|
||||||
|
{
|
||||||
|
if ([self panBack:gestureRecognizer]) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)panBack:(UIGestureRecognizer *)gestureRecognizer {
|
||||||
|
if (gestureRecognizer == self.panGestureRecognizer) {
|
||||||
|
CGPoint point = [self.panGestureRecognizer translationInView:self];
|
||||||
|
UIGestureRecognizerState state = gestureRecognizer.state;
|
||||||
|
|
||||||
|
// 设置手势滑动的位置距屏幕左边的区域
|
||||||
|
CGFloat locationDistance = self.bounds.size.width;
|
||||||
|
|
||||||
|
if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStatePossible) {
|
||||||
|
CGPoint location = [gestureRecognizer locationInView:self];
|
||||||
|
if (point.x > 0 && location.x < locationDistance && self.contentOffset.x <= 0) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 临界点:scrollView滑动到最后一屏时的x轴位置,可根据需求改变
|
||||||
|
CGFloat criticalPoint = self.frame.size.width;
|
||||||
|
|
||||||
|
// point.x < 0 代表左滑即手指从屏幕右边向左移动
|
||||||
|
// 当UIScrollview滑动到临界点时,则不再相应UIScrollview的滑动左滑手势,防止与左滑手势冲突
|
||||||
|
if (point.x < 0 && self.contentOffset.x + criticalPoint >= self.contentSize.width) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
26
HiBit/Project/Player/View/GKDYTitleView.h
Executable file
26
HiBit/Project/Player/View/GKDYTitleView.h
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// GKDYTitleView.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/27.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <JXCategoryView/JXCategoryView.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GKDYTitleView : UIView
|
||||||
|
|
||||||
|
@property (nonatomic, strong) JXCategoryTitleView *categoryView;
|
||||||
|
|
||||||
|
@property (nonatomic, copy) void(^loadingBlock)(void);
|
||||||
|
|
||||||
|
- (void)changeAlphaWithDistance:(CGFloat)distance isEnd:(BOOL)isEnd;
|
||||||
|
|
||||||
|
- (void)loadingEnd;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
195
HiBit/Project/Player/View/GKDYTitleView.m
Executable file
195
HiBit/Project/Player/View/GKDYTitleView.m
Executable file
@ -0,0 +1,195 @@
|
|||||||
|
//
|
||||||
|
// GKDYTitleView.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/27.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYTitleView.h"
|
||||||
|
#import "GKBallLoadingView.h"
|
||||||
|
|
||||||
|
#define kTransitionCenter 20.0f
|
||||||
|
|
||||||
|
@interface GKDYTitleView()
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UILabel *refreshLabel;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIButton *searchBtn;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) GKBallLoadingView *loadingView;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL isRefreshing;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKDYTitleView
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
if (self = [super init]) {
|
||||||
|
[self initUI];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)initUI {
|
||||||
|
[self addSubview:self.categoryView];
|
||||||
|
[self addSubview:self.searchBtn];
|
||||||
|
[self addSubview:self.refreshLabel];
|
||||||
|
[self addSubview:self.loadingView];
|
||||||
|
|
||||||
|
[self.categoryView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.top.bottom.equalTo(self);
|
||||||
|
make.left.equalTo(self).offset(60);
|
||||||
|
make.right.equalTo(self).offset(-60);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.searchBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.right.equalTo(self).offset(-15);
|
||||||
|
make.top.bottom.equalTo(self);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.refreshLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.top.bottom.equalTo(self);
|
||||||
|
make.centerX.equalTo(self);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.loadingView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.right.equalTo(self).offset(-15);
|
||||||
|
make.centerY.equalTo(self);
|
||||||
|
make.width.height.mas_equalTo(44);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)changeAlphaWithDistance:(CGFloat)distance isEnd:(BOOL)isEnd {
|
||||||
|
if (isEnd) {
|
||||||
|
[UIView animateWithDuration:0.25 animations:^{
|
||||||
|
[self changeFrameWithDistance:0];
|
||||||
|
self.categoryView.alpha = 1;
|
||||||
|
self.refreshLabel.alpha = 0;
|
||||||
|
self.loadingView.alpha = 1;
|
||||||
|
}];
|
||||||
|
|
||||||
|
if (distance >= 2 * kTransitionCenter) {
|
||||||
|
self.searchBtn.alpha = 0;
|
||||||
|
self.isRefreshing = YES;
|
||||||
|
[self.loadingView startLoading];
|
||||||
|
!self.loadingBlock ?: self.loadingBlock();
|
||||||
|
}else {
|
||||||
|
self.searchBtn.alpha = 1;
|
||||||
|
self.loadingView.alpha = 0;
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
if (distance <= 0) {
|
||||||
|
self.categoryView.alpha = 1;
|
||||||
|
self.searchBtn.alpha = 1;
|
||||||
|
self.refreshLabel.alpha = 0;
|
||||||
|
self.loadingView.alpha = 0;
|
||||||
|
}else if (distance > 0 && distance < kTransitionCenter) {
|
||||||
|
CGFloat alpha = distance / kTransitionCenter;
|
||||||
|
self.categoryView.alpha = 1 - alpha;
|
||||||
|
self.searchBtn.alpha = 1 - alpha;
|
||||||
|
self.refreshLabel.alpha = 0;
|
||||||
|
self.loadingView.alpha = 0;
|
||||||
|
|
||||||
|
// 改变位置
|
||||||
|
[self changeFrameWithDistance:distance];
|
||||||
|
}else if (distance >= kTransitionCenter && distance <= 2 * kTransitionCenter) {
|
||||||
|
CGFloat alpha = (2 * kTransitionCenter - distance) / kTransitionCenter;
|
||||||
|
self.categoryView.alpha = 0;
|
||||||
|
self.searchBtn.alpha = 0;
|
||||||
|
self.refreshLabel.alpha = 1 - alpha;
|
||||||
|
self.loadingView.alpha = 1 - alpha;
|
||||||
|
|
||||||
|
// 改变位置
|
||||||
|
[self changeFrameWithDistance:distance];
|
||||||
|
|
||||||
|
[self.loadingView startLoadingWithProgress:1 - alpha];
|
||||||
|
}else {
|
||||||
|
self.categoryView.alpha = 0;
|
||||||
|
self.searchBtn.alpha = 0;
|
||||||
|
self.refreshLabel.alpha = 1;
|
||||||
|
self.loadingView.alpha = 1;
|
||||||
|
|
||||||
|
[self.loadingView startLoadingWithProgress:1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)changeFrameWithDistance:(CGFloat)distance {
|
||||||
|
CGRect frame = self.categoryView.frame;
|
||||||
|
frame.origin.y = distance;
|
||||||
|
self.categoryView.frame = frame;
|
||||||
|
|
||||||
|
frame = self.searchBtn.frame;
|
||||||
|
frame.origin.y = distance;
|
||||||
|
self.searchBtn.frame = frame;
|
||||||
|
|
||||||
|
frame = self.refreshLabel.frame;
|
||||||
|
frame.origin.y = distance;
|
||||||
|
self.refreshLabel.frame = frame;
|
||||||
|
|
||||||
|
frame = self.loadingView.frame;
|
||||||
|
frame.origin.y = distance;
|
||||||
|
self.loadingView.frame = frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)loadingEnd {
|
||||||
|
self.searchBtn.alpha = 1;
|
||||||
|
self.loadingView.alpha = 0;
|
||||||
|
[self.loadingView stopLoading];
|
||||||
|
self.isRefreshing = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)searchClick:(id)sender {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Lazy
|
||||||
|
- (JXCategoryTitleView *)categoryView {
|
||||||
|
if (!_categoryView) {
|
||||||
|
_categoryView = [[JXCategoryTitleView alloc] init];
|
||||||
|
_categoryView.backgroundColor = UIColor.clearColor;
|
||||||
|
_categoryView.titleColor = UIColor.lightGrayColor;
|
||||||
|
_categoryView.titleSelectedColor = UIColor.whiteColor;
|
||||||
|
_categoryView.titleFont = [UIFont systemFontOfSize:16];
|
||||||
|
_categoryView.titleSelectedFont = [UIFont boldSystemFontOfSize:16];
|
||||||
|
_categoryView.cellSpacing = 10;
|
||||||
|
|
||||||
|
JXCategoryIndicatorLineView *lineView = [[JXCategoryIndicatorLineView alloc] init];
|
||||||
|
lineView.indicatorColor = UIColor.whiteColor;
|
||||||
|
lineView.indicatorWidthIncrement = -4;
|
||||||
|
_categoryView.indicators = @[lineView];
|
||||||
|
}
|
||||||
|
return _categoryView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIButton *)searchBtn {
|
||||||
|
if (!_searchBtn) {
|
||||||
|
_searchBtn = [[UIButton alloc] init];
|
||||||
|
[_searchBtn setImage:[UIImage imageNamed:@"ich_feed_search_Normal"] forState:UIControlStateNormal];
|
||||||
|
[_searchBtn addTarget:self action:@selector(searchClick:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
}
|
||||||
|
return _searchBtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)refreshLabel {
|
||||||
|
if (!_refreshLabel) {
|
||||||
|
_refreshLabel = [[UILabel alloc] init];
|
||||||
|
_refreshLabel.font = [UIFont systemFontOfSize:16];
|
||||||
|
_refreshLabel.textColor = UIColor.whiteColor;
|
||||||
|
_refreshLabel.text = @"下拉刷新内容";
|
||||||
|
_refreshLabel.alpha = 0;
|
||||||
|
}
|
||||||
|
return _refreshLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKBallLoadingView *)loadingView {
|
||||||
|
if (!_loadingView) {
|
||||||
|
_loadingView = [[GKBallLoadingView alloc] init];
|
||||||
|
_loadingView.alpha = 0;
|
||||||
|
}
|
||||||
|
return _loadingView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
29
HiBit/Project/Player/View/GKDYVideoCell.h
Executable file
29
HiBit/Project/Player/View/GKDYVideoCell.h
Executable file
@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoCell.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/17.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <GKVideoScrollView/GKVideoScrollView.h>
|
||||||
|
#import "GKDYVideoModel.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GKDYVideoCell : GKVideoViewCell
|
||||||
|
|
||||||
|
@property (nonatomic, strong) GKDYVideoModel *model;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIImageView *coverImgView;
|
||||||
|
|
||||||
|
- (void)initUI;
|
||||||
|
|
||||||
|
- (void)loadData:(GKDYVideoModel *)model;
|
||||||
|
|
||||||
|
- (void)resetView;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
58
HiBit/Project/Player/View/GKDYVideoCell.m
Executable file
58
HiBit/Project/Player/View/GKDYVideoCell.m
Executable file
@ -0,0 +1,58 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoCell.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/17.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYVideoCell.h"
|
||||||
|
|
||||||
|
@interface GKDYVideoCell()
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKDYVideoCell
|
||||||
|
|
||||||
|
- (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier {
|
||||||
|
if (self = [super initWithReuseIdentifier:reuseIdentifier]) {
|
||||||
|
[self initUI];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)initUI {
|
||||||
|
[self addSubview:self.coverImgView];
|
||||||
|
[self.coverImgView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.edges.equalTo(self);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)loadData:(GKDYVideoModel *)model {
|
||||||
|
self.model = model;
|
||||||
|
|
||||||
|
[self.coverImgView sd_setImageWithURL:[NSURL URLWithString:model.image_url]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setModel:(GKDYVideoModel *)model {
|
||||||
|
_model = model;
|
||||||
|
|
||||||
|
[self.coverImgView sd_setImageWithURL:[NSURL URLWithString:model.image_url]];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)resetView {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Lazy
|
||||||
|
- (UIImageView *)coverImgView {
|
||||||
|
if (!_coverImgView) {
|
||||||
|
_coverImgView = [[UIImageView alloc] init];
|
||||||
|
_coverImgView.contentMode = UIViewContentModeScaleAspectFit;
|
||||||
|
_coverImgView.userInteractionEnabled = YES;
|
||||||
|
}
|
||||||
|
return _coverImgView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
55
HiBit/Project/Player/View/GKDYVideoControlView.h
Executable file
55
HiBit/Project/Player/View/GKDYVideoControlView.h
Executable file
@ -0,0 +1,55 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoControlView.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2018/9/23.
|
||||||
|
// Copyright © 2018 QuintGao. All rights reserved.
|
||||||
|
// 播放器视图控制层
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
//#import "GKAWEModel.h"
|
||||||
|
#import <GKSliderView/GKSliderView.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@class GKDYVideoControlView;
|
||||||
|
|
||||||
|
@protocol GKDYVideoControlViewDelegate <NSObject>
|
||||||
|
|
||||||
|
- (void)controlViewDidClickSelf:(GKDYVideoControlView *)controlView;
|
||||||
|
|
||||||
|
- (void)controlViewDidClickPriase:(GKDYVideoControlView *)controlView;
|
||||||
|
|
||||||
|
- (void)controlViewdidClickEpiscode:(GKDYVideoControlView *)controlView;
|
||||||
|
|
||||||
|
- (void)controlViewDidClickShare:(GKDYVideoControlView *)controlView;
|
||||||
|
|
||||||
|
- (void)controlView:(GKDYVideoControlView *)controlView touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface GKDYVideoControlView : UIView
|
||||||
|
|
||||||
|
@property (nonatomic, weak) id<GKDYVideoControlViewDelegate> delegate;
|
||||||
|
|
||||||
|
// 视频封面图:显示封面并播放视频
|
||||||
|
@property (nonatomic, strong) UIImageView *coverImgView;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) id model;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) GKSliderView *sliderView;
|
||||||
|
|
||||||
|
- (void)setProgress:(float)progress;
|
||||||
|
|
||||||
|
- (void)startLoading;
|
||||||
|
- (void)stopLoading;
|
||||||
|
|
||||||
|
- (void)showPlayBtn;
|
||||||
|
- (void)hidePlayBtn;
|
||||||
|
|
||||||
|
- (void)showLikeAnimation;
|
||||||
|
- (void)showUnLikeAnimation;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
302
HiBit/Project/Player/View/GKDYVideoControlView.m
Executable file
302
HiBit/Project/Player/View/GKDYVideoControlView.m
Executable file
@ -0,0 +1,302 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoControlView.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2018/9/23.
|
||||||
|
// Copyright © 2018 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYVideoControlView.h"
|
||||||
|
#import "GKLikeView.h"
|
||||||
|
//#import "NSString+GKCategory.h"
|
||||||
|
#import "GKDYVideoItemButton.h"
|
||||||
|
|
||||||
|
@interface GKDYVideoControlView()
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIImageView *iconView;
|
||||||
|
@property (nonatomic, strong) GKLikeView *likeView;
|
||||||
|
@property (nonatomic, strong) GKDYVideoItemButton *commentBtn;
|
||||||
|
@property (nonatomic, strong) GKDYVideoItemButton *shareBtn;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UILabel *nameLabel;
|
||||||
|
@property (nonatomic, strong) UILabel *contentLabel;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIButton *playBtn;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UILabel *label;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKDYVideoControlView
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
if (self = [super init]) {
|
||||||
|
[self addSubview:self.coverImgView];
|
||||||
|
[self addSubview:self.iconView];
|
||||||
|
[self addSubview:self.likeView];
|
||||||
|
[self addSubview:self.commentBtn];
|
||||||
|
[self addSubview:self.shareBtn];
|
||||||
|
[self addSubview:self.nameLabel];
|
||||||
|
[self addSubview:self.contentLabel];
|
||||||
|
[self addSubview:self.sliderView];
|
||||||
|
|
||||||
|
[self addSubview:self.playBtn];
|
||||||
|
[self addSubview:self.label];
|
||||||
|
|
||||||
|
[self.coverImgView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.edges.equalTo(self);
|
||||||
|
}];
|
||||||
|
|
||||||
|
CGFloat bottomM = [UIScreen bottomSafeHeight];
|
||||||
|
|
||||||
|
self.sliderView.frame = CGRectMake(0, HBScreenSize.height - [UIScreen bottomSafeHeight] - 0.5, HBScreenSize.width, 1.0f);
|
||||||
|
|
||||||
|
[self.contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.equalTo(self).offset(HBAdapt(30.0f));
|
||||||
|
make.bottom.equalTo(self).offset(-(HBAdapt(30.0f) + bottomM));
|
||||||
|
make.width.mas_equalTo(HBAdapt(504.0f));
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.equalTo(self.contentLabel);
|
||||||
|
make.bottom.equalTo(self.contentLabel.mas_top).offset(-HBAdapt(20.0f));
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.shareBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.right.equalTo(self).offset(-HBAdapt(30.0f));
|
||||||
|
make.bottom.equalTo(self.sliderView.mas_top).offset(-HBAdapt(100.0f));
|
||||||
|
make.width.height.mas_equalTo(HBAdapt(110.0f));
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.commentBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.centerX.equalTo(self.shareBtn);
|
||||||
|
make.bottom.equalTo(self.shareBtn.mas_top).offset(-HBAdapt(45.0f));
|
||||||
|
make.width.height.mas_equalTo(HBAdapt(110.0f));
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.likeView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.centerX.equalTo(self.shareBtn);
|
||||||
|
make.bottom.equalTo(self.commentBtn.mas_top).offset(-HBAdapt(45.0f));
|
||||||
|
make.width.height.mas_equalTo(HBAdapt(110.0f));
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.iconView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.centerX.equalTo(self.shareBtn);
|
||||||
|
make.bottom.equalTo(self.likeView.mas_top).offset(-HBAdapt(70.0f));
|
||||||
|
make.width.height.mas_equalTo(HBAdapt(100.0f));
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.playBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.center.equalTo(self);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.label mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.center.equalTo(self);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- (void)setModel:(GKAWEModel *)model {
|
||||||
|
// _model = model;
|
||||||
|
//
|
||||||
|
// self.sliderView.value = 0;
|
||||||
|
//
|
||||||
|
// if (model.video.width.floatValue > model.video.height.floatValue) {
|
||||||
|
// self.coverImgView.contentMode = UIViewContentModeScaleAspectFit;
|
||||||
|
// }else {
|
||||||
|
// self.coverImgView.contentMode = UIViewContentModeScaleAspectFill;
|
||||||
|
// }
|
||||||
|
// NSString *url = model.video.cover.url_list.firstObject;
|
||||||
|
// [self.coverImgView sd_setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:@"img_video_loading"]];
|
||||||
|
// self.nameLabel.text = [NSString stringWithFormat:@"@%@", model.author.nickname];
|
||||||
|
// [self.iconView sd_setImageWithURL:[NSURL URLWithString:model.author.avatar_thumb.url_list.firstObject] placeholderImage:[UIImage imageNamed:@"placeholderimg"]];
|
||||||
|
// self.contentLabel.text = model.desc;
|
||||||
|
//
|
||||||
|
// [self.likeView setupLikeState:model.is_like];
|
||||||
|
// [self.likeView setupLikeCount:[model.statistics.digg_count gk_unitConvert]];
|
||||||
|
//
|
||||||
|
// [self.commentBtn setTitle:[model.statistics.comment_count gk_unitConvert] forState:UIControlStateNormal];
|
||||||
|
// [self.shareBtn setTitle:[model.statistics.share_count gk_unitConvert] forState:UIControlStateNormal];
|
||||||
|
//
|
||||||
|
// self.label.text = [NSString stringWithFormat:@"第%zd个", model.index];
|
||||||
|
//}
|
||||||
|
|
||||||
|
#pragma mark - Public Methods
|
||||||
|
- (void)setProgress:(float)progress {
|
||||||
|
self.sliderView.value = progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)startLoading {
|
||||||
|
[self.sliderView showLineLoading];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)stopLoading {
|
||||||
|
[self.sliderView hideLineLoading];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)showPlayBtn {
|
||||||
|
self.playBtn.hidden = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)hidePlayBtn {
|
||||||
|
self.playBtn.hidden = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)showLikeAnimation {
|
||||||
|
[self.likeView startAnimationWithIsLike:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)showUnLikeAnimation {
|
||||||
|
[self.likeView startAnimationWithIsLike:NO];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Action
|
||||||
|
- (void)controlViewDidClick {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(controlViewDidClickSelf:)]) {
|
||||||
|
[self.delegate controlViewDidClickSelf:self];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)praiseBtnClick:(id)sender {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(controlViewDidClickPriase:)]) {
|
||||||
|
[self.delegate controlViewDidClickPriase:self];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)commentBtnClick:(id)sender {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(controlViewdidClickEpiscode:)]) {
|
||||||
|
[self.delegate controlViewdidClickEpiscode:self];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)shareBtnClick:(id)sender {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(controlViewDidClickShare:)]) {
|
||||||
|
[self.delegate controlViewDidClickShare:self];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
||||||
|
UITouch *touch = [touches anyObject];
|
||||||
|
|
||||||
|
NSTimeInterval delayTime = 0.3f;
|
||||||
|
|
||||||
|
if (touch.tapCount <= 1) {
|
||||||
|
[self performSelector:@selector(controlViewDidClick) withObject:nil afterDelay:delayTime];
|
||||||
|
}else {
|
||||||
|
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(controlViewDidClick) object:nil];
|
||||||
|
|
||||||
|
if ([self.delegate respondsToSelector:@selector(controlView:touchesBegan:withEvent:)]) {
|
||||||
|
[self.delegate controlView:self touchesBegan:touches withEvent:event];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - 懒加载
|
||||||
|
- (UIImageView *)coverImgView {
|
||||||
|
if (!_coverImgView) {
|
||||||
|
_coverImgView = [UIImageView new];
|
||||||
|
_coverImgView.contentMode = UIViewContentModeScaleAspectFill;
|
||||||
|
_coverImgView.clipsToBounds = YES;
|
||||||
|
}
|
||||||
|
return _coverImgView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIImageView *)iconView {
|
||||||
|
if (!_iconView) {
|
||||||
|
_iconView = [UIImageView new];
|
||||||
|
_iconView.layer.cornerRadius = HBAdapt(50.0f);
|
||||||
|
_iconView.layer.masksToBounds = YES;
|
||||||
|
_iconView.layer.borderColor = [UIColor whiteColor].CGColor;
|
||||||
|
_iconView.layer.borderWidth = 1.0f;
|
||||||
|
_iconView.userInteractionEnabled = YES;
|
||||||
|
|
||||||
|
UITapGestureRecognizer *iconTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(iconDidClick:)];
|
||||||
|
[_iconView addGestureRecognizer:iconTap];
|
||||||
|
}
|
||||||
|
return _iconView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKLikeView *)likeView {
|
||||||
|
if (!_likeView) {
|
||||||
|
_likeView = [GKLikeView new];
|
||||||
|
}
|
||||||
|
return _likeView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKDYVideoItemButton *)commentBtn {
|
||||||
|
if (!_commentBtn) {
|
||||||
|
_commentBtn = [GKDYVideoItemButton new];
|
||||||
|
[_commentBtn setImage:[UIImage imageNamed:@"icon_home_comment"] forState:UIControlStateNormal];
|
||||||
|
_commentBtn.titleLabel.font = [UIFont systemFontOfSize:13.0f];
|
||||||
|
[_commentBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
||||||
|
[_commentBtn addTarget:self action:@selector(commentBtnClick:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
}
|
||||||
|
return _commentBtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKDYVideoItemButton *)shareBtn {
|
||||||
|
if (!_shareBtn) {
|
||||||
|
_shareBtn = [GKDYVideoItemButton new];
|
||||||
|
[_shareBtn setImage:[UIImage imageNamed:@"icon_home_share"] forState:UIControlStateNormal];
|
||||||
|
_shareBtn.titleLabel.font = [UIFont systemFontOfSize:13.0f];
|
||||||
|
[_shareBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
||||||
|
[_shareBtn addTarget:self action:@selector(shareBtnClick:) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
}
|
||||||
|
return _shareBtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)nameLabel {
|
||||||
|
if (!_nameLabel) {
|
||||||
|
_nameLabel = [UILabel new];
|
||||||
|
_nameLabel.textColor = [UIColor whiteColor];
|
||||||
|
_nameLabel.font = [UIFont boldSystemFontOfSize:15.0f];
|
||||||
|
_nameLabel.userInteractionEnabled = YES;
|
||||||
|
|
||||||
|
UITapGestureRecognizer *nameTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(iconDidClick:)];
|
||||||
|
[_nameLabel addGestureRecognizer:nameTap];
|
||||||
|
}
|
||||||
|
return _nameLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)contentLabel {
|
||||||
|
if (!_contentLabel) {
|
||||||
|
_contentLabel = [UILabel new];
|
||||||
|
_contentLabel.numberOfLines = 0;
|
||||||
|
_contentLabel.textColor = [UIColor whiteColor];
|
||||||
|
_contentLabel.font = [UIFont systemFontOfSize:14.0f];
|
||||||
|
}
|
||||||
|
return _contentLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKSliderView *)sliderView {
|
||||||
|
if (!_sliderView) {
|
||||||
|
_sliderView = [GKSliderView new];
|
||||||
|
_sliderView.isHideSliderBlock = YES;
|
||||||
|
_sliderView.sliderHeight = 1.0f;
|
||||||
|
_sliderView.maximumTrackTintColor = [UIColor clearColor];
|
||||||
|
_sliderView.minimumTrackTintColor = HBColor.color_FF0049;
|
||||||
|
}
|
||||||
|
return _sliderView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIButton *)playBtn {
|
||||||
|
if (!_playBtn) {
|
||||||
|
_playBtn = [UIButton new];
|
||||||
|
[_playBtn setImage:[UIImage imageNamed:@"player_play"] forState:UIControlStateNormal];
|
||||||
|
_playBtn.hidden = YES;
|
||||||
|
}
|
||||||
|
return _playBtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)label {
|
||||||
|
if (!_label) {
|
||||||
|
_label = [[UILabel alloc] init];
|
||||||
|
_label.font = [UIFont systemFontOfSize:30];
|
||||||
|
_label.backgroundColor = UIColor.blackColor;
|
||||||
|
_label.textColor = UIColor.whiteColor;
|
||||||
|
}
|
||||||
|
return _label;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
21
HiBit/Project/Player/View/GKDYVideoFullscreenView.h
Executable file
21
HiBit/Project/Player/View/GKDYVideoFullscreenView.h
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoFullscreenView.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/5/8.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <ZFPlayer/ZFPlayer.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GKDYVideoFullscreenView : UIView<ZFPlayerMediaControl>
|
||||||
|
|
||||||
|
@property (nonatomic, copy) void(^closeFullscreenBlock)(void);
|
||||||
|
@property (nonatomic, copy) void(^likeBlock)(void);
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
211
HiBit/Project/Player/View/GKDYVideoFullscreenView.m
Executable file
211
HiBit/Project/Player/View/GKDYVideoFullscreenView.m
Executable file
@ -0,0 +1,211 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoFullscreenView.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/5/8.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYVideoFullscreenView.h"
|
||||||
|
#import "GKDoubleLikeView.h"
|
||||||
|
|
||||||
|
@interface GKDYVideoFullscreenView()
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIView *bottomView;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIView *leftView;
|
||||||
|
@property (nonatomic, strong) UIButton *closeBtn;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIView *rightView;
|
||||||
|
@property (nonatomic, strong) UIButton *playBtn;
|
||||||
|
@property (nonatomic, strong) UIButton *speedBtn;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) NSArray *speeds;
|
||||||
|
@property (nonatomic, assign) NSInteger currentSpeed;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) GKDoubleLikeView *likeView;
|
||||||
|
@property (nonatomic, strong) NSDate *lastDoubleTapTime;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKDYVideoFullscreenView
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
if (self = [super init]) {
|
||||||
|
[self initUI];
|
||||||
|
self.speeds = @[@1, @1.5, @2, @0.5];
|
||||||
|
self.currentSpeed = 0;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)initUI {
|
||||||
|
[self addSubview:self.bottomView];
|
||||||
|
[self.bottomView addSubview:self.leftView];
|
||||||
|
[self.leftView addSubview:self.closeBtn];
|
||||||
|
[self.bottomView addSubview:self.rightView];
|
||||||
|
[self.rightView addSubview:self.playBtn];
|
||||||
|
[self.rightView addSubview:self.speedBtn];
|
||||||
|
|
||||||
|
[self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.right.equalTo(self);
|
||||||
|
make.bottom.equalTo(self);
|
||||||
|
make.height.mas_equalTo(44);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.leftView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.equalTo(self.bottomView).offset(10);
|
||||||
|
make.top.bottom.equalTo(self.bottomView);
|
||||||
|
make.width.mas_equalTo(58);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.closeBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.edges.equalTo(self.leftView);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.rightView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.right.equalTo(self.bottomView).offset(-10);
|
||||||
|
make.top.bottom.equalTo(self.bottomView);
|
||||||
|
make.width.mas_equalTo(100);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.playBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.top.bottom.equalTo(self.rightView);
|
||||||
|
make.right.equalTo(self.rightView.mas_centerX);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.speedBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.right.top.bottom.equalTo(self.rightView);
|
||||||
|
make.left.equalTo(self.rightView.mas_centerX);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - ZFPlayerMediaControl
|
||||||
|
@synthesize player = _player;
|
||||||
|
- (void)setPlayer:(ZFPlayerController *)player {
|
||||||
|
_player = player;
|
||||||
|
|
||||||
|
self.playBtn.selected = player.currentPlayerManager.isPlaying;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)gestureSingleTapped:(ZFPlayerGestureControl *)gestureControl {
|
||||||
|
CGFloat diff = [NSDate date].timeIntervalSince1970 - self.lastDoubleTapTime.timeIntervalSince1970;
|
||||||
|
if (diff < 0.6) {
|
||||||
|
[self handleDoubleTapped:gestureControl.singleTap];
|
||||||
|
self.lastDoubleTapTime = [NSDate date];
|
||||||
|
}else {
|
||||||
|
[self handleSingleTapped];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)gestureDoubleTapped:(ZFPlayerGestureControl *)gestureControl {
|
||||||
|
[self handleDoubleTapped:gestureControl.doubleTap];
|
||||||
|
self.lastDoubleTapTime = [NSDate date];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)gestureBeganPan:(ZFPlayerGestureControl *)gestureControl panDirection:(ZFPanDirection)direction panLocation:(ZFPanLocation)location {
|
||||||
|
[self closeAction];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handleSingleTapped {
|
||||||
|
[self playAction];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handleDoubleTapped:(UITapGestureRecognizer *)gesture {
|
||||||
|
CGPoint point = [gesture locationInView:gesture.view];
|
||||||
|
[self.likeView createAnimationWithPoint:point view:gesture.view completion:nil];
|
||||||
|
!self.likeBlock ?: self.likeBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - action
|
||||||
|
- (void)closeAction {
|
||||||
|
!self.closeFullscreenBlock ?: self.closeFullscreenBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)playAction {
|
||||||
|
id<ZFPlayerMediaPlayback> manager = self.player.currentPlayerManager;
|
||||||
|
if (manager.isPlaying) {
|
||||||
|
[manager pause];
|
||||||
|
self.playBtn.selected = NO;
|
||||||
|
}else {
|
||||||
|
[manager play];
|
||||||
|
self.playBtn.selected = YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)speedAction {
|
||||||
|
self.currentSpeed++;
|
||||||
|
if (self.currentSpeed == self.speeds.count) {
|
||||||
|
self.currentSpeed = 0;
|
||||||
|
}
|
||||||
|
float speed = [self.speeds[self.currentSpeed] floatValue];
|
||||||
|
self.player.currentPlayerManager.rate = speed;
|
||||||
|
[self.speedBtn setTitle:[NSString stringWithFormat:@"%@x", self.speeds[self.currentSpeed]] forState:UIControlStateNormal];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - lazy
|
||||||
|
- (UIView *)bottomView {
|
||||||
|
if (!_bottomView) {
|
||||||
|
_bottomView = [[UIView alloc] init];
|
||||||
|
}
|
||||||
|
return _bottomView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIView *)leftView {
|
||||||
|
if (!_leftView) {
|
||||||
|
_leftView = [[UIView alloc] init];
|
||||||
|
_leftView.backgroundColor = UIColor.darkGrayColor;
|
||||||
|
_leftView.layer.cornerRadius = 5;
|
||||||
|
_leftView.layer.masksToBounds = YES;
|
||||||
|
}
|
||||||
|
return _leftView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIButton *)closeBtn {
|
||||||
|
if (!_closeBtn) {
|
||||||
|
_closeBtn = [[UIButton alloc] init];
|
||||||
|
[_closeBtn setImage:[UIImage imageNamed:@"icon_feedback_close_Normal"] forState:UIControlStateNormal];
|
||||||
|
[_closeBtn addTarget:self action:@selector(closeAction) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
}
|
||||||
|
return _closeBtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIView *)rightView {
|
||||||
|
if (!_rightView) {
|
||||||
|
_rightView = [[UIView alloc] init];
|
||||||
|
_rightView.backgroundColor = UIColor.darkGrayColor;
|
||||||
|
_rightView.layer.cornerRadius = 5;
|
||||||
|
_rightView.layer.masksToBounds = YES;
|
||||||
|
}
|
||||||
|
return _rightView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIButton *)playBtn {
|
||||||
|
if (!_playBtn) {
|
||||||
|
_playBtn = [[UIButton alloc] init];
|
||||||
|
[_playBtn setImage:[UIImage imageNamed:@"icon_modern_feed_play_Normal"] forState:UIControlStateNormal];
|
||||||
|
[_playBtn setImage:[UIImage imageNamed:@"icon_music_pause_new_Normal"] forState:UIControlStateSelected];
|
||||||
|
[_playBtn addTarget:self action:@selector(playAction) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
}
|
||||||
|
return _playBtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIButton *)speedBtn {
|
||||||
|
if (!_speedBtn) {
|
||||||
|
_speedBtn = [[UIButton alloc] init];
|
||||||
|
[_speedBtn setTitle:@"1x" forState:UIControlStateNormal];
|
||||||
|
[_speedBtn setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
|
||||||
|
_speedBtn.titleLabel.font = [UIFont systemFontOfSize:14];
|
||||||
|
[_speedBtn addTarget:self action:@selector(speedAction) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
}
|
||||||
|
return _speedBtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKDoubleLikeView *)likeView {
|
||||||
|
if (!_likeView) {
|
||||||
|
_likeView = [[GKDoubleLikeView alloc] init];
|
||||||
|
}
|
||||||
|
return _likeView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
17
HiBit/Project/Player/View/GKDYVideoItemButton.h
Executable file
17
HiBit/Project/Player/View/GKDYVideoItemButton.h
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoItemButton.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/22.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GKDYVideoItemButton : UIButton
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
33
HiBit/Project/Player/View/GKDYVideoItemButton.m
Executable file
33
HiBit/Project/Player/View/GKDYVideoItemButton.m
Executable file
@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoItemButton.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/22.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYVideoItemButton.h"
|
||||||
|
|
||||||
|
@implementation GKDYVideoItemButton
|
||||||
|
|
||||||
|
- (void)layoutSubviews {
|
||||||
|
[super layoutSubviews];
|
||||||
|
|
||||||
|
[self.imageView sizeToFit];
|
||||||
|
[self.titleLabel sizeToFit];
|
||||||
|
|
||||||
|
CGFloat width = self.frame.size.width;
|
||||||
|
CGFloat height = self.frame.size.height;
|
||||||
|
|
||||||
|
CGFloat imgW = self.imageView.frame.size.width;
|
||||||
|
CGFloat imgH = self.imageView.frame.size.height;
|
||||||
|
|
||||||
|
self.imageView.frame = CGRectMake((width - imgH) / 2, 0, imgW, imgH);
|
||||||
|
|
||||||
|
CGFloat titleW = self.titleLabel.frame.size.width;
|
||||||
|
CGFloat titleH = self.titleLabel.frame.size.height;
|
||||||
|
|
||||||
|
self.titleLabel.frame = CGRectMake((width - titleW) / 2, height - titleH, titleW, titleH);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
26
HiBit/Project/Player/View/GKDYVideoLandscapeCell.h
Executable file
26
HiBit/Project/Player/View/GKDYVideoLandscapeCell.h
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoLandscapeCell.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/5/5.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYVideoCell.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GKDYVideoLandscapeCell : GKDYVideoCell
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL isShowTop;
|
||||||
|
|
||||||
|
@property (nonatomic, copy) void(^backClickBlock)(void);
|
||||||
|
|
||||||
|
- (void)hideTopView;
|
||||||
|
- (void)showTopView;
|
||||||
|
|
||||||
|
- (void)autoHide;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
110
HiBit/Project/Player/View/GKDYVideoLandscapeCell.m
Executable file
110
HiBit/Project/Player/View/GKDYVideoLandscapeCell.m
Executable file
@ -0,0 +1,110 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoLandscapeCell.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/5/5.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYVideoLandscapeCell.h"
|
||||||
|
#import "GKDYVideoMaskView.h"
|
||||||
|
#import "UIButton+GKEnlarge.h"
|
||||||
|
|
||||||
|
@interface GKDYVideoLandscapeCell()
|
||||||
|
|
||||||
|
@property (nonatomic, strong) GKDYVideoMaskView *topContainerView;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIButton *backBtn;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UILabel *titleLabel;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKDYVideoLandscapeCell
|
||||||
|
|
||||||
|
- (void)initUI {
|
||||||
|
[super initUI];
|
||||||
|
|
||||||
|
[self addSubview:self.topContainerView];
|
||||||
|
[self.topContainerView addSubview:self.backBtn];
|
||||||
|
[self.topContainerView addSubview:self.titleLabel];
|
||||||
|
|
||||||
|
[self.topContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.top.left.right.equalTo(self);
|
||||||
|
make.height.mas_equalTo(80);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.backBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.top.equalTo(self).offset(25);
|
||||||
|
make.left.equalTo(self.topContainerView.mas_safeAreaLayoutGuideLeft).offset(12);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.top.equalTo(self.backBtn).offset(3);
|
||||||
|
make.left.equalTo(self.backBtn.mas_right).offset(5);
|
||||||
|
make.right.equalTo(self.topContainerView.mas_safeAreaLayoutGuideRight).offset(-30);
|
||||||
|
}];
|
||||||
|
|
||||||
|
self.topContainerView.hidden = YES;
|
||||||
|
self.isShowTop = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)loadData:(GKDYVideoModel *)model {
|
||||||
|
[super loadData:model];
|
||||||
|
|
||||||
|
self.titleLabel.text = model.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)hideTopView {
|
||||||
|
self.topContainerView.hidden = YES;
|
||||||
|
self.isShowTop = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)showTopView {
|
||||||
|
self.topContainerView.hidden = NO;
|
||||||
|
self.isShowTop = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)autoHide {
|
||||||
|
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(hideTopView) object:nil];
|
||||||
|
[self performSelector:@selector(hideTopView) withObject:nil afterDelay:3.0f];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)resetView {
|
||||||
|
[super resetView];
|
||||||
|
[self showTopView];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)backAction {
|
||||||
|
!self.backClickBlock ?: self.backClickBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Lazy
|
||||||
|
- (GKDYVideoMaskView *)topContainerView {
|
||||||
|
if (!_topContainerView) {
|
||||||
|
_topContainerView = [[GKDYVideoMaskView alloc] initWithStyle:GKDYVideoMaskViewStyle_Top];
|
||||||
|
}
|
||||||
|
return _topContainerView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIButton *)backBtn {
|
||||||
|
if (!_backBtn) {
|
||||||
|
_backBtn = [[UIButton alloc] init];
|
||||||
|
[_backBtn setEnlargeEdge:10];
|
||||||
|
[_backBtn setImage:[UIImage imageNamed:@"ic_back_white"] forState:UIControlStateNormal];
|
||||||
|
[_backBtn addTarget:self action:@selector(backAction) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
}
|
||||||
|
return _backBtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)titleLabel {
|
||||||
|
if (!_titleLabel) {
|
||||||
|
_titleLabel = [[UILabel alloc] init];
|
||||||
|
_titleLabel.font = [UIFont boldSystemFontOfSize:15];
|
||||||
|
_titleLabel.textColor = UIColor.whiteColor;
|
||||||
|
_titleLabel.numberOfLines = 0;
|
||||||
|
}
|
||||||
|
return _titleLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
37
HiBit/Project/Player/View/GKDYVideoLandscapeView.h
Executable file
37
HiBit/Project/Player/View/GKDYVideoLandscapeView.h
Executable file
@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoLandscapeView.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/17.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <ZFPlayer/ZFPlayer.h>
|
||||||
|
#import "GKDYVideoModel.h"
|
||||||
|
#import "GKRotationManager.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GKDYVideoLandscapeView : UIView<ZFPlayerMediaControl>
|
||||||
|
|
||||||
|
@property (nonatomic, strong) GKDYVideoModel *model;
|
||||||
|
|
||||||
|
@property (nonatomic, weak) GKRotationManager *rotationManager;
|
||||||
|
|
||||||
|
@property (nonatomic, copy) void(^likeBlock)(GKDYVideoModel *model);
|
||||||
|
|
||||||
|
@property (nonatomic, copy) void(^singleTapBlock)(void);
|
||||||
|
|
||||||
|
- (void)startTimer;
|
||||||
|
- (void)destoryTimer;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL isContainerShow;
|
||||||
|
- (void)showContainerView:(BOOL)animated;
|
||||||
|
- (void)hideContainerView:(BOOL)animated;
|
||||||
|
|
||||||
|
- (void)autoHide;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
491
HiBit/Project/Player/View/GKDYVideoLandscapeView.m
Executable file
491
HiBit/Project/Player/View/GKDYVideoLandscapeView.m
Executable file
@ -0,0 +1,491 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoLandscapeView.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/17.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYVideoLandscapeView.h"
|
||||||
|
#import "GKDYVideoStatusBar.h"
|
||||||
|
#import "GKDYVideoMaskView.h"
|
||||||
|
#import "GKDoubleLikeView.h"
|
||||||
|
#import <GKSliderView/GKSliderView.h>
|
||||||
|
#import "UIButton+GKEnlarge.h"
|
||||||
|
#import <ZFPlayer/ZFReachabilityManager.h>
|
||||||
|
#import "GKDYVideoPreviewView.h"
|
||||||
|
|
||||||
|
|
||||||
|
@interface GKDYVideoLandscapeView()<GKSliderViewDelegate, GKSliderViewPreviewDelegate>
|
||||||
|
|
||||||
|
// 顶部
|
||||||
|
@property (nonatomic, strong) GKDYVideoMaskView *topContainerView;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) GKDYVideoStatusBar *statusBar;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIButton *backBtn;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UILabel *nameLabel;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UILabel *contentLabel;
|
||||||
|
|
||||||
|
// 底部
|
||||||
|
@property (nonatomic, strong) GKDYVideoMaskView *bottomContainerView;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) GKSliderView *sliderView;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIButton *playBtn;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UILabel *timeLabel;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIButton *likeBtn;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIButton *exitBtn;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) GKDoubleLikeView *likeView;
|
||||||
|
@property (nonatomic, strong) NSDate *lastDoubleTapTime;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL isDragging;
|
||||||
|
@property (nonatomic ,assign) BOOL isSeeking;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKDYVideoLandscapeView
|
||||||
|
|
||||||
|
- (instancetype)initWithFrame:(CGRect)frame {
|
||||||
|
if (self = [super initWithFrame:frame]) {
|
||||||
|
[self initUI];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)initUI {
|
||||||
|
[self addSubview:self.topContainerView];
|
||||||
|
[self.topContainerView addSubview:self.statusBar];
|
||||||
|
[self.topContainerView addSubview:self.backBtn];
|
||||||
|
[self.topContainerView addSubview:self.contentLabel];
|
||||||
|
[self.topContainerView addSubview:self.nameLabel];
|
||||||
|
|
||||||
|
[self addSubview:self.bottomContainerView];
|
||||||
|
[self.bottomContainerView addSubview:self.sliderView];
|
||||||
|
[self.bottomContainerView addSubview:self.playBtn];
|
||||||
|
[self.bottomContainerView addSubview:self.timeLabel];
|
||||||
|
[self.bottomContainerView addSubview:self.likeBtn];
|
||||||
|
[self.bottomContainerView addSubview:self.exitBtn];
|
||||||
|
|
||||||
|
[self.topContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.top.left.right.equalTo(self);
|
||||||
|
make.height.mas_equalTo(80);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.statusBar mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.top.equalTo(self.topContainerView.mas_safeAreaLayoutGuideTop);
|
||||||
|
make.left.equalTo(self.topContainerView.mas_safeAreaLayoutGuideLeft).offset(10);
|
||||||
|
make.right.equalTo(self.topContainerView.mas_safeAreaLayoutGuideRight).offset(-10);
|
||||||
|
make.height.mas_equalTo(20);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.backBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.top.equalTo(self.statusBar.mas_bottom).offset(5);
|
||||||
|
make.left.equalTo(self.statusBar).offset(2);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.top.equalTo(self.backBtn).offset(3);
|
||||||
|
make.left.equalTo(self.backBtn.mas_right).offset(5);
|
||||||
|
make.right.equalTo(self.statusBar.mas_right).offset(-20);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.equalTo(self.contentLabel);
|
||||||
|
make.top.equalTo(self.contentLabel.mas_bottom).offset(5);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.bottomContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.bottom.left.right.equalTo(self);
|
||||||
|
make.height.mas_equalTo(80);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.sliderView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.equalTo(self.bottomContainerView.mas_safeAreaLayoutGuideLeft).offset(10);
|
||||||
|
make.right.equalTo(self.bottomContainerView.mas_safeAreaLayoutGuideRight).offset(-10);
|
||||||
|
make.bottom.equalTo(self.playBtn.mas_top).offset(-10);
|
||||||
|
make.height.mas_equalTo(10);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.playBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.equalTo(self.sliderView);
|
||||||
|
make.bottom.equalTo(self.bottomContainerView).offset(-10);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.centerY.equalTo(self.playBtn);
|
||||||
|
make.left.equalTo(self.playBtn.mas_right).offset(10);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.likeBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.centerY.equalTo(self.playBtn);
|
||||||
|
make.right.equalTo(self.exitBtn.mas_left).offset(-20);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.exitBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.centerY.equalTo(self.playBtn);
|
||||||
|
make.right.equalTo(self.sliderView.mas_right);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setModel:(GKDYVideoModel *)model {
|
||||||
|
_model = model;
|
||||||
|
|
||||||
|
self.contentLabel.text = model.detailText;
|
||||||
|
self.nameLabel.text = model.title;
|
||||||
|
self.likeBtn.selected = model.is_collect;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)startTimer {
|
||||||
|
[self.statusBar startTimer];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)destoryTimer {
|
||||||
|
[self.statusBar destoryTimer];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - ZFPlayerMediaControl
|
||||||
|
@synthesize player = _player;
|
||||||
|
- (void)setPlayer:(ZFPlayerController *)player {
|
||||||
|
_player = player;
|
||||||
|
|
||||||
|
GKDYVideoPreviewView *videoPreview = (GKDYVideoPreviewView *)self.sliderView.preview;
|
||||||
|
videoPreview.player = player;
|
||||||
|
|
||||||
|
self.playBtn.selected = player.currentPlayerManager.isPlaying;
|
||||||
|
[self setNetworkState];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)videoPlayer:(ZFPlayerController *)videoPlayer orientationDidChanged:(ZFOrientationObserver *)observer {
|
||||||
|
if (videoPlayer.isFullScreen) {
|
||||||
|
[self showContainerView:NO];
|
||||||
|
[self cancelAutoHidden];
|
||||||
|
[self performSelector:@selector(hideContainerView:) withObject:@(YES) afterDelay:5.0f];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)gestureSingleTapped:(ZFPlayerGestureControl *)gestureControl {
|
||||||
|
CGFloat diff = [NSDate date].timeIntervalSince1970 - self.lastDoubleTapTime.timeIntervalSince1970;
|
||||||
|
if (diff < 0.6) {
|
||||||
|
[self handleDoubleTapped:gestureControl.singleTap];
|
||||||
|
self.lastDoubleTapTime = [NSDate date];
|
||||||
|
}else {
|
||||||
|
[self handleSingleTapped];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)gestureDoubleTapped:(ZFPlayerGestureControl *)gestureControl {
|
||||||
|
[self handleDoubleTapped:gestureControl.doubleTap];
|
||||||
|
self.lastDoubleTapTime = [NSDate date];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)videoPlayer:(ZFPlayerController *)videoPlayer reachabilityChanged:(ZFReachabilityStatus)status {
|
||||||
|
[self setNetworkState];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)videoPlayer:(ZFPlayerController *)videoPlayer currentTime:(NSTimeInterval)currentTime totalTime:(NSTimeInterval)totalTime {
|
||||||
|
if (self.isDragging) return;
|
||||||
|
if (self.isSeeking) return;
|
||||||
|
self.sliderView.value = self.player.progress;
|
||||||
|
self.timeLabel.text = [NSString stringWithFormat:@"%@ / %@", [NSString convertTimeSecond:currentTime], [NSString convertTimeSecond:totalTime]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handleSingleTapped {
|
||||||
|
!self.singleTapBlock ?: self.singleTapBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handleDoubleTapped:(UITapGestureRecognizer *)gesture {
|
||||||
|
[self cancelAutoHidden];
|
||||||
|
|
||||||
|
CGPoint point = [gesture locationInView:gesture.view];
|
||||||
|
@weakify(self);
|
||||||
|
[self.likeView createAnimationWithPoint:point view:gesture.view completion:^{
|
||||||
|
@strongify(self);
|
||||||
|
[self performSelector:@selector(hideContainerView) withObject:nil afterDelay:5.0f];
|
||||||
|
}];
|
||||||
|
self.model.is_collect = YES;
|
||||||
|
self.likeBtn.selected = self.model.is_collect;
|
||||||
|
!self.likeBlock ?: self.likeBlock(self.model);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Public
|
||||||
|
- (void)showContainerView:(BOOL)animated {
|
||||||
|
[self.topContainerView mas_updateConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.top.equalTo(self);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.bottomContainerView mas_updateConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.bottom.equalTo(self);
|
||||||
|
}];
|
||||||
|
|
||||||
|
self.topContainerView.hidden = NO;
|
||||||
|
self.bottomContainerView.hidden = NO;
|
||||||
|
|
||||||
|
NSTimeInterval duration = animated ? 0.2 : 0;
|
||||||
|
|
||||||
|
[UIView animateWithDuration:duration animations:^{
|
||||||
|
[self layoutIfNeeded];
|
||||||
|
} completion:^(BOOL finished) {
|
||||||
|
self.isContainerShow = YES;
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)hideContainerView {
|
||||||
|
[self hideContainerView:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)hideContainerView:(BOOL)animated {
|
||||||
|
[self.topContainerView mas_updateConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.top.equalTo(self).offset(-80);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.bottomContainerView mas_updateConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.bottom.equalTo(self).offset(80);
|
||||||
|
}];
|
||||||
|
|
||||||
|
NSTimeInterval duration = animated ? 0.15 : 0;
|
||||||
|
|
||||||
|
[UIView animateWithDuration:duration animations:^{
|
||||||
|
[self layoutIfNeeded];
|
||||||
|
} completion:^(BOOL finished) {
|
||||||
|
self.isContainerShow = NO;
|
||||||
|
self.topContainerView.hidden = YES;
|
||||||
|
self.bottomContainerView.hidden = YES;
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)autoHide {
|
||||||
|
[self cancelAutoHidden];
|
||||||
|
|
||||||
|
if (self.isContainerShow) {
|
||||||
|
[self hideContainerView:YES];
|
||||||
|
}else {
|
||||||
|
[self showContainerView:YES];
|
||||||
|
[self performSelector:@selector(hideContainerView) withObject:nil afterDelay:5.0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)cancelAutoHidden {
|
||||||
|
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(hideContainerView) object:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setNetworkState {
|
||||||
|
NSString *net = @"WIFI";
|
||||||
|
switch (ZFReachabilityManager.sharedManager.networkReachabilityStatus) {
|
||||||
|
case ZFReachabilityStatusReachableViaWiFi:
|
||||||
|
net = @"WIFI";
|
||||||
|
break;
|
||||||
|
case ZFReachabilityStatusNotReachable:
|
||||||
|
net = @"无网络";
|
||||||
|
break;
|
||||||
|
case ZFReachabilityStatusReachableVia2G:
|
||||||
|
net = @"2G";
|
||||||
|
break;
|
||||||
|
case ZFReachabilityStatusReachableVia3G:
|
||||||
|
net = @"3G";
|
||||||
|
break;
|
||||||
|
case ZFReachabilityStatusReachableVia4G:
|
||||||
|
net = @"4G";
|
||||||
|
break;
|
||||||
|
case ZFReachabilityStatusReachableVia5G:
|
||||||
|
net = @"5G";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
net = @"未知";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
self.statusBar.network = net;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Action
|
||||||
|
- (void)backAction {
|
||||||
|
[self cancelAutoHidden];
|
||||||
|
[self.rotationManager rotate];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)playAction {
|
||||||
|
[self cancelAutoHidden];
|
||||||
|
id<ZFPlayerMediaPlayback> manager = self.player.currentPlayerManager;
|
||||||
|
if (manager.isPlaying) {
|
||||||
|
[manager pause];
|
||||||
|
}else {
|
||||||
|
[manager play];
|
||||||
|
}
|
||||||
|
self.playBtn.selected = manager.isPlaying;
|
||||||
|
[self autoHide];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)likeAction {
|
||||||
|
[self cancelAutoHidden];
|
||||||
|
self.model.is_collect = !self.model.is_collect;
|
||||||
|
self.likeBtn.selected = self.model.is_collect;
|
||||||
|
!self.likeBlock ?: self.likeBlock(self.model);
|
||||||
|
[self autoHide];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)exitAction {
|
||||||
|
[self backAction];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - GKSliderViewDelegate
|
||||||
|
- (void)sliderView:(GKSliderView *)sliderView touchBegan:(float)value {
|
||||||
|
self.isDragging = YES;
|
||||||
|
[self showLargeSlider];
|
||||||
|
[self cancelAutoHidden];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)sliderView:(GKSliderView *)sliderView touchEnded:(float)value {
|
||||||
|
self.isDragging = NO;
|
||||||
|
[self showSmallSlider];
|
||||||
|
[self autoHide];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - GKSliderViewPreviewDelegate
|
||||||
|
- (UIView *)sliderViewSetupPreview:(GKSliderView *)sliderView {
|
||||||
|
GKDYVideoPreviewView *preview = [[GKDYVideoPreviewView alloc] init];
|
||||||
|
preview.bounds = CGRectMake(0, 0, 120, 120);
|
||||||
|
return preview;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGFloat)sliderViewPreviewMargin:(GKSliderView *)sliderView {
|
||||||
|
return 40;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)sliderView:(GKSliderView *)sliderView preview:(UIView *)preview valueChanged:(float)value {
|
||||||
|
GKDYVideoPreviewView *videoPreview = (GKDYVideoPreviewView *)preview;
|
||||||
|
[videoPreview setPreviewValue:value];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)showLargeSlider {
|
||||||
|
self.sliderView.sliderBtn.transform = CGAffineTransformMakeScale(1.5, 1.5);
|
||||||
|
self.sliderView.sliderHeight = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)showSmallSlider {
|
||||||
|
self.sliderView.sliderBtn.transform = CGAffineTransformIdentity;
|
||||||
|
self.sliderView.sliderHeight = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Lazy
|
||||||
|
- (GKDYVideoMaskView *)topContainerView {
|
||||||
|
if (!_topContainerView) {
|
||||||
|
_topContainerView = [[GKDYVideoMaskView alloc] initWithStyle:GKDYVideoMaskViewStyle_Top];
|
||||||
|
}
|
||||||
|
return _topContainerView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKDYVideoMaskView *)bottomContainerView {
|
||||||
|
if (!_bottomContainerView) {
|
||||||
|
_bottomContainerView = [[GKDYVideoMaskView alloc] initWithStyle:GKDYVideoMaskViewStyle_Bottom];
|
||||||
|
}
|
||||||
|
return _bottomContainerView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKDYVideoStatusBar *)statusBar {
|
||||||
|
if (!_statusBar) {
|
||||||
|
_statusBar = [[GKDYVideoStatusBar alloc] init];
|
||||||
|
}
|
||||||
|
return _statusBar;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIButton *)backBtn {
|
||||||
|
if (!_backBtn) {
|
||||||
|
_backBtn = [[UIButton alloc] init];
|
||||||
|
[_backBtn setImage:[UIImage imageNamed:@"ic_back_white"] forState:UIControlStateNormal];
|
||||||
|
[_backBtn addTarget:self action:@selector(backAction) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
[_backBtn setEnlargeEdge:10];
|
||||||
|
}
|
||||||
|
return _backBtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)contentLabel {
|
||||||
|
if (!_contentLabel) {
|
||||||
|
_contentLabel = [[UILabel alloc] init];
|
||||||
|
_contentLabel.font = [UIFont boldSystemFontOfSize:15];
|
||||||
|
_contentLabel.textColor = UIColor.whiteColor;
|
||||||
|
_contentLabel.numberOfLines = 0;
|
||||||
|
}
|
||||||
|
return _contentLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)nameLabel {
|
||||||
|
if (!_nameLabel) {
|
||||||
|
_nameLabel = [[UILabel alloc] init];
|
||||||
|
_nameLabel.font = [UIFont systemFontOfSize:14];
|
||||||
|
_nameLabel.textColor = UIColor.whiteColor;
|
||||||
|
}
|
||||||
|
return _nameLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKSliderView *)sliderView {
|
||||||
|
if (!_sliderView) {
|
||||||
|
_sliderView = [[GKSliderView alloc] init];
|
||||||
|
// [_sliderView setThumbImage:[UIImage imageNamed:@"icon_slider"] forState:UIControlStateNormal];
|
||||||
|
// [_sliderView setThumbImage:[UIImage imageNamed:@"icon_slider"] forState:UIControlStateHighlighted];
|
||||||
|
_sliderView.maximumTrackTintColor = UIColor.grayColor;
|
||||||
|
_sliderView.minimumTrackTintColor = HBColor.color_FF0049;
|
||||||
|
_sliderView.sliderHeight = 2;
|
||||||
|
_sliderView.delegate = self;
|
||||||
|
_sliderView.previewDelegate = self;
|
||||||
|
_sliderView.isPreviewChangePosition = NO;
|
||||||
|
_sliderView.isSliderAllowTapped = YES;
|
||||||
|
_sliderView.isSliderAllowDragged = YES;
|
||||||
|
}
|
||||||
|
return _sliderView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIButton *)playBtn {
|
||||||
|
if (!_playBtn) {
|
||||||
|
_playBtn = [[UIButton alloc] init];
|
||||||
|
[_playBtn setImage:[UIImage imageNamed:@"icon_play"] forState:UIControlStateNormal];
|
||||||
|
[_playBtn setImage:[UIImage imageNamed:@"icon_pause"] forState:UIControlStateSelected];
|
||||||
|
[_playBtn addTarget:self action:@selector(playAction) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
[_playBtn setEnlargeEdge:10];
|
||||||
|
}
|
||||||
|
return _playBtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)timeLabel {
|
||||||
|
if (!_timeLabel) {
|
||||||
|
_timeLabel = [[UILabel alloc] init];
|
||||||
|
_timeLabel.font = [UIFont systemFontOfSize:13];
|
||||||
|
_timeLabel.textColor = UIColor.whiteColor;
|
||||||
|
}
|
||||||
|
return _timeLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIButton *)likeBtn {
|
||||||
|
if (!_likeBtn) {
|
||||||
|
_likeBtn = [[UIButton alloc] init];
|
||||||
|
[_likeBtn setImage:[UIImage imageNamed:@"ss_icon_star_normal"] forState:UIControlStateNormal];
|
||||||
|
[_likeBtn setImage:[UIImage imageNamed:@"ss_icon_star_selected"] forState:UIControlStateSelected];
|
||||||
|
[_likeBtn addTarget:self action:@selector(likeAction) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
[_likeBtn setEnlargeEdge:10];
|
||||||
|
}
|
||||||
|
return _likeBtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIButton *)exitBtn {
|
||||||
|
if (!_exitBtn) {
|
||||||
|
_exitBtn = [[UIButton alloc] init];
|
||||||
|
[_exitBtn setImage:[UIImage imageNamed:@"ss_icon_shrinkscreen"] forState:UIControlStateNormal];
|
||||||
|
[_exitBtn addTarget:self action:@selector(exitAction) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
[_exitBtn setEnlargeEdge:10];
|
||||||
|
}
|
||||||
|
return _exitBtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKDoubleLikeView *)likeView {
|
||||||
|
if (!_likeView) {
|
||||||
|
_likeView = [[GKDoubleLikeView alloc] init];
|
||||||
|
}
|
||||||
|
return _likeView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
26
HiBit/Project/Player/View/GKDYVideoMaskView.h
Executable file
26
HiBit/Project/Player/View/GKDYVideoMaskView.h
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoMaskView.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/22.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSUInteger, GKDYVideoMaskViewStyle) {
|
||||||
|
GKDYVideoMaskViewStyle_Top, // 顶部,(上->下)从深到浅
|
||||||
|
GKDYVideoMaskViewStyle_Bottom // 底部,(上->下)从浅到深
|
||||||
|
};
|
||||||
|
|
||||||
|
@interface GKDYVideoMaskView : UIView
|
||||||
|
|
||||||
|
- (instancetype)initWithStyle:(GKDYVideoMaskViewStyle)style;
|
||||||
|
|
||||||
|
- (void)clearColors;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
48
HiBit/Project/Player/View/GKDYVideoMaskView.m
Executable file
48
HiBit/Project/Player/View/GKDYVideoMaskView.m
Executable file
@ -0,0 +1,48 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoMaskView.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/22.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYVideoMaskView.h"
|
||||||
|
|
||||||
|
@interface GKDYVideoMaskView()
|
||||||
|
|
||||||
|
@property (nonatomic, assign) GKDYVideoMaskViewStyle style;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKDYVideoMaskView
|
||||||
|
|
||||||
|
+ (Class)layerClass {
|
||||||
|
return CAGradientLayer.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithStyle:(GKDYVideoMaskViewStyle)style {
|
||||||
|
if (self = [super init]) {
|
||||||
|
self.style = style;
|
||||||
|
CAGradientLayer *maskGradientLayer = (id)self.layer;
|
||||||
|
switch (self.style) {
|
||||||
|
case GKDYVideoMaskViewStyle_Top: {
|
||||||
|
maskGradientLayer.colors = @[(__bridge id)[UIColor colorWithWhite:0 alpha:0.8].CGColor,
|
||||||
|
(__bridge id)[UIColor clearColor].CGColor];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GKDYVideoMaskViewStyle_Bottom: {
|
||||||
|
maskGradientLayer.colors = @[(__bridge id)[UIColor clearColor].CGColor,
|
||||||
|
(__bridge id)[UIColor colorWithWhite:0 alpha:0.8].CGColor];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)clearColors {
|
||||||
|
CAGradientLayer *maskGradientLayer = (id)self.layer;
|
||||||
|
maskGradientLayer.colors = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
49
HiBit/Project/Player/View/GKDYVideoPortraitCell.h
Executable file
49
HiBit/Project/Player/View/GKDYVideoPortraitCell.h
Executable file
@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoPortraitCell.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/5/5.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYVideoCell.h"
|
||||||
|
#import "GKDYPlayerManager.h"
|
||||||
|
#import "GKDYVideoPortraitView.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@class GKDYVideoPortraitCell;
|
||||||
|
|
||||||
|
@protocol GKDYVideoPortraitCellDelegate <NSObject>
|
||||||
|
|
||||||
|
@optional;
|
||||||
|
|
||||||
|
- (void)videoCell:(GKDYVideoPortraitCell *)cell didClickFavorite:(GKDYVideoModel *)model;
|
||||||
|
|
||||||
|
- (void)videoCell:(GKDYVideoPortraitCell *)cell didClickEpiscode:(GKDYVideoModel *)model;
|
||||||
|
|
||||||
|
- (void)videoCell:(GKDYVideoPortraitCell *)cell didClickShare:(GKDYVideoModel *)model;
|
||||||
|
|
||||||
|
- (void)videoCell:(GKDYVideoPortraitCell *)cell didClickDanmu:(GKDYVideoModel *)model;
|
||||||
|
|
||||||
|
- (void)videoCell:(GKDYVideoPortraitCell *)cell didClickFullscreen:(GKDYVideoModel *)model;
|
||||||
|
|
||||||
|
- (void)videoCell:(GKDYVideoPortraitCell *)cell zoomBegan:(GKDYVideoModel *)model;
|
||||||
|
|
||||||
|
- (void)videoCell:(GKDYVideoPortraitCell *)cell zoomEnded:(GKDYVideoModel *)model isFullscreen:(BOOL)isFullscreen;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface GKDYVideoPortraitCell : GKDYVideoCell
|
||||||
|
|
||||||
|
@property (nonatomic, weak) id<GKDYVideoPortraitCellDelegate> delegate;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) GKDYVideoPortraitView *portraitView;
|
||||||
|
|
||||||
|
@property (nonatomic, weak) GKDYPlayerManager *manager;
|
||||||
|
|
||||||
|
- (void)closeFullscreen;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
174
HiBit/Project/Player/View/GKDYVideoPortraitCell.m
Executable file
174
HiBit/Project/Player/View/GKDYVideoPortraitCell.m
Executable file
@ -0,0 +1,174 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoPortraitCell.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/5/5.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYVideoPortraitCell.h"
|
||||||
|
|
||||||
|
@interface GKDYVideoPortraitCell()<GKDYVideoPortraitViewDelegate, UIScrollViewDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIScrollView *scrollView;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL isFullscreen;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL isCodeSet;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKDYVideoPortraitCell
|
||||||
|
|
||||||
|
- (void)initUI {
|
||||||
|
[self addSubview:self.scrollView];
|
||||||
|
[self.scrollView addSubview:self.coverImgView];
|
||||||
|
|
||||||
|
// [self addSubview:self.coverImgView];
|
||||||
|
[self.coverImgView addSubview:self.portraitView];
|
||||||
|
|
||||||
|
[self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.edges.equalTo(self);
|
||||||
|
}];
|
||||||
|
|
||||||
|
// [self.coverImgView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
// make.edges.equalTo(self);
|
||||||
|
// }];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)layoutSubviews {
|
||||||
|
[super layoutSubviews];
|
||||||
|
|
||||||
|
self.coverImgView.frame = self.scrollView.bounds;
|
||||||
|
self.portraitView.frame = self.coverImgView.bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)loadData:(GKDYVideoModel *)model {
|
||||||
|
[super loadData:model];
|
||||||
|
|
||||||
|
self.portraitView.model = model;
|
||||||
|
|
||||||
|
if (self.manager) {
|
||||||
|
[self.manager requestPlayUrlWithModel:model completion:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)resetView {
|
||||||
|
[super resetView];
|
||||||
|
|
||||||
|
self.portraitView.slider.player = nil;
|
||||||
|
self.portraitView.slider.sliderView.value = 0;
|
||||||
|
self.portraitView.hidden = NO;
|
||||||
|
self.portraitView.frame = self.coverImgView.bounds;
|
||||||
|
[self.coverImgView addSubview:self.portraitView];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - UIScrollViewDelegate
|
||||||
|
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
|
||||||
|
return self.coverImgView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
|
||||||
|
self.coverImgView.center = [self centerOfScrollViewContent:scrollView];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view {
|
||||||
|
if (self.isCodeSet) return;
|
||||||
|
if ([self.delegate respondsToSelector:@selector(videoCell:zoomBegan:)]) {
|
||||||
|
[self.delegate videoCell:self zoomBegan:self.model];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {
|
||||||
|
if (self.isCodeSet) {
|
||||||
|
self.isCodeSet = NO;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ([self.delegate respondsToSelector:@selector(videoCell:zoomEnded:isFullscreen:)]) {
|
||||||
|
BOOL isFullscreen = NO;
|
||||||
|
if (scale > 1) {
|
||||||
|
isFullscreen = YES;
|
||||||
|
self.isFullscreen = isFullscreen;
|
||||||
|
}else {
|
||||||
|
self.isFullscreen = !self.isFullscreen;
|
||||||
|
isFullscreen = self.isFullscreen;
|
||||||
|
}
|
||||||
|
[self.delegate videoCell:self zoomEnded:self.model isFullscreen:isFullscreen];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scale != 1) {
|
||||||
|
self.isCodeSet = YES;
|
||||||
|
[scrollView setZoomScale:1.0f animated:YES];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGPoint)centerOfScrollViewContent:(UIScrollView *)scrollView {
|
||||||
|
CGFloat offsetX = (scrollView.bounds.size.width > scrollView.contentSize.width) ? (scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5 : 0;
|
||||||
|
CGFloat offsetY = (scrollView.bounds.size.height > scrollView.contentSize.height) ? (scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5 : 0;
|
||||||
|
CGPoint actualCenter = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX, scrollView.contentSize.height * 0.5 + offsetY);
|
||||||
|
return actualCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)closeFullscreen {
|
||||||
|
self.isFullscreen = NO;
|
||||||
|
if ([self.delegate respondsToSelector:@selector(videoCell:zoomEnded:isFullscreen:)]) {
|
||||||
|
[self.delegate videoCell:self zoomEnded:self.model isFullscreen:self.isFullscreen];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - GKDYVideoPortraitViewDelegate
|
||||||
|
|
||||||
|
- (void)videoPortraitView:(GKDYVideoPortraitView *) view didClickFavorite:(GKDYVideoModel *)model {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(videoCell:didClickFavorite:)]) {
|
||||||
|
[self.delegate videoCell:self didClickFavorite:model];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)videoPortraitView:(GKDYVideoPortraitView *) view didClickEpiscode:(GKDYVideoModel *)model {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(videoCell:didClickEpiscode:)]) {
|
||||||
|
[self.delegate videoCell:self didClickEpiscode:model];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)videoPortraitView:(GKDYVideoPortraitView *) view didClickShare:(GKDYVideoModel *)model {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(videoCell:didClickShare:)]) {
|
||||||
|
[self.delegate videoCell:self didClickShare:model];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)videoPortraitView:(GKDYVideoPortraitView *) view didClickDanmu:(GKDYVideoModel *)model {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(videoCell:didClickDanmu:)]) {
|
||||||
|
[self.delegate videoCell:self didClickDanmu:model];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)videoPortraitView:(GKDYVideoPortraitView *) view didClickFullscreen:(GKDYVideoModel *)model {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(videoCell:didClickFullscreen:)]) {
|
||||||
|
[self.delegate videoCell:self didClickFullscreen:model];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Lazy
|
||||||
|
- (UIScrollView *)scrollView {
|
||||||
|
if (!_scrollView) {
|
||||||
|
_scrollView = [[UIScrollView alloc] init];
|
||||||
|
_scrollView.delegate = self;
|
||||||
|
_scrollView.backgroundColor = UIColor.clearColor;
|
||||||
|
_scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
||||||
|
_scrollView.showsVerticalScrollIndicator = NO;
|
||||||
|
_scrollView.showsHorizontalScrollIndicator = NO;
|
||||||
|
_scrollView.minimumZoomScale = 1.0f;
|
||||||
|
_scrollView.maximumZoomScale = 10.0f;
|
||||||
|
}
|
||||||
|
return _scrollView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKDYVideoPortraitView *)portraitView {
|
||||||
|
if (!_portraitView) {
|
||||||
|
_portraitView = [[GKDYVideoPortraitView alloc] initWithFrame:UIScreen.mainScreen.bounds];
|
||||||
|
_portraitView.delegate = self;
|
||||||
|
}
|
||||||
|
return _portraitView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
64
HiBit/Project/Player/View/GKDYVideoPortraitView.h
Executable file
64
HiBit/Project/Player/View/GKDYVideoPortraitView.h
Executable file
@ -0,0 +1,64 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoPortraitView.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/17.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <ZFPlayer/ZFPlayer.h>
|
||||||
|
#import "GKDYVideoModel.h"
|
||||||
|
#import "GKDYVideoSlider.h"
|
||||||
|
#import "GKLikeView.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@class GKDYVideoPortraitView;
|
||||||
|
|
||||||
|
@protocol GKDYVideoPortraitViewDelegate <NSObject>
|
||||||
|
|
||||||
|
/// 收藏点击事件代理
|
||||||
|
- (void)videoPortraitView:(GKDYVideoPortraitView *) view didClickFavorite:(GKDYVideoModel *)model;
|
||||||
|
|
||||||
|
/// 剧集点击事件代理
|
||||||
|
- (void)videoPortraitView:(GKDYVideoPortraitView *) view didClickEpiscode:(GKDYVideoModel *)model;
|
||||||
|
|
||||||
|
/// 分享点击事件代理
|
||||||
|
- (void)videoPortraitView:(GKDYVideoPortraitView *) view didClickShare:(GKDYVideoModel *)model;
|
||||||
|
|
||||||
|
/// 弹幕点击事件代理
|
||||||
|
- (void)videoPortraitView:(GKDYVideoPortraitView *) view didClickDanmu:(GKDYVideoModel *)model;
|
||||||
|
|
||||||
|
/// 全屏点击事件代理
|
||||||
|
- (void)videoPortraitView:(GKDYVideoPortraitView *) view didClickFullscreen:(GKDYVideoModel *)model;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface GKDYVideoPortraitView : UIView<ZFPlayerMediaControl>
|
||||||
|
|
||||||
|
@property (nonatomic, weak) id<GKDYVideoPortraitViewDelegate> delegate;
|
||||||
|
|
||||||
|
/// 数据模型
|
||||||
|
@property (nonatomic, strong) GKDYVideoModel * model;
|
||||||
|
|
||||||
|
/// 视频介绍等
|
||||||
|
@property (nonatomic, strong) UIView * bottomContainerView;
|
||||||
|
|
||||||
|
/// 进度条
|
||||||
|
@property (nonatomic, strong) GKDYVideoSlider * slider;
|
||||||
|
|
||||||
|
/// 收藏按钮 带动画
|
||||||
|
@property (nonatomic, strong) GKLikeView * favoriteButton;
|
||||||
|
|
||||||
|
/// 继续播放按钮
|
||||||
|
@property (nonatomic, strong) UIButton * resumeButton;
|
||||||
|
|
||||||
|
- (void)handleSingleTapped;
|
||||||
|
- (void)willBeginDragging;
|
||||||
|
- (void)didEndDragging;
|
||||||
|
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
393
HiBit/Project/Player/View/GKDYVideoPortraitView.m
Executable file
393
HiBit/Project/Player/View/GKDYVideoPortraitView.m
Executable file
@ -0,0 +1,393 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoPortraitView.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/17.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYVideoPortraitView.h"
|
||||||
|
#import "GKDYVideoItemButton.h"
|
||||||
|
#import "GKDoubleLikeView.h"
|
||||||
|
#import "UIButton+GKEnlarge.h"
|
||||||
|
|
||||||
|
@interface GKDYVideoPortraitView()
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIView * buttonContainerView;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UILabel * titleLabel;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UILabel * contentLabel;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UILabel * episcodeLabel;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIButton * shareButton;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) RSButton * episcodeButton;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIButton * danmuButton;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIButton * fullscreenButton;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) GKDoubleLikeView * doubleLikeView;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) NSDate * lastDoubleTapTime;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKDYVideoPortraitView
|
||||||
|
|
||||||
|
@synthesize player = _player;
|
||||||
|
|
||||||
|
- (instancetype)initWithFrame:(CGRect)frame {
|
||||||
|
if (self = [super initWithFrame:frame]) {
|
||||||
|
[self initUI];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
- (void)dealloc {
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)initUI {
|
||||||
|
|
||||||
|
|
||||||
|
[self addSubview:self.bottomContainerView];
|
||||||
|
[self.bottomContainerView addSubview:self.contentLabel];
|
||||||
|
[self.bottomContainerView addSubview:self.episcodeLabel];
|
||||||
|
[self.bottomContainerView addSubview:self.titleLabel];
|
||||||
|
|
||||||
|
|
||||||
|
[self.bottomContainerView addSubview:self.buttonContainerView];
|
||||||
|
[self.buttonContainerView addSubview:self.shareButton];
|
||||||
|
[self.buttonContainerView addSubview:self.episcodeButton];
|
||||||
|
[self.buttonContainerView addSubview:self.favoriteButton];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[self addSubview:self.slider];
|
||||||
|
[self addSubview:self.danmuButton];
|
||||||
|
[self addSubview:self.fullscreenButton];
|
||||||
|
[self addSubview:self.resumeButton];
|
||||||
|
|
||||||
|
[self.bottomContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.right.equalTo(self);
|
||||||
|
make.bottom.equalTo(self.mas_safeAreaLayoutGuideBottom);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.slider mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.equalTo(self).offset(16.0);
|
||||||
|
make.right.equalTo(self).offset(-16.0);
|
||||||
|
make.bottom.equalTo(self.mas_safeAreaLayoutGuideBottom);
|
||||||
|
make.height.mas_equalTo(20.0);
|
||||||
|
}];
|
||||||
|
|
||||||
|
|
||||||
|
[self.contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.right.equalTo(self.slider);
|
||||||
|
make.bottom.equalTo(self.slider.mas_top).offset(-10.0);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.buttonContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.top.equalTo(self.bottomContainerView);
|
||||||
|
make.right.equalTo(self.contentLabel);
|
||||||
|
make.bottom.equalTo(self.contentLabel.mas_top).offset(-30.0);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.episcodeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.equalTo(self.contentLabel);
|
||||||
|
make.bottom.equalTo(self.contentLabel.mas_top).offset(-12.0);
|
||||||
|
make.right.equalTo(self.buttonContainerView.mas_left).offset(-8.0);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.right.equalTo(self.episcodeLabel);
|
||||||
|
make.bottom.equalTo(self.episcodeLabel.mas_top).offset(-8.0);
|
||||||
|
}];
|
||||||
|
|
||||||
|
|
||||||
|
[self.shareButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.bottom.left.right.equalTo(self.buttonContainerView);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.episcodeButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.right.equalTo(self.buttonContainerView);
|
||||||
|
make.bottom.equalTo(self.shareButton.mas_top).offset(-26.0);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.favoriteButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.top.right.equalTo(self.buttonContainerView);
|
||||||
|
make.bottom.equalTo(self.episcodeButton.mas_top).offset(-26.0);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.danmuButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.right.equalTo(self.bottomContainerView);
|
||||||
|
make.right.equalTo(self.mas_centerX).offset(-40);
|
||||||
|
make.width.height.mas_equalTo(30);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.fullscreenButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.centerY.equalTo(self.danmuButton);
|
||||||
|
make.left.equalTo(self.danmuButton.mas_right).offset(20);
|
||||||
|
make.width.mas_equalTo(80);
|
||||||
|
make.height.mas_equalTo(30);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.resumeButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.center.equalTo(self);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - ZFPlayerMediaControl
|
||||||
|
- (void)gestureSingleTapped:(ZFPlayerGestureControl *)gestureControl {
|
||||||
|
CGFloat diff = [NSDate date].timeIntervalSince1970 - self.lastDoubleTapTime.timeIntervalSince1970;
|
||||||
|
if (diff < 0.6) {
|
||||||
|
[self handleDoubleTapped:gestureControl.singleTap];
|
||||||
|
self.lastDoubleTapTime = [NSDate date];
|
||||||
|
}else {
|
||||||
|
[self handleSingleTapped];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)gestureDoubleTapped:(ZFPlayerGestureControl *)gestureControl {
|
||||||
|
[self handleDoubleTapped:gestureControl.doubleTap];
|
||||||
|
self.lastDoubleTapTime = [NSDate date];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handleSingleTapped {
|
||||||
|
id<ZFPlayerMediaPlayback> manager = self.player.currentPlayerManager;
|
||||||
|
if (manager.isPlaying) {
|
||||||
|
|
||||||
|
[manager pause];
|
||||||
|
[self.slider showLargeSlider];
|
||||||
|
self.resumeButton.hidden = NO;
|
||||||
|
self.resumeButton.transform = CGAffineTransformMakeScale(3, 3);
|
||||||
|
[UIView animateWithDuration:0.15 animations:^{
|
||||||
|
self.resumeButton.alpha = 1;
|
||||||
|
self.resumeButton.transform = CGAffineTransformIdentity;
|
||||||
|
}];
|
||||||
|
}else {
|
||||||
|
[manager play];
|
||||||
|
[self.slider showSmallSlider];
|
||||||
|
[UIView animateWithDuration:0.15 animations:^{
|
||||||
|
self.resumeButton.alpha = 0;
|
||||||
|
} completion:^(BOOL finished) {
|
||||||
|
self.resumeButton.hidden = YES;
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handleDoubleTapped:(UITapGestureRecognizer *)gesture {
|
||||||
|
CGPoint point = [gesture locationInView:gesture.view];
|
||||||
|
[self.doubleLikeView createAnimationWithPoint:point view:gesture.view completion:nil];
|
||||||
|
[self.favoriteButton startAnimationWithIsLike:YES];
|
||||||
|
self.model.is_collect = YES;
|
||||||
|
if ([self.delegate respondsToSelector:@selector(videoPortraitView:didClickFavorite:)]) {
|
||||||
|
[self.delegate videoPortraitView:self didClickFavorite:self.model];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setModel:(GKDYVideoModel *)model {
|
||||||
|
_model = model;
|
||||||
|
|
||||||
|
self.titleLabel.text = model.title;
|
||||||
|
|
||||||
|
self.contentLabel.text = model.detailText;
|
||||||
|
|
||||||
|
self.episcodeLabel.text = [NSString stringWithFormat:[@"player_text_episcode" language],model.videoInfo.episode,model.episode];
|
||||||
|
|
||||||
|
[self.favoriteButton setupLikeCount:[NSString stringWithFormat:@"%ld", model.collect_total]];
|
||||||
|
[self.favoriteButton setupLikeState:model.is_collect];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Action
|
||||||
|
|
||||||
|
|
||||||
|
- (void)favoriteAction {
|
||||||
|
self.model.is_collect = !self.model.is_collect;
|
||||||
|
if ([self.delegate respondsToSelector:@selector(videoPortraitView:didClickFavorite:)]) {
|
||||||
|
[self.delegate videoPortraitView:self didClickFavorite:self.model];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)episcodeAction {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(videoPortraitView:didClickEpiscode:)]) {
|
||||||
|
[self.delegate videoPortraitView:self didClickEpiscode:self.model];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)shareAction {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(videoPortraitView:didClickShare:)]) {
|
||||||
|
[self.delegate videoPortraitView:self didClickShare:self.model];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)danmuAction {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(videoPortraitView:didClickDanmu:)]) {
|
||||||
|
[self.delegate videoPortraitView:self didClickDanmu:self.model];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)fullscreenAction {
|
||||||
|
if ([self.delegate respondsToSelector:@selector(videoPortraitView:didClickFullscreen:)]) {
|
||||||
|
[self.delegate videoPortraitView:self didClickFullscreen:self.model];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)sliderDragging:(BOOL)isDragging {
|
||||||
|
self.bottomContainerView.alpha = !isDragging;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)willBeginDragging {
|
||||||
|
self.bottomContainerView.alpha = 0.4;
|
||||||
|
self.danmuButton.alpha = 0.4;
|
||||||
|
self.fullscreenButton.alpha = 0.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)didEndDragging {
|
||||||
|
self.bottomContainerView.alpha = 1;
|
||||||
|
self.danmuButton.alpha = 1;
|
||||||
|
self.fullscreenButton.alpha = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Lazy
|
||||||
|
- (UIView *)bottomContainerView {
|
||||||
|
if (!_bottomContainerView) {
|
||||||
|
_bottomContainerView = [[UIView alloc] init];
|
||||||
|
}
|
||||||
|
return _bottomContainerView;
|
||||||
|
}
|
||||||
|
- (UIView *)buttonContainerView{
|
||||||
|
if (!_buttonContainerView) {
|
||||||
|
_buttonContainerView = [[UIView alloc] init];
|
||||||
|
}
|
||||||
|
return _buttonContainerView ;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)titleLabel {
|
||||||
|
if (!_titleLabel) {
|
||||||
|
_titleLabel = [[UILabel alloc] init];
|
||||||
|
_titleLabel.font = [UIFont boldSystemFontOfSize:16];
|
||||||
|
_titleLabel.textColor = UIColor.whiteColor;
|
||||||
|
_titleLabel.userInteractionEnabled = YES;
|
||||||
|
}
|
||||||
|
return _titleLabel;
|
||||||
|
}
|
||||||
|
- (UILabel *)episcodeLabel {
|
||||||
|
if (!_episcodeLabel) {
|
||||||
|
_episcodeLabel = [[UILabel alloc] init];
|
||||||
|
_episcodeLabel.font = [UIFont systemFontOfSize:12.0 weight:UIFontWeightMedium];
|
||||||
|
_episcodeLabel.textColor = UIColor.whiteColor;
|
||||||
|
_episcodeLabel.text = @"Episode 1 Complete set : 999";
|
||||||
|
}
|
||||||
|
return _episcodeLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)contentLabel {
|
||||||
|
if (!_contentLabel) {
|
||||||
|
_contentLabel = [[UILabel alloc] init];
|
||||||
|
_contentLabel.font = [UIFont systemFontOfSize:12.0 weight:UIFontWeightLight];
|
||||||
|
_contentLabel.textColor = UIColor.whiteColor;
|
||||||
|
_contentLabel.numberOfLines = 4;
|
||||||
|
}
|
||||||
|
return _contentLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKDYVideoSlider *)slider {
|
||||||
|
if (!_slider) {
|
||||||
|
_slider = [[GKDYVideoSlider alloc] init];
|
||||||
|
|
||||||
|
@weakify(self);
|
||||||
|
_slider.slideBlock = ^(BOOL isDragging) {
|
||||||
|
@strongify(self);
|
||||||
|
[self sliderDragging:isDragging];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return _slider;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKLikeView *)favoriteButton {
|
||||||
|
if (!_favoriteButton) {
|
||||||
|
_favoriteButton = [[GKLikeView alloc] init];
|
||||||
|
@weakify(self);
|
||||||
|
_favoriteButton.likeBlock = ^{
|
||||||
|
@strongify(self);
|
||||||
|
[self favoriteAction];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return _favoriteButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (RSButton *)episcodeButton {
|
||||||
|
if (!_episcodeButton) {
|
||||||
|
_episcodeButton = [[RSButton alloc] initWithType:RSButtonTypeAbove];
|
||||||
|
_episcodeButton.margin = 4.0;
|
||||||
|
[_episcodeButton setTitleFont:[UIFont systemFontOfSize:12.0f weight:UIFontWeightRegular]];
|
||||||
|
[_episcodeButton setImage:[UIImage imageNamed:@"player_episode"] forState:UIControlStateNormal];
|
||||||
|
[_episcodeButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
|
||||||
|
[_episcodeButton setTitle:[@"player_text_series" language] forState:UIControlStateNormal];
|
||||||
|
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(episcodeAction)];
|
||||||
|
[_episcodeButton addGestureRecognizer:tapGesture];
|
||||||
|
}
|
||||||
|
return _episcodeButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIButton *)shareButton {
|
||||||
|
if (!_shareButton) {
|
||||||
|
_shareButton = [[UIButton alloc] init];
|
||||||
|
[_shareButton setImage:[UIImage imageNamed:@"player_shared"] forState:UIControlStateNormal];
|
||||||
|
[_shareButton addTarget:self action:@selector(shareAction) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
}
|
||||||
|
return _shareButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIButton *)danmuButton {
|
||||||
|
if (!_danmuButton) {
|
||||||
|
_danmuButton = [[UIButton alloc] init];
|
||||||
|
_danmuButton.hidden = YES;
|
||||||
|
[_danmuButton setTitle:@"弹" forState:UIControlStateNormal];
|
||||||
|
[_danmuButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
|
||||||
|
_danmuButton.titleLabel.font = [UIFont systemFontOfSize:15];
|
||||||
|
_danmuButton.layer.cornerRadius = 15;
|
||||||
|
_danmuButton.layer.masksToBounds = YES;
|
||||||
|
_danmuButton.layer.borderColor = UIColor.whiteColor.CGColor;
|
||||||
|
_danmuButton.layer.borderWidth = 0.5;
|
||||||
|
[_danmuButton addTarget:self action:@selector(danmuAction) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
}
|
||||||
|
return _danmuButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIButton *)fullscreenButton {
|
||||||
|
if (!_fullscreenButton) {
|
||||||
|
_fullscreenButton = [[UIButton alloc] init];
|
||||||
|
_fullscreenButton.hidden = YES;
|
||||||
|
[_fullscreenButton setTitle:@"全屏观看" forState:UIControlStateNormal];
|
||||||
|
[_fullscreenButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
|
||||||
|
_fullscreenButton.titleLabel.font = [UIFont systemFontOfSize:15];
|
||||||
|
_fullscreenButton.layer.cornerRadius = 15;
|
||||||
|
_fullscreenButton.layer.masksToBounds = YES;
|
||||||
|
_fullscreenButton.layer.borderColor = UIColor.whiteColor.CGColor;
|
||||||
|
_fullscreenButton.layer.borderWidth = 0.5;
|
||||||
|
[_fullscreenButton addTarget:self action:@selector(fullscreenAction) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
}
|
||||||
|
return _fullscreenButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIButton *)resumeButton {
|
||||||
|
if (!_resumeButton) {
|
||||||
|
_resumeButton = [[UIButton alloc] init];
|
||||||
|
[_resumeButton setImage:[UIImage imageNamed:@"player_play"] forState:UIControlStateNormal];
|
||||||
|
_resumeButton.hidden = YES;
|
||||||
|
}
|
||||||
|
return _resumeButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (GKDoubleLikeView *)doubleLikeView {
|
||||||
|
if (!_doubleLikeView) {
|
||||||
|
_doubleLikeView = [[GKDoubleLikeView alloc] init];
|
||||||
|
}
|
||||||
|
return _doubleLikeView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
22
HiBit/Project/Player/View/GKDYVideoPreviewView.h
Executable file
22
HiBit/Project/Player/View/GKDYVideoPreviewView.h
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoPreviewView.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/22.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <ZFPlayer/ZFPlayer.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GKDYVideoPreviewView : UIView
|
||||||
|
|
||||||
|
@property (nonatomic, weak) ZFPlayerController *player;
|
||||||
|
|
||||||
|
- (void)setPreviewValue:(float)value;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
108
HiBit/Project/Player/View/GKDYVideoPreviewView.m
Executable file
108
HiBit/Project/Player/View/GKDYVideoPreviewView.m
Executable file
@ -0,0 +1,108 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoPreviewView.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/22.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYVideoPreviewView.h"
|
||||||
|
|
||||||
|
#import <ZFPlayer/ZFAVPlayerManager.h>
|
||||||
|
|
||||||
|
@interface ZFAVPlayerManager (GKCategory)
|
||||||
|
|
||||||
|
- (void)thumbnailImageAtTime:(NSTimeInterval)time completion:(void(^)(UIImage *_Nullable image))completion;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ZFAVPlayerManager (GKCategory)
|
||||||
|
|
||||||
|
- (void)thumbnailImageAtTime:(NSTimeInterval)time completion:(void (^)(UIImage * _Nullable))completion {
|
||||||
|
CMTime expectedTime = CMTimeMakeWithSeconds(time, NSEC_PER_SEC);
|
||||||
|
|
||||||
|
AVAssetImageGenerator *imageGenerator = [self valueForKey:@"imageGenerator"];
|
||||||
|
|
||||||
|
[imageGenerator generateCGImagesAsynchronouslyForTimes:@[[NSValue valueWithCMTime:expectedTime]] completionHandler:^(CMTime requestedTime, CGImageRef _Nullable image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError * _Nullable error) {
|
||||||
|
if (image) {
|
||||||
|
UIImage *finalImage = [UIImage imageWithCGImage:image];
|
||||||
|
!completion ?: completion(finalImage);
|
||||||
|
}else {
|
||||||
|
!completion ?: completion(nil);
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface GKDYVideoPreviewView()
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIImageView *imageView;
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UILabel *timeLabel;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKDYVideoPreviewView
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
if (self = [super init]) {
|
||||||
|
[self initUI];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)initUI {
|
||||||
|
[self addSubview:self.imageView];
|
||||||
|
[self addSubview:self.timeLabel];
|
||||||
|
|
||||||
|
[self.imageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.top.right.equalTo(self);
|
||||||
|
make.height.mas_equalTo(120*9/16);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.top.equalTo(self.imageView.mas_bottom).offset(20);
|
||||||
|
make.centerX.equalTo(self);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setPreviewValue:(float)value {
|
||||||
|
NSString *currentTime = [NSString convertTimeSecond:self.player.totalTime * value];
|
||||||
|
NSString *totalTime = [NSString convertTimeSecond:self.player.totalTime];
|
||||||
|
self.timeLabel.text = [NSString stringWithFormat:@"%@ / %@", currentTime, totalTime];
|
||||||
|
|
||||||
|
ZFAVPlayerManager *manager = (ZFAVPlayerManager *)self.player.currentPlayerManager;
|
||||||
|
|
||||||
|
@weakify(self);
|
||||||
|
[manager thumbnailImageAtTime:self.player.totalTime * value completion:^(UIImage * _Nullable image) {
|
||||||
|
if (image) {
|
||||||
|
@strongify(self);
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
self.imageView.image = image;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Lazy
|
||||||
|
- (UIImageView *)imageView {
|
||||||
|
if (!_imageView) {
|
||||||
|
_imageView = [[UIImageView alloc] init];
|
||||||
|
_imageView.contentMode = UIViewContentModeScaleAspectFill;
|
||||||
|
_imageView.layer.cornerRadius = 5;
|
||||||
|
_imageView.layer.masksToBounds = YES;
|
||||||
|
}
|
||||||
|
return _imageView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)timeLabel {
|
||||||
|
if (!_timeLabel) {
|
||||||
|
_timeLabel = [[UILabel alloc] init];
|
||||||
|
_timeLabel.font = [UIFont systemFontOfSize:15];
|
||||||
|
_timeLabel.textColor = UIColor.whiteColor;
|
||||||
|
}
|
||||||
|
return _timeLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
31
HiBit/Project/Player/View/GKDYVideoScrollView.h
Executable file
31
HiBit/Project/Player/View/GKDYVideoScrollView.h
Executable file
@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoScrollView.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/17.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <GKVideoScrollView/GKVideoScrollView.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@class GKDYVideoScrollView;
|
||||||
|
|
||||||
|
@protocol GKDYVideoScrollViewDelegate <NSObject, GKVideoScrollViewDelegate>
|
||||||
|
|
||||||
|
@optional
|
||||||
|
|
||||||
|
- (void)scrollView:(GKDYVideoScrollView *)scrollView didPanWithDistance:(CGFloat)distance isEnd:(BOOL)isEnd;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface GKDYVideoScrollView : GKVideoScrollView
|
||||||
|
|
||||||
|
@property (nonatomic, weak) id<GKDYVideoScrollViewDelegate> delegate;
|
||||||
|
|
||||||
|
- (void)addPanGesture;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
126
HiBit/Project/Player/View/GKDYVideoScrollView.m
Executable file
126
HiBit/Project/Player/View/GKDYVideoScrollView.m
Executable file
@ -0,0 +1,126 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoScrollView.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/17.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYVideoScrollView.h"
|
||||||
|
#import "GKDYPanGestureRecognizer.h"
|
||||||
|
|
||||||
|
@interface GKDYVideoScrollView()<UIGestureRecognizerDelegate, UIScrollViewDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic, strong) GKDYPanGestureRecognizer *panGesture;
|
||||||
|
|
||||||
|
// 开始移动时的位置
|
||||||
|
@property (nonatomic, assign) CGFloat startLocationY;
|
||||||
|
|
||||||
|
@property (nonatomic, weak) id<GKDYVideoScrollViewDelegate> userDelegate;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKDYVideoScrollView
|
||||||
|
|
||||||
|
@dynamic delegate;
|
||||||
|
|
||||||
|
- (instancetype)initWithFrame:(CGRect)frame {
|
||||||
|
if (self = [super initWithFrame:frame]) {
|
||||||
|
if (CGRectEqualToRect(frame, CGRectZero)) {
|
||||||
|
self.frame = CGRectMake(0, 0, HBScreenSize.width, HBScreenSize.height);
|
||||||
|
}
|
||||||
|
self.contentSize = CGSizeMake(0, self.frame.size.height);
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)layoutSubviews {
|
||||||
|
[super layoutSubviews];
|
||||||
|
|
||||||
|
if (self.contentSize.height == 0) {
|
||||||
|
self.contentSize = CGSizeMake(self.bounds.size.width, self.bounds.size.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)addPanGesture {
|
||||||
|
[self addGestureRecognizer:self.panGesture];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setDelegate:(id<GKDYVideoScrollViewDelegate>)delegate {
|
||||||
|
[super setDelegate:delegate];
|
||||||
|
|
||||||
|
if (delegate) {
|
||||||
|
self.userDelegate = delegate;
|
||||||
|
}else {
|
||||||
|
self.userDelegate = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Gesture
|
||||||
|
- (void)handlePanGesture:(GKDYPanGestureRecognizer *)panGesture {
|
||||||
|
if (self.currentIndex == 0) {
|
||||||
|
CGPoint location = [panGesture locationInView:panGesture.view];
|
||||||
|
|
||||||
|
switch (panGesture.state) {
|
||||||
|
case UIGestureRecognizerStateBegan: {
|
||||||
|
self.startLocationY = location.y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UIGestureRecognizerStateChanged: {
|
||||||
|
if (panGesture.direction == GKDYPanGestureRecognizerDirectionVertical) {
|
||||||
|
// 这里取整是解决上滑时可能出现的distance > 0的情况
|
||||||
|
CGFloat distance = ceil(location.y) - ceil(self.startLocationY);
|
||||||
|
if (distance > 0) { // 只要distance>0且没松手 就认为是下滑
|
||||||
|
self.panGestureRecognizer.enabled = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.panGestureRecognizer.enabled == NO) {
|
||||||
|
[self didPanWithDistance:distance isEnd:NO];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UIGestureRecognizerStateFailed:
|
||||||
|
case UIGestureRecognizerStateCancelled:
|
||||||
|
case UIGestureRecognizerStateEnded: {
|
||||||
|
if (self.panGestureRecognizer.enabled == NO) {
|
||||||
|
CGFloat distance = location.y - self.startLocationY;
|
||||||
|
[self didPanWithDistance:distance isEnd:YES];
|
||||||
|
self.panGestureRecognizer.enabled = YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[panGesture setTranslation:CGPointZero inView:panGesture.view];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 允许多个手势响应
|
||||||
|
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
|
||||||
|
if (otherGestureRecognizer.view == self) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)didPanWithDistance:(CGFloat)distance isEnd:(BOOL)isEnd {
|
||||||
|
if ([self.userDelegate respondsToSelector:@selector(scrollView:didPanWithDistance:isEnd:)]) {
|
||||||
|
[self.userDelegate scrollView:self didPanWithDistance:distance isEnd:isEnd];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Lazy
|
||||||
|
- (GKDYPanGestureRecognizer *)panGesture {
|
||||||
|
if (!_panGesture) {
|
||||||
|
_panGesture = [[GKDYPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)];
|
||||||
|
_panGesture.delegate = self;
|
||||||
|
_panGesture.direction = GKDYPanGestureRecognizerDirectionVertical;
|
||||||
|
}
|
||||||
|
return _panGesture;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
33
HiBit/Project/Player/View/GKDYVideoSlider.h
Executable file
33
HiBit/Project/Player/View/GKDYVideoSlider.h
Executable file
@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoSlider.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/22.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <GKSliderView/GKSliderView.h>
|
||||||
|
#import <ZFPlayer/ZFPlayer.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GKDYVideoSlider : UIView
|
||||||
|
|
||||||
|
@property (nonatomic, strong) GKSliderView *sliderView;
|
||||||
|
|
||||||
|
@property (nonatomic, copy) void(^slideBlock)(BOOL isDragging);
|
||||||
|
|
||||||
|
@property (nonatomic, weak) ZFPlayerController *player;
|
||||||
|
|
||||||
|
- (void)updateCurrentTime:(NSTimeInterval)currentTime totalTime:(NSTimeInterval)totalTime;
|
||||||
|
|
||||||
|
- (void)showSmallSlider;
|
||||||
|
- (void)showLargeSlider;
|
||||||
|
|
||||||
|
- (void)showLoading;
|
||||||
|
- (void)hideLoading;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
212
HiBit/Project/Player/View/GKDYVideoSlider.m
Executable file
212
HiBit/Project/Player/View/GKDYVideoSlider.m
Executable file
@ -0,0 +1,212 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoSlider.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/22.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYVideoSlider.h"
|
||||||
|
#import <Masonry/Masonry.h>
|
||||||
|
|
||||||
|
@interface GKDYVideoSlider()<GKSliderViewPreviewDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic, assign) CGFloat startLocationX;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) float startValue;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL isDragging;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL isSeeking;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) NSTimeInterval currentTime;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) NSTimeInterval totalTime;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKDYVideoSlider
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
if (self = [super init]) {
|
||||||
|
[self initUI];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)initUI {
|
||||||
|
[self addSubview:self.sliderView];
|
||||||
|
[self.sliderView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.right.bottom.equalTo(self);
|
||||||
|
make.height.mas_offset(4);
|
||||||
|
}];
|
||||||
|
|
||||||
|
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
|
||||||
|
[self addGestureRecognizer:panGesture];
|
||||||
|
|
||||||
|
[self showSmallSlider];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)updateCurrentTime:(NSTimeInterval)currentTime totalTime:(NSTimeInterval)totalTime {
|
||||||
|
self.currentTime = currentTime;
|
||||||
|
self.totalTime = totalTime;
|
||||||
|
if (self.isDragging) return;
|
||||||
|
if (self.isSeeking) return;
|
||||||
|
CGFloat value = totalTime == 0 ? 0 : currentTime / totalTime;
|
||||||
|
self.sliderView.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)showLoading {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[self.sliderView showLineLoading];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)hideLoading {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[self.sliderView hideLineLoading];
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handlePan:(UIPanGestureRecognizer *)gesture {
|
||||||
|
CGPoint location = [gesture locationInView:gesture.view];
|
||||||
|
switch (gesture.state) {
|
||||||
|
case UIGestureRecognizerStateBegan: {
|
||||||
|
self.startLocationX = location.x;
|
||||||
|
self.startValue = self.sliderView.value;
|
||||||
|
if (self.sliderView.preview) {
|
||||||
|
self.sliderView.preview.hidden = NO;
|
||||||
|
}
|
||||||
|
self.isDragging = YES;
|
||||||
|
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showSmallSlider) object:nil];
|
||||||
|
[self showLargeSlider];
|
||||||
|
!self.slideBlock ?: self.slideBlock(self.isDragging);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UIGestureRecognizerStateChanged: {
|
||||||
|
CGFloat diff = location.x - self.startLocationX;
|
||||||
|
CGFloat progress = self.startValue + diff / gesture.view.frame.size.width;
|
||||||
|
if (progress < 0) progress = 0;
|
||||||
|
if (progress > 1) progress = 1;
|
||||||
|
self.sliderView.value = progress;
|
||||||
|
if (self.sliderView.preview && [self.sliderView.previewDelegate respondsToSelector:@selector(sliderView:preview:valueChanged:)]) {
|
||||||
|
[self.sliderView.previewDelegate sliderView:self.sliderView preview:self.sliderView.preview valueChanged:self.sliderView.value];
|
||||||
|
}
|
||||||
|
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showSmallSlider) object:nil];
|
||||||
|
[self showDragSlider];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UIGestureRecognizerStateFailed:
|
||||||
|
case UIGestureRecognizerStateCancelled:
|
||||||
|
case UIGestureRecognizerStateEnded: {
|
||||||
|
self.isDragging = NO;
|
||||||
|
if (self.sliderView.preview) {
|
||||||
|
self.sliderView.preview.hidden = YES;
|
||||||
|
}
|
||||||
|
[self showLargeSlider];
|
||||||
|
[self performSelector:@selector(showSmallSlider) withObject:nil afterDelay:3.0f];
|
||||||
|
!self.slideBlock ?: self.slideBlock(self.isDragging);
|
||||||
|
[self seekTo:self.sliderView.value];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)seekTo:(float)value {
|
||||||
|
NSTimeInterval time = self.totalTime * value;
|
||||||
|
|
||||||
|
NSLog(@"seekTo: %f",time);
|
||||||
|
|
||||||
|
self.isSeeking = YES;
|
||||||
|
@weakify(self);
|
||||||
|
[self.player seekToTime:time completionHandler:^(BOOL finished) {
|
||||||
|
@strongify(self);
|
||||||
|
weak_self.isSeeking = NO;
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Slider
|
||||||
|
- (void)showSmallSlider {
|
||||||
|
CGRect frame = self.sliderView.sliderBtn.frame;
|
||||||
|
frame.size = CGSizeMake(4, 4);
|
||||||
|
self.sliderView.sliderBtn.frame = frame;
|
||||||
|
self.sliderView.sliderBtn.layer.cornerRadius = 2;
|
||||||
|
self.sliderView.sliderHeight = 1;
|
||||||
|
[self.sliderView mas_updateConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.height.mas_equalTo(4);
|
||||||
|
}];
|
||||||
|
self.sliderView.bgCornerRadius = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)showLargeSlider {
|
||||||
|
CGRect frame = self.sliderView.sliderBtn.frame;
|
||||||
|
frame.size = CGSizeMake(8, 8);
|
||||||
|
self.sliderView.sliderBtn.frame = frame;
|
||||||
|
self.sliderView.sliderBtn.layer.cornerRadius = 4;
|
||||||
|
self.sliderView.sliderHeight = 2;
|
||||||
|
[self.sliderView mas_updateConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.height.mas_equalTo(8);
|
||||||
|
}];
|
||||||
|
self.sliderView.bgCornerRadius = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)showDragSlider {
|
||||||
|
CGRect frame = self.sliderView.sliderBtn.frame;
|
||||||
|
frame.size = CGSizeMake(8, 16);
|
||||||
|
self.sliderView.sliderBtn.frame = frame;
|
||||||
|
self.sliderView.sliderBtn.layer.cornerRadius = 4;
|
||||||
|
self.sliderView.sliderHeight = 10;
|
||||||
|
[self.sliderView mas_updateConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.height.mas_equalTo(16);
|
||||||
|
}];
|
||||||
|
self.sliderView.bgCornerRadius = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - GKSliderViewPreviewDelegate
|
||||||
|
- (UIView *)sliderViewSetupPreview:(GKSliderView *)sliderView {
|
||||||
|
GKSliderButton *preview = [[GKSliderButton alloc] init];
|
||||||
|
NSString *currentTime = [NSString convertTimeSecond:self.currentTime];
|
||||||
|
NSString *totalTime = [NSString convertTimeSecond:self.totalTime];
|
||||||
|
[preview setTitle:[NSString stringWithFormat:@"%@ / %@", currentTime, totalTime] forState:UIControlStateNormal];
|
||||||
|
[preview setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
|
||||||
|
preview.titleLabel.font = [UIFont systemFontOfSize:15];
|
||||||
|
[preview sizeToFit];
|
||||||
|
CGRect frame = preview.frame;
|
||||||
|
frame.size.width += 10;
|
||||||
|
preview.frame = frame;
|
||||||
|
return preview;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGFloat)sliderViewPreviewMargin:(GKSliderView *)sliderView {
|
||||||
|
return 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)sliderView:(GKSliderView *)sliderView preview:(UIView *)preview valueChanged:(float)value {
|
||||||
|
GKSliderButton *button = (GKSliderButton *)preview;
|
||||||
|
NSString *currentTime = [NSString convertTimeSecond:self.totalTime * value];
|
||||||
|
NSString *totalTime = [NSString convertTimeSecond:self.totalTime];
|
||||||
|
[button setTitle:[NSString stringWithFormat:@"%@ / %@", currentTime, totalTime] forState:UIControlStateNormal];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Lazy
|
||||||
|
- (GKSliderView *)sliderView {
|
||||||
|
if (!_sliderView) {
|
||||||
|
_sliderView = [[GKSliderView alloc] init];
|
||||||
|
_sliderView.isSliderAllowTapped = NO;
|
||||||
|
_sliderView.sliderHeight = 2;
|
||||||
|
_sliderView.maximumTrackTintColor = [UIColor lightGrayColor];
|
||||||
|
_sliderView.minimumTrackTintColor = HBColor.color_FF0049;
|
||||||
|
_sliderView.sliderBtn.layer.masksToBounds = YES;
|
||||||
|
_sliderView.sliderBtn.backgroundColor = HBColor.color_FF0049;
|
||||||
|
_sliderView.isPreviewChangePosition = NO;
|
||||||
|
_sliderView.userInteractionEnabled = NO;
|
||||||
|
_sliderView.previewDelegate = self;
|
||||||
|
}
|
||||||
|
return _sliderView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
27
HiBit/Project/Player/View/GKDYVideoStatusBar.h
Executable file
27
HiBit/Project/Player/View/GKDYVideoStatusBar.h
Executable file
@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoStatusBar.h
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/22.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface GKDYVideoStatusBar : UIView
|
||||||
|
|
||||||
|
// 刷新时间,默认3s
|
||||||
|
@property (nonatomic, assign) NSTimeInterval refreshTime;
|
||||||
|
|
||||||
|
// 网络状态
|
||||||
|
@property (nonatomic, copy) NSString *network;
|
||||||
|
|
||||||
|
- (void)startTimer;
|
||||||
|
|
||||||
|
- (void)destoryTimer;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
345
HiBit/Project/Player/View/GKDYVideoStatusBar.m
Executable file
345
HiBit/Project/Player/View/GKDYVideoStatusBar.m
Executable file
@ -0,0 +1,345 @@
|
|||||||
|
//
|
||||||
|
// GKDYVideoStatusBar.m
|
||||||
|
// GKDYVideo
|
||||||
|
//
|
||||||
|
// Created by QuintGao on 2023/3/22.
|
||||||
|
// Copyright © 2023 QuintGao. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GKDYVideoStatusBar.h"
|
||||||
|
|
||||||
|
#define UIColorFromHex(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
|
||||||
|
|
||||||
|
@interface GKDYVideoTimerTarget : NSProxy
|
||||||
|
|
||||||
|
@property (nonatomic, weak) id target;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKDYVideoTimerTarget
|
||||||
|
|
||||||
|
+ (instancetype)proxyWithTarget:(id)target {
|
||||||
|
GKDYVideoTimerTarget *proxy = [GKDYVideoTimerTarget alloc];
|
||||||
|
proxy.target = target;
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
|
||||||
|
NSMethodSignature *signature = nil;
|
||||||
|
if ([self.target respondsToSelector:sel]) {
|
||||||
|
signature = [self.target methodSignatureForSelector:sel];
|
||||||
|
}else {
|
||||||
|
/// 动态造一个 void object selector arg 函数签名
|
||||||
|
/// 目的是返回有效signature,不要以为找不到而crash
|
||||||
|
signature = [NSMethodSignature signatureWithObjCTypes:"v@:@"];
|
||||||
|
}
|
||||||
|
return signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)forwardInvocation:(NSInvocation *)invocation {
|
||||||
|
if ([self.target respondsToSelector:invocation.selector]) {
|
||||||
|
[invocation invokeWithTarget:self.target];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface GKDYVideoStatusBar()
|
||||||
|
|
||||||
|
/// 时间
|
||||||
|
@property (nonatomic, strong) UILabel *dateLabel;
|
||||||
|
/// 电池
|
||||||
|
@property (nonatomic, strong) UIView *batteryView;
|
||||||
|
/// 充电标识
|
||||||
|
@property (nonatomic, strong) UIImageView *batteryImageView;
|
||||||
|
/// 充电层
|
||||||
|
@property (nonatomic, strong) CAShapeLayer *batteryLayer;
|
||||||
|
/// 电池边框
|
||||||
|
@property (nonatomic, strong) CAShapeLayer *batteryBoundLayer;
|
||||||
|
/// 电池正极
|
||||||
|
@property (nonatomic, strong) CAShapeLayer *batteryPositiveLayer;
|
||||||
|
/// 电量百分比
|
||||||
|
@property (nonatomic, strong) UILabel *batteryLabel;
|
||||||
|
|
||||||
|
/// 网络状态
|
||||||
|
@property (nonatomic, strong) UILabel *networkLabel;
|
||||||
|
@property (nonatomic, strong) NSTimer *timer;
|
||||||
|
@property (nonatomic, strong) NSDateFormatter *dateFormatter;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GKDYVideoStatusBar
|
||||||
|
|
||||||
|
- (instancetype)initWithFrame:(CGRect)frame {
|
||||||
|
if (self = [super initWithFrame:frame]) {
|
||||||
|
[self setup];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
[self destoryTimer];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setup {
|
||||||
|
self.refreshTime = 3.0f;
|
||||||
|
/// 时间
|
||||||
|
[self addSubview:self.dateLabel];
|
||||||
|
/// 电池
|
||||||
|
[self addSubview:self.batteryView];
|
||||||
|
[self.batteryView.layer addSublayer:self.batteryBoundLayer];
|
||||||
|
[self.batteryView.layer addSublayer:self.batteryPositiveLayer];
|
||||||
|
[self.batteryView.layer addSublayer:self.batteryLayer];
|
||||||
|
[self.batteryView addSubview:self.batteryImageView];
|
||||||
|
[self addSubview:self.batteryLabel];
|
||||||
|
[self addSubview:self.networkLabel];
|
||||||
|
|
||||||
|
[UIDevice currentDevice].batteryMonitoringEnabled = YES;
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryLevelDidChangeNotification:) name:UIDeviceBatteryLevelDidChangeNotification object:nil];
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryStateDidChangeNotification:) name:UIDeviceBatteryStateDidChangeNotification object:nil];
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(localeDidChangeNotification:) name:NSCurrentLocaleDidChangeNotification object:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)layoutSubviews {
|
||||||
|
[self.dateLabel sizeToFit];
|
||||||
|
[self.networkLabel sizeToFit];
|
||||||
|
[self.batteryLabel sizeToFit];
|
||||||
|
|
||||||
|
CGRect frame = self.dateLabel.frame;
|
||||||
|
CGPoint center = self.dateLabel.center;
|
||||||
|
|
||||||
|
// dateLabel
|
||||||
|
frame.size.height = 16;
|
||||||
|
self.dateLabel.frame = frame;
|
||||||
|
center = self.center;
|
||||||
|
self.dateLabel.center = center;
|
||||||
|
|
||||||
|
// batteryView
|
||||||
|
frame = self.batteryView.frame;
|
||||||
|
frame.origin.x = self.bounds.size.width - 35;
|
||||||
|
frame.size.width = 22;
|
||||||
|
frame.size.height = 10;
|
||||||
|
self.batteryView.frame = frame;
|
||||||
|
center = self.batteryView.center;
|
||||||
|
center.y = self.center.y;
|
||||||
|
self.batteryView.center = center;
|
||||||
|
|
||||||
|
// batteryLabel
|
||||||
|
frame = self.batteryLabel.frame;
|
||||||
|
frame.origin.x = CGRectGetMinX(self.batteryView.frame) - 5 - frame.size.width;
|
||||||
|
frame.size.height = 16;
|
||||||
|
self.batteryLabel.frame = frame;
|
||||||
|
center = self.batteryLabel.center;
|
||||||
|
center.y = self.batteryView.center.y;
|
||||||
|
self.batteryLabel.center = center;
|
||||||
|
|
||||||
|
// networkLabel
|
||||||
|
frame = self.networkLabel.frame;
|
||||||
|
frame.origin.x = 10;
|
||||||
|
frame.size.width = frame.size.width + 13;
|
||||||
|
frame.size.height = 14;
|
||||||
|
self.networkLabel.frame = frame;
|
||||||
|
center = self.networkLabel.center;
|
||||||
|
center.y = self.batteryView.center.y;
|
||||||
|
self.networkLabel.center = center;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)batteryLevelDidChangeNotification:(NSNotification *)noti {
|
||||||
|
[self updateUI];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)batteryStateDidChangeNotification:(NSNotification *)noti {
|
||||||
|
[self updateUI];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)localeDidChangeNotification:(NSNotification *)noti {
|
||||||
|
[self.dateFormatter setLocale:NSLocale.currentLocale];
|
||||||
|
[self updateUI];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setNetwork:(NSString *)network {
|
||||||
|
_network = network;
|
||||||
|
|
||||||
|
self.networkLabel.text = network;
|
||||||
|
[self setNeedsLayout];
|
||||||
|
[self layoutIfNeeded];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)startTimer {
|
||||||
|
if (self.timer) return;
|
||||||
|
self.timer = [NSTimer timerWithTimeInterval:self.refreshTime target:[GKDYVideoTimerTarget proxyWithTarget:self] selector:@selector(updateUI) userInfo:nil repeats:YES];
|
||||||
|
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
|
||||||
|
[self.timer fire];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)destoryTimer {
|
||||||
|
if (self.timer) {
|
||||||
|
[self.timer invalidate];
|
||||||
|
self.timer = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - update UI
|
||||||
|
- (void)updateUI {
|
||||||
|
[self updateDate];
|
||||||
|
[self updateBattery];
|
||||||
|
[self setNeedsLayout];
|
||||||
|
[self layoutIfNeeded];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)updateDate {
|
||||||
|
NSMutableString *dateString = [[NSMutableString alloc] initWithString:[self.dateFormatter stringFromDate:[NSDate date]]];
|
||||||
|
NSRange amRange = [dateString rangeOfString:[self.dateFormatter AMSymbol]];
|
||||||
|
NSRange pmRange = [dateString rangeOfString:[self.dateFormatter PMSymbol]];
|
||||||
|
if (amRange.location != NSNotFound) {
|
||||||
|
[dateString deleteCharactersInRange:amRange];
|
||||||
|
}else if (pmRange.location != NSNotFound) {
|
||||||
|
[dateString deleteCharactersInRange:pmRange];
|
||||||
|
}
|
||||||
|
self.dateLabel.text = dateString;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)updateBattery {
|
||||||
|
[UIDevice currentDevice].batteryMonitoringEnabled = YES;
|
||||||
|
CGFloat batteryLevel = [UIDevice currentDevice].batteryLevel;
|
||||||
|
/// -1是模拟器
|
||||||
|
if (batteryLevel < 0) { batteryLevel = 1.0; }
|
||||||
|
CGRect rect = CGRectMake(1.5, 1.5, (20-3)*batteryLevel, 10-3);
|
||||||
|
UIBezierPath *batteryPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:2];
|
||||||
|
|
||||||
|
UIColor *batteryColor;
|
||||||
|
UIDeviceBatteryState batteryState = [UIDevice currentDevice].batteryState;
|
||||||
|
if (batteryState == UIDeviceBatteryStateCharging || batteryState == UIDeviceBatteryStateFull) { /// 在充电
|
||||||
|
self.batteryImageView.hidden = NO;
|
||||||
|
} else {
|
||||||
|
self.batteryImageView.hidden = YES;
|
||||||
|
}
|
||||||
|
if (@available(iOS 9.0, *)) {
|
||||||
|
if ([NSProcessInfo processInfo].lowPowerModeEnabled) { /// 低电量模式
|
||||||
|
batteryColor = UIColorFromHex(0xF9CF0E);
|
||||||
|
} else {
|
||||||
|
if (batteryState == UIDeviceBatteryStateCharging || batteryState == UIDeviceBatteryStateFull) { /// 在充电
|
||||||
|
batteryColor = UIColorFromHex(0x37CB46);
|
||||||
|
} else if (batteryLevel <= 0.2) { /// 电量低
|
||||||
|
batteryColor = UIColorFromHex(0xF02C2D);
|
||||||
|
} else { /// 电量正常 白色
|
||||||
|
batteryColor = [UIColor whiteColor];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (batteryState == UIDeviceBatteryStateCharging || batteryState == UIDeviceBatteryStateFull) { /// 在充电
|
||||||
|
batteryColor = UIColorFromHex(0x37CB46);
|
||||||
|
} else if (batteryLevel <= 0.2) { /// 电量低
|
||||||
|
batteryColor = UIColorFromHex(0xF02C2D);
|
||||||
|
} else { /// 电量正常 白色
|
||||||
|
batteryColor = [UIColor whiteColor];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.batteryLayer.strokeColor = [UIColor clearColor].CGColor;
|
||||||
|
self.batteryLayer.path = batteryPath.CGPath;
|
||||||
|
self.batteryLayer.fillColor = batteryColor.CGColor;
|
||||||
|
self.batteryLabel.text = [NSString stringWithFormat:@"%.0f%%", batteryLevel*100];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - getter
|
||||||
|
- (UILabel *)dateLabel {
|
||||||
|
if (!_dateLabel) {
|
||||||
|
_dateLabel = [[UILabel alloc] init];
|
||||||
|
_dateLabel.bounds = CGRectMake(0, 0, 100, 16);
|
||||||
|
_dateLabel.textColor = UIColor.whiteColor;
|
||||||
|
_dateLabel.font = [UIFont systemFontOfSize:12];
|
||||||
|
}
|
||||||
|
return _dateLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDateFormatter *)dateFormatter {
|
||||||
|
if (!_dateFormatter) {
|
||||||
|
_dateFormatter = [[NSDateFormatter alloc] init];
|
||||||
|
[_dateFormatter setLocale:NSLocale.currentLocale];
|
||||||
|
_dateFormatter.dateStyle = NSDateFormatterNoStyle;
|
||||||
|
_dateFormatter.timeStyle = NSDateFormatterShortStyle;
|
||||||
|
}
|
||||||
|
return _dateFormatter;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIView *)batteryView {
|
||||||
|
if (!_batteryView) {
|
||||||
|
_batteryView = [[UIView alloc] init];
|
||||||
|
}
|
||||||
|
return _batteryView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIImageView *)batteryImageView {
|
||||||
|
if (!_batteryImageView) {
|
||||||
|
_batteryImageView = [[UIImageView alloc] init];
|
||||||
|
_batteryImageView.bounds = CGRectMake(0, 0, 8, 12);
|
||||||
|
_batteryImageView.center = CGPointMake(10, 5);
|
||||||
|
_batteryImageView.image = [UIImage imageNamed:@"icon_battery_lightning"];
|
||||||
|
}
|
||||||
|
return _batteryImageView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CAShapeLayer *)batteryLayer {
|
||||||
|
if (!_batteryLayer) {
|
||||||
|
[UIDevice currentDevice].batteryMonitoringEnabled = YES;
|
||||||
|
CGFloat batteryLevel = [UIDevice currentDevice].batteryLevel;
|
||||||
|
UIBezierPath *batteryPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(1.5, 1.5, (20-3)*batteryLevel, 10-3) cornerRadius:2];
|
||||||
|
_batteryLayer = [CAShapeLayer layer];
|
||||||
|
_batteryLayer.lineWidth = 1;
|
||||||
|
_batteryLayer.strokeColor = [UIColor clearColor].CGColor;
|
||||||
|
_batteryLayer.path = batteryPath.CGPath;
|
||||||
|
_batteryLayer.fillColor = [UIColor whiteColor].CGColor;
|
||||||
|
}
|
||||||
|
return _batteryLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CAShapeLayer *)batteryBoundLayer {
|
||||||
|
if (!_batteryBoundLayer) {
|
||||||
|
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 20, 10) cornerRadius:2.5];
|
||||||
|
_batteryBoundLayer = [CAShapeLayer layer];
|
||||||
|
_batteryBoundLayer.lineWidth = 1;
|
||||||
|
_batteryBoundLayer.strokeColor = [[UIColor whiteColor] colorWithAlphaComponent:0.8].CGColor;
|
||||||
|
_batteryBoundLayer.path = bezierPath.CGPath;
|
||||||
|
_batteryBoundLayer.fillColor = nil;
|
||||||
|
}
|
||||||
|
return _batteryBoundLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CAShapeLayer *)batteryPositiveLayer {
|
||||||
|
if (!_batteryPositiveLayer) {
|
||||||
|
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(22, 3, 1, 3) byRoundingCorners:(UIRectCornerTopRight|UIRectCornerBottomRight) cornerRadii:CGSizeMake(2, 2)];
|
||||||
|
_batteryPositiveLayer = [CAShapeLayer layer];
|
||||||
|
_batteryPositiveLayer.lineWidth = 0.5;
|
||||||
|
_batteryPositiveLayer.strokeColor = [[UIColor whiteColor] colorWithAlphaComponent:0.8].CGColor;
|
||||||
|
_batteryPositiveLayer.path = path.CGPath;
|
||||||
|
_batteryPositiveLayer.fillColor = [[UIColor whiteColor] colorWithAlphaComponent:0.8].CGColor;
|
||||||
|
}
|
||||||
|
return _batteryPositiveLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)batteryLabel {
|
||||||
|
if (!_batteryLabel) {
|
||||||
|
_batteryLabel = [[UILabel alloc] init];
|
||||||
|
_batteryLabel.textColor = [UIColor whiteColor];
|
||||||
|
_batteryLabel.font = [UIFont systemFontOfSize:11];
|
||||||
|
_batteryLabel.textAlignment = NSTextAlignmentRight;
|
||||||
|
}
|
||||||
|
return _batteryLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UILabel *)networkLabel {
|
||||||
|
if (!_networkLabel) {
|
||||||
|
_networkLabel = [[UILabel alloc] init];
|
||||||
|
_networkLabel.layer.cornerRadius = 7;
|
||||||
|
_networkLabel.layer.borderWidth = 1;
|
||||||
|
_networkLabel.layer.borderColor = [UIColor lightGrayColor].CGColor;
|
||||||
|
_networkLabel.textColor = [UIColor whiteColor];
|
||||||
|
_networkLabel.font = [UIFont systemFontOfSize:9];
|
||||||
|
_networkLabel.textAlignment = NSTextAlignmentCenter;
|
||||||
|
_networkLabel.text = @"WIFI";
|
||||||
|
}
|
||||||
|
return _networkLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
@ -8,32 +8,32 @@
|
|||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
/// 网络请求地址
|
/// 网络请求地址
|
||||||
extern NSString *const HBBaseUrlString;
|
extern NSString * _Nonnull const HBBaseUrlString;
|
||||||
|
|
||||||
/// 保存设备唯一值key
|
/// 保存设备唯一值key
|
||||||
extern NSString *const HBIdentifierForVendorKey;
|
extern NSString * _Nonnull const HBIdentifierForVendorKey;
|
||||||
|
|
||||||
/// 用来保存用户是不是主动登录成功了,可以用来判断是否登录
|
/// 用来保存用户是不是主动登录成功了,可以用来判断是否登录
|
||||||
extern NSString *const HBCustomerLoginSuccessKey;
|
extern NSString * _Nonnull const HBCustomerLoginSuccessKey;
|
||||||
|
|
||||||
/// 保存网络请求的Token
|
/// 保存网络请求的Token
|
||||||
extern NSString *const HBNetWorkingTokenKey;
|
extern NSString * _Nonnull const HBNetWorkingTokenKey;
|
||||||
|
|
||||||
/// 保存网络请求的Token
|
/// 保存网络请求的Token
|
||||||
extern NSString *const HBCustomerIdKey;
|
extern NSString * _Nonnull const HBCustomerIdKey;
|
||||||
|
|
||||||
/// 搜索历史key
|
/// 搜索历史key
|
||||||
extern NSString *const HBSearchHistoryKey;
|
extern NSString * _Nonnull const HBSearchHistoryKey;
|
||||||
|
|
||||||
/// 播放界面离开 通知播放器暂停
|
/// 播放界面离开 通知播放器暂停
|
||||||
extern NSString *const HBPlayerPuaseKey;
|
extern NSString * _Nonnull const HBPlayerPuaseKey;
|
||||||
|
|
||||||
/// 推送详情使用
|
/// 推送详情使用
|
||||||
extern NSString *const HBNotificationOpenActionIdentifier;
|
extern NSString * _Nonnull const HBNotificationOpenActionIdentifier;
|
||||||
extern NSString *const HBNotificationOpenCategoryIdentifier;
|
extern NSString * _Nonnull const HBNotificationOpenCategoryIdentifier;
|
||||||
|
|
||||||
/// 第一次启动存储
|
/// 第一次启动存储
|
||||||
extern NSString *const HBNotFirstStartKey;
|
extern NSString * _Nonnull const HBNotFirstStartKey;
|
||||||
|
|
||||||
/// 通知
|
/// 通知
|
||||||
FOUNDATION_EXPORT NSNotificationName _Nonnull const HBUpdateUserInfoNotification;
|
FOUNDATION_EXPORT NSNotificationName _Nonnull const HBUpdateUserInfoNotification;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#import "HBCommonKeys.h"
|
#import "HBCommonKeys.h"
|
||||||
|
|
||||||
/// 网络请求地址
|
/// 网络请求地址
|
||||||
NSString *const HBBaseUrlString = @"https://hongkongapi.peonytv.com";
|
NSString *const HBBaseUrlString = @"https://test-api.peonytv.com";
|
||||||
|
|
||||||
NSString *const HBIdentifierForVendorKey = @"HBIdentifierForVendorKey";
|
NSString *const HBIdentifierForVendorKey = @"HBIdentifierForVendorKey";
|
||||||
|
|
||||||
|
@ -8,13 +8,13 @@
|
|||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
/// appsflyer dev key
|
/// appsflyer dev key
|
||||||
extern NSString *const HBAppsFlyerDevKey;
|
extern NSString * _Nonnull const HBAppsFlyerDevKey;
|
||||||
|
|
||||||
/// appsflyer app id
|
/// appsflyer app id
|
||||||
extern NSString *const HBAppsFlyerAppID;
|
extern NSString * _Nonnull const HBAppsFlyerAppID;
|
||||||
|
|
||||||
/// applovin key
|
/// applovin key
|
||||||
extern NSString *const HBAppLovinKey;
|
extern NSString * _Nonnull const HBAppLovinKey;
|
||||||
|
|
||||||
/// Panlge app id
|
/// Panlge app id
|
||||||
extern NSString *const HBPangleID;
|
extern NSString * _Nonnull const HBPangleID;
|
||||||
|
@ -19,10 +19,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// 多语言 userdefine key
|
/// 多语言 userdefine key
|
||||||
extern NSString *const HBMultiLanguageKey;
|
extern NSString * _Nonnull const HBMultiLanguageKey;
|
||||||
|
|
||||||
/// 多语言 查询系统首选语言 key
|
/// 多语言 查询系统首选语言 key
|
||||||
extern NSString *const HBLocaleLanguageKey;
|
extern NSString * _Nonnull const HBLocaleLanguageKey;
|
||||||
|
|
||||||
/// 多语言发发现切换使用通知的key
|
/// 多语言发发现切换使用通知的key
|
||||||
FOUNDATION_EXPORT NSNotificationName _Nonnull const HBMultiLanguageChangeNotification;
|
FOUNDATION_EXPORT NSNotificationName _Nonnull const HBMultiLanguageChangeNotification;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user