From 699e1b8322baa063f93959007f58b6fc5c78c9d5 Mon Sep 17 00:00:00 2001 From: QuintGao <1094887059@qq.com> Date: Fri, 13 Sep 2024 17:03:33 +0800 Subject: [PATCH] =?UTF-8?q?demo=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GKDYVideo.xcodeproj/project.pbxproj | 46 +- .../Home/Comment/View/GKDYCommentView.h | 3 +- .../Home/Comment/View/GKDYCommentView.m | 28 +- .../Controller/GKDYListPlayerController.h | 35 ++ .../Controller/GKDYListPlayerController.m | 218 +++++++++ .../Controller/GKDYPlayerViewController.m | 45 +- .../Mine/Controller/GKDYUserViewController.m | 56 ++- .../Classes/Mine/View/GKDYScaleVideoView.m | 6 +- .../GKPopupController/GKPopupController.h | 32 -- .../GKPopupController/GKPopupController.m | 458 ------------------ .../Tools/GKPopupController/GKPopupProtocol.h | 75 --- .../GKScaleTransition/GKScaleAnimation.h | 26 + .../GKScaleTransition/GKScaleAnimation.m | 142 ++++++ .../GKScaleTransition/GKScaleTransition.h | 45 ++ .../GKScaleTransition/GKScaleTransition.m | 169 +++++++ .../Tools/GKSlidePopupView/GKSlidePopupView.h | 25 - .../Tools/GKSlidePopupView/GKSlidePopupView.m | 191 -------- Podfile | 1 + 18 files changed, 733 insertions(+), 868 deletions(-) create mode 100644 GKDYVideo/Classes/Home/Video/Controller/GKDYListPlayerController.h create mode 100644 GKDYVideo/Classes/Home/Video/Controller/GKDYListPlayerController.m delete mode 100644 GKDYVideo/Classes/Tools/GKPopupController/GKPopupController.h delete mode 100644 GKDYVideo/Classes/Tools/GKPopupController/GKPopupController.m delete mode 100644 GKDYVideo/Classes/Tools/GKPopupController/GKPopupProtocol.h create mode 100644 GKDYVideo/Classes/Tools/GKScaleTransition/GKScaleAnimation.h create mode 100644 GKDYVideo/Classes/Tools/GKScaleTransition/GKScaleAnimation.m create mode 100644 GKDYVideo/Classes/Tools/GKScaleTransition/GKScaleTransition.h create mode 100644 GKDYVideo/Classes/Tools/GKScaleTransition/GKScaleTransition.m delete mode 100644 GKDYVideo/Classes/Tools/GKSlidePopupView/GKSlidePopupView.h delete mode 100644 GKDYVideo/Classes/Tools/GKSlidePopupView/GKSlidePopupView.m diff --git a/GKDYVideo.xcodeproj/project.pbxproj b/GKDYVideo.xcodeproj/project.pbxproj index 37d0a87..829bc79 100644 --- a/GKDYVideo.xcodeproj/project.pbxproj +++ b/GKDYVideo.xcodeproj/project.pbxproj @@ -21,7 +21,6 @@ 6099CDCC22BA31B4005098EE /* GKDoubleLikeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6099CDCB22BA31B4005098EE /* GKDoubleLikeView.m */; }; 60D7CF602626C529004D7477 /* NSMethodSignature+GKCategory.m in Sources */ = {isa = PBXBuildFile; fileRef = 60D7CF5C2626C529004D7477 /* NSMethodSignature+GKCategory.m */; }; 60D7CF612626C529004D7477 /* UITabBar+GKCategory.m in Sources */ = {isa = PBXBuildFile; fileRef = 60D7CF5F2626C529004D7477 /* UITabBar+GKCategory.m */; }; - 79194D712B590225003EC779 /* GKPopupController.m in Sources */ = {isa = PBXBuildFile; fileRef = 79194D702B590225003EC779 /* GKPopupController.m */; }; 79194D742B593A47003EC779 /* GKDYCommentModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 79194D732B593A47003EC779 /* GKDYCommentModel.m */; }; 79194D7F2B593DCD003EC779 /* GKDYCommentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 79194D7E2B593DCD003EC779 /* GKDYCommentCell.m */; }; 7988CB1F227C9DB900023A2B /* GKDYShootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7988CB1E227C9DB900023A2B /* GKDYShootViewController.m */; }; @@ -64,8 +63,10 @@ 79CC62E521573FC500101773 /* GKDYScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 79CC62E421573FC500101773 /* GKDYScrollView.m */; }; 79CC62EB2157402800101773 /* GKDYVideoControlView.m in Sources */ = {isa = PBXBuildFile; fileRef = 79CC62EA2157402800101773 /* GKDYVideoControlView.m */; }; 79CC62F52158E44300101773 /* GKNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 79CC62F42158E44300101773 /* GKNetworking.m */; }; + 79D1421C2C8EBF760081604A /* GKDYListPlayerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 79D1421B2C8EBF760081604A /* GKDYListPlayerController.m */; }; + 79D142392C92CCB00081604A /* GKScaleTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 79D142382C92CCB00081604A /* GKScaleTransition.m */; }; + 79D1423C2C92E82F0081604A /* GKScaleAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 79D1423B2C92E82F0081604A /* GKScaleAnimation.m */; }; 79DD87CE226C268D008FB903 /* GKDYNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 79DD87CD226C268D008FB903 /* GKDYNavigationController.m */; }; - 79E16A132274748F00DE4967 /* GKSlidePopupView.m in Sources */ = {isa = PBXBuildFile; fileRef = 79E16A122274748F00DE4967 /* GKSlidePopupView.m */; }; 79E16A162279A63200DE4967 /* GKDYCommentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 79E16A152279A63200DE4967 /* GKDYCommentView.m */; }; 79EB334C2B5A0B7800423758 /* GKDYCommentControlView.m in Sources */ = {isa = PBXBuildFile; fileRef = 79EB334B2B5A0B7800423758 /* GKDYCommentControlView.m */; }; 79F46BD72A08CC7A006E3B85 /* GKDYVideoFullscreenView.m in Sources */ = {isa = PBXBuildFile; fileRef = 79F46BD62A08CC7A006E3B85 /* GKDYVideoFullscreenView.m */; }; @@ -101,9 +102,6 @@ 60D7CF5D2626C529004D7477 /* NSMethodSignature+GKCategory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMethodSignature+GKCategory.h"; sourceTree = ""; }; 60D7CF5E2626C529004D7477 /* UITabBar+GKCategory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITabBar+GKCategory.h"; sourceTree = ""; }; 60D7CF5F2626C529004D7477 /* UITabBar+GKCategory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITabBar+GKCategory.m"; sourceTree = ""; }; - 79194D6E2B590225003EC779 /* GKPopupController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKPopupController.h; sourceTree = ""; }; - 79194D6F2B590225003EC779 /* GKPopupProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GKPopupProtocol.h; sourceTree = ""; }; - 79194D702B590225003EC779 /* GKPopupController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GKPopupController.m; sourceTree = ""; }; 79194D722B593A47003EC779 /* GKDYCommentModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GKDYCommentModel.h; sourceTree = ""; }; 79194D732B593A47003EC779 /* GKDYCommentModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GKDYCommentModel.m; sourceTree = ""; }; 79194D7D2B593DCD003EC779 /* GKDYCommentCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GKDYCommentCell.h; sourceTree = ""; }; @@ -191,10 +189,14 @@ 79CC62EA2157402800101773 /* GKDYVideoControlView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GKDYVideoControlView.m; sourceTree = ""; }; 79CC62F32158E44300101773 /* GKNetworking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GKNetworking.h; sourceTree = ""; }; 79CC62F42158E44300101773 /* GKNetworking.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GKNetworking.m; sourceTree = ""; }; + 79D1421A2C8EBF760081604A /* GKDYListPlayerController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GKDYListPlayerController.h; sourceTree = ""; }; + 79D1421B2C8EBF760081604A /* GKDYListPlayerController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GKDYListPlayerController.m; sourceTree = ""; }; + 79D142372C92CCB00081604A /* GKScaleTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GKScaleTransition.h; sourceTree = ""; }; + 79D142382C92CCB00081604A /* GKScaleTransition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GKScaleTransition.m; sourceTree = ""; }; + 79D1423A2C92E82F0081604A /* GKScaleAnimation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GKScaleAnimation.h; sourceTree = ""; }; + 79D1423B2C92E82F0081604A /* GKScaleAnimation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GKScaleAnimation.m; sourceTree = ""; }; 79DD87CC226C268D008FB903 /* GKDYNavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GKDYNavigationController.h; sourceTree = ""; }; 79DD87CD226C268D008FB903 /* GKDYNavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GKDYNavigationController.m; sourceTree = ""; }; - 79E16A112274748F00DE4967 /* GKSlidePopupView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GKSlidePopupView.h; sourceTree = ""; }; - 79E16A122274748F00DE4967 /* GKSlidePopupView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GKSlidePopupView.m; sourceTree = ""; }; 79E16A142279A63200DE4967 /* GKDYCommentView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GKDYCommentView.h; sourceTree = ""; }; 79E16A152279A63200DE4967 /* GKDYCommentView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GKDYCommentView.m; sourceTree = ""; }; 79EB334A2B5A0B7800423758 /* GKDYCommentControlView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GKDYCommentControlView.h; sourceTree = ""; }; @@ -376,16 +378,6 @@ path = Category; sourceTree = ""; }; - 79194D6D2B590225003EC779 /* GKPopupController */ = { - isa = PBXGroup; - children = ( - 79194D6E2B590225003EC779 /* GKPopupController.h */, - 79194D702B590225003EC779 /* GKPopupController.m */, - 79194D6F2B590225003EC779 /* GKPopupProtocol.h */, - ); - path = GKPopupController; - sourceTree = ""; - }; 79194D752B593CFE003EC779 /* Comment */ = { isa = PBXGroup; children = ( @@ -411,6 +403,8 @@ children = ( 79CC62D521573C2C00101773 /* GKDYPlayerViewController.h */, 79CC62D621573C2C00101773 /* GKDYPlayerViewController.m */, + 79D1421A2C8EBF760081604A /* GKDYListPlayerController.h */, + 79D1421B2C8EBF760081604A /* GKDYListPlayerController.m */, ); path = Controller; sourceTree = ""; @@ -610,13 +604,12 @@ 79CC62C721573B2700101773 /* Tools */ = { isa = PBXGroup; children = ( + 79D142362C92CC690081604A /* GKScaleTransition */, 799277D129C837A000A410DC /* GKDYTools.h */, 799277D229C837A000A410DC /* GKDYTools.m */, - 79194D6D2B590225003EC779 /* GKPopupController */, 60D7CF5B2626C48D004D7477 /* Category */, 60089110229BDDB4002A6D52 /* GKLikeView */, 607CAB7022818FC20062AC0F /* GKLoadingView */, - 79E16A102274746200DE4967 /* GKSlidePopupView */, 79CC62F22158E42D00101773 /* GKNetworking */, 7991D4CC2A04DEAC002AADCD /* GKRotationManager */, ); @@ -632,13 +625,15 @@ path = GKNetworking; sourceTree = ""; }; - 79E16A102274746200DE4967 /* GKSlidePopupView */ = { + 79D142362C92CC690081604A /* GKScaleTransition */ = { isa = PBXGroup; children = ( - 79E16A112274748F00DE4967 /* GKSlidePopupView.h */, - 79E16A122274748F00DE4967 /* GKSlidePopupView.m */, + 79D142372C92CCB00081604A /* GKScaleTransition.h */, + 79D142382C92CCB00081604A /* GKScaleTransition.m */, + 79D1423A2C92E82F0081604A /* GKScaleAnimation.h */, + 79D1423B2C92E82F0081604A /* GKScaleAnimation.m */, ); - path = GKSlidePopupView; + path = GKScaleTransition; sourceTree = ""; }; /* End PBXGroup section */ @@ -771,6 +766,7 @@ 601140C622EFD0450014EF50 /* GKDYScaleVideoView.m in Sources */, 79A5252729D2831400CFB32F /* GKDYUserModel.m in Sources */, 79F46BD72A08CC7A006E3B85 /* GKDYVideoFullscreenView.m in Sources */, + 79D142392C92CCB00081604A /* GKScaleTransition.m in Sources */, 7991D4DF2A04DEAD002AADCD /* GKLandscapeViewController.m in Sources */, 607CAB822282A8D80062AC0F /* GKDYMessageViewController.m in Sources */, 79CC62D721573C2C00101773 /* GKDYPlayerViewController.m in Sources */, @@ -801,15 +797,15 @@ 79CC62942157377400101773 /* AppDelegate.m in Sources */, 799277D329C837A000A410DC /* GKDYTools.m in Sources */, 60089113229BE0BD002A6D52 /* GKLikeView.m in Sources */, + 79D1421C2C8EBF760081604A /* GKDYListPlayerController.m in Sources */, 79194D742B593A47003EC779 /* GKDYCommentModel.m in Sources */, 79C4208A29C448FA00A0AB84 /* GKDYVideoPortraitView.m in Sources */, 79A5252429D1998100CFB32F /* GKDYVideoListCell.m in Sources */, 7991D4E42A04E499002AADCD /* GKDYVideoLandscapeCell.m in Sources */, - 79194D712B590225003EC779 /* GKPopupController.m in Sources */, + 79D1423C2C92E82F0081604A /* GKScaleAnimation.m in Sources */, 79CC62D121573BFD00101773 /* GKDYHomeViewController.m in Sources */, 799277F829CAF77300A410DC /* GKDYVideoPreviewView.m in Sources */, 6099CDCC22BA31B4005098EE /* GKDoubleLikeView.m in Sources */, - 79E16A132274748F00DE4967 /* GKSlidePopupView.m in Sources */, 607CAB882282BB3F0062AC0F /* GKDYTabBar.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/GKDYVideo/Classes/Home/Comment/View/GKDYCommentView.h b/GKDYVideo/Classes/Home/Comment/View/GKDYCommentView.h index c1fd3bf..b1abd59 100644 --- a/GKDYVideo/Classes/Home/Comment/View/GKDYCommentView.h +++ b/GKDYVideo/Classes/Home/Comment/View/GKDYCommentView.h @@ -9,6 +9,7 @@ #import #import "GKDYVideoModel.h" #import +#import "GKDYVideoPortraitCell.h" NS_ASSUME_NONNULL_BEGIN @@ -34,7 +35,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)requestDataWithModel:(GKDYVideoModel *)model; -- (void)show; +- (void)showWithCell:(GKDYVideoPortraitCell *)cell containerView:(UIView *)containerView; @end diff --git a/GKDYVideo/Classes/Home/Comment/View/GKDYCommentView.m b/GKDYVideo/Classes/Home/Comment/View/GKDYCommentView.m index 440f6a3..02b48ec 100644 --- a/GKDYVideo/Classes/Home/Comment/View/GKDYCommentView.m +++ b/GKDYVideo/Classes/Home/Comment/View/GKDYCommentView.m @@ -38,8 +38,11 @@ @interface GKDYCommentView() + +- (UIView *)sourceViewWithIndex:(NSInteger)index; + +@end + +@interface GKDYListPlayerController : GKDYBaseViewController + +@property (nonatomic, weak) id delegate; + +@property (nonatomic, strong) GKDYVideoScrollView *scrollView; + +@property (nonatomic, strong) NSMutableArray *videoList; +@property (nonatomic, assign) NSInteger index; + +@end + +NS_ASSUME_NONNULL_END diff --git a/GKDYVideo/Classes/Home/Video/Controller/GKDYListPlayerController.m b/GKDYVideo/Classes/Home/Video/Controller/GKDYListPlayerController.m new file mode 100644 index 0000000..bc52468 --- /dev/null +++ b/GKDYVideo/Classes/Home/Video/Controller/GKDYListPlayerController.m @@ -0,0 +1,218 @@ +// +// GKDYListPlayerController.m +// GKDYVideo +// +// Created by QuintGao on 2024/9/9. +// Copyright © 2024 QuintGao. All rights reserved. +// + +#import "GKDYListPlayerController.h" +#import "GKDYPlayerManager.h" +#import "GKDYVideoPortraitCell.h" +#import "GKDYVideoLandscapeCell.h" +#import "GKScaleTransition.h" +#import "GKDYCommentView.h" +#import "GKDYUserViewController.h" + +@interface GKDYPlayerNavigationController() + +@property (nonatomic, strong) GKScaleTransition *transition; + +@end + +@implementation GKDYPlayerNavigationController + +- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { + [super pushViewController:viewController animated:animated]; + + if ([viewController isKindOfClass:GKDYListPlayerController.class]) { + self.transition = [[GKScaleTransition alloc] init]; + [self.transition connectToViewController:self]; + self.transition.delegate = (id)viewController; + } +} + +@end + + +@interface GKDYListPlayerController () + +@property (nonatomic, strong) GKDYPlayerManager *manager; + +@property (nonatomic, strong) GKDYCommentView *commentView; + +@property (nonatomic, weak) UIView *containerView; + +@end + +@implementation GKDYListPlayerController + +- (void)viewDidLoad { + [super viewDidLoad]; + + [self initUI]; + [self initData]; +} + +- (void)initUI { + self.gk_navBackgroundColor = UIColor.clearColor; + self.gk_navLeftBarButtonItem = [UIBarButtonItem gk_itemWithImage:[UIImage gk_imageNamed:@"btn_back_white"] target:self action:@selector(backItemClick:)]; + + [self.view addSubview:self.scrollView]; + [self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; +} + +- (void)initData { + self.view.backgroundColor = UIColor.blackColor; + self.manager.dataSources = self.videoList; + self.manager.isAppeared = YES; + self.scrollView.defaultIndex = self.index; + [self.scrollView reloadData]; +} + +- (void)backItemClick:(id)sender { + [self dismiss]; +} + +- (void)dismiss { + [self dismissViewControllerAnimated:YES completion:nil]; +} + +#pragma mark - GKScaleTransitionDelegate +@synthesize sourceView; + +- (void)transitionPanBegan { + [self.manager pause]; +} + +- (void)transitionPanChange { + +} + +- (void)transitionPanEnded:(BOOL)isDismiss { + if (!isDismiss) { + [self.manager play]; + } +} + +#pragma mark - GKVideoScrollViewDataSource +- (NSInteger)numberOfRowsInScrollView:(GKVideoScrollView *)scrollView { + return self.manager.dataSources.count; +} + +- (GKVideoViewCell *)scrollView:(GKVideoScrollView *)scrollView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + NSString *identifier = scrollView == self.scrollView ? @"GKDYVideoPortraitCell" : @"GKDYVideoLandscapeCell"; + GKDYVideoCell *cell = [scrollView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath]; + [cell loadData:self.manager.dataSources[indexPath.row]]; + if ([cell isKindOfClass:GKDYVideoPortraitCell.class]) { + GKDYVideoPortraitCell *portraitCell = (GKDYVideoPortraitCell *)cell; + portraitCell.delegate = self; + portraitCell.manager = self.manager; + }else { + GKDYVideoLandscapeCell *landscapeCell = (GKDYVideoLandscapeCell *)cell; + @weakify(self); + landscapeCell.backClickBlock = ^{ + @strongify(self); + [self.manager rotate]; + }; + } + return cell; +} + +#pragma mark - GKDYVideoScrollViewDelegate +- (void)scrollView:(GKVideoScrollView *)scrollView didEndScrollingCell:(UIView *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { + [self.manager playVideoWithCell:(GKDYVideoCell *)cell index:indexPath.row]; + +// [self.vc.currentListVC scrollItemToIndexPath:indexPath]; +} + +- (void)scrollView:(GKVideoScrollView *)scrollView didEndDisplayingCell:(UIView *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { + [self.manager stopPlayWithCell:(GKDYVideoCell *)cell index:indexPath.row]; +} + +#pragma mark - GKDYVideoCellDelegate +- (void)videoCell:(GKDYVideoCell *)cell didClickIcon:(GKDYVideoModel *)model { + [self dismiss]; +} + +- (void)videoCell:(GKDYVideoCell *)cell didClickLike:(GKDYVideoModel *)model { + model.isLike = !model.isLike; + [self.scrollView reloadData]; +} + +- (void)videoCell:(GKDYVideoPortraitCell *)cell didClickFullscreen:(GKDYVideoModel *)model { + [self.manager rotate]; +} + +- (void)cellDidClickIcon:(GKDYVideoModel *)model { + GKDYUserViewController *userVC = [[GKDYUserViewController alloc] init]; + userVC.model = model; + [self.navigationController pushViewController:userVC animated:YES]; +} + +- (void)videoCell:(GKDYVideoPortraitCell *)cell didClickComment:(GKDYVideoModel *)model { + UIView *containerView = [[UIView alloc] init]; + containerView.backgroundColor = UIColor.blackColor; + containerView.frame = self.view.bounds; + [self.view addSubview:containerView]; + self.containerView = containerView; + + self.commentView.videoModel = model; + [self.commentView showWithCell:cell containerView:containerView]; +} + +#pragma mark - GKDYCommentViewDelegate +- (void)commentView:(GKDYCommentView *)commentView showOrHide:(BOOL)show { + +} + +#pragma mark - 懒加载 +- (GKDYVideoScrollView *)scrollView { + if (!_scrollView) { + _scrollView = [[GKDYVideoScrollView alloc] init]; + _scrollView.dataSource = self; + _scrollView.delegate = self; + [_scrollView registerClass:GKDYVideoPortraitCell.class forCellReuseIdentifier:@"GKDYVideoPortraitCell"]; + } + return _scrollView; +} + +- (GKDYPlayerManager *)manager { + if (!_manager) { + _manager = [[GKDYPlayerManager alloc] init]; + _manager.scrollView = self.scrollView; + } + return _manager; +} + +- (GKDYCommentView *)commentView { + if (!_commentView) { + _commentView = [[GKDYCommentView alloc] init]; + _commentView.delegate = self; + } + return _commentView; +} + +- (NSMutableArray *)videoList { + if (!_videoList) { + _videoList = [NSMutableArray array]; + } + return _videoList; +} + +- (UIView *)sourceView { + if ([self.delegate respondsToSelector:@selector(sourceViewWithIndex:)]) { + NSInteger index = 0; + if (self.isViewLoaded) { + index = self.scrollView.currentIndex; + }else { + index = self.index; + } + return [self.delegate sourceViewWithIndex:index]; + } + return nil; +} + +@end diff --git a/GKDYVideo/Classes/Home/Video/Controller/GKDYPlayerViewController.m b/GKDYVideo/Classes/Home/Video/Controller/GKDYPlayerViewController.m index aa748c5..0b4ede3 100644 --- a/GKDYVideo/Classes/Home/Video/Controller/GKDYPlayerViewController.m +++ b/GKDYVideo/Classes/Home/Video/Controller/GKDYPlayerViewController.m @@ -8,7 +8,6 @@ #import "GKDYPlayerViewController.h" #import "GKDYUserViewController.h" -#import "GKSlidePopupView.h" #import "GKDYCommentView.h" #import "GKDYCommentControlView.h" #import "GKBallLoadingView.h" @@ -18,23 +17,14 @@ #import "GKDYPlayerManager.h" #import "GKDYVideoPortraitCell.h" #import "GKDYVideoLandscapeCell.h" -#import "GKPopupController.h" -@interface GKDYPlayerViewController () +@interface GKDYPlayerViewController () -@property (nonatomic, strong) GKDYPlayerManager *manager; - -@property (nonatomic, strong) UIView *containerView; - -@property (nonatomic, weak) GKDYVideoPortraitCell *currentCell; -@property (nonatomic, weak) GKDYVideoModel *currentModel; +@property (nonatomic, strong) GKDYPlayerManager *manager; @property (nonatomic, strong) GKDYCommentView *commentView; -@property (nonatomic, assign) CGFloat playerW; -@property (nonatomic, assign) CGFloat playerH; - -@property (nonatomic, assign) BOOL isOpen; +@property (nonatomic, weak) UIView *containerView; @end @@ -171,17 +161,14 @@ - (void)cellDidClickIcon:(GKDYVideoModel *)model { } - (void)cellDidClickComment:(GKDYVideoModel *)model cell:(GKDYVideoPortraitCell *)cell { - self.currentCell = cell; - self.currentModel = model; + UIView *containerView = [[UIView alloc] init]; + containerView.backgroundColor = UIColor.blackColor; + containerView.frame = self.view.bounds; + [self.view addSubview:containerView]; + self.containerView = containerView; - self.commentView.player = self.manager.player; self.commentView.videoModel = model; - - self.containerView.frame = self.view.bounds; - [self.view addSubview:self.containerView]; - self.commentView.containerView = self.containerView; - - [self.commentView show]; + [self.commentView showWithCell:cell containerView:self.containerView]; } - (void)cellZoomBegan:(GKDYVideoModel *)model { @@ -198,12 +185,6 @@ - (void)cellZoomEnded:(GKDYVideoModel *)model isFullscreen:(BOOL)isFullscreen { #pragma mark - GKDYCommentViewDelegate - (void)commentView:(GKDYCommentView *)commentView showOrHide:(BOOL)show { - if (!show) { - self.manager.player.containerView = self.currentCell.coverImgView; - self.manager.player.controlView = self.currentCell.portraitView; - [self.commentView.containerView removeFromSuperview]; - } - if ([self.delegate respondsToSelector:@selector(playerVC:commentShowOrHide:)]) { [self.delegate playerVC:self commentShowOrHide:show]; } @@ -226,12 +207,4 @@ - (GKDYCommentView *)commentView { return _commentView; } -- (UIView *)containerView { - if (!_containerView) { - _containerView = [[UIView alloc] init]; - _containerView.backgroundColor = UIColor.blackColor; - } - return _containerView; -} - @end diff --git a/GKDYVideo/Classes/Mine/Controller/GKDYUserViewController.m b/GKDYVideo/Classes/Mine/Controller/GKDYUserViewController.m index 422f61d..6568cee 100644 --- a/GKDYVideo/Classes/Mine/Controller/GKDYUserViewController.m +++ b/GKDYVideo/Classes/Mine/Controller/GKDYUserViewController.m @@ -12,8 +12,9 @@ #import "GKDYUserHeaderView.h" #import "GKDYVideoListViewController.h" #import "GKDYScaleVideoView.h" +#import "GKDYListPlayerController.h" -@interface GKDYUserViewController () +@interface GKDYUserViewController () @property (nonatomic, strong) UILabel *titleView; @@ -123,25 +124,43 @@ - (void)smoothView:(GKPageSmoothView *)smoothView listScrollViewDidScroll:(UIScr #pragma mark - Private - (void)showVideoViewWithList:(NSArray *)list index:(NSInteger)index { - GKDYScaleVideoView *videoView = [[GKDYScaleVideoView alloc] initWithFrame:self.view.bounds]; - - [list enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + GKDYListPlayerController *listVC = [[GKDYListPlayerController alloc] init]; + [list enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL * _Nonnull stop) { GKDYVideoModel *model = [[GKDYVideoModel alloc] initWithModel:obj]; model.source_name = self.headerView.model.author; model.author_avatar = self.headerView.model.author_icon; - [videoView.videoList addObject:model]; + [listVC.videoList addObject:model]; }]; + listVC.index = index; + listVC.delegate = self; +// listVC.modalPresentationStyle = UIModalPresentationOverCurrentContext; +// [self presentViewController:listVC animated:YES completion:nil]; - @weakify(self); - [videoView setRequestBlock:^{ - @strongify(self); - [self requestMoreList]; - }]; +// UINavigationController *nav = [UINavigationController rootVC:listVC]; +// nav.modalPresentationStyle = UIModalPresentationOverCurrentContext; + GKDYPlayerNavigationController *nav = [GKDYPlayerNavigationController rootVC:listVC]; + [self presentViewController:nav animated:YES completion:nil]; - videoView.vc = self; - videoView.index = index; - [videoView show]; - self.videoView = videoView; + +// GKDYScaleVideoView *videoView = [[GKDYScaleVideoView alloc] initWithFrame:self.view.bounds]; +// +// [list enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { +// GKDYVideoModel *model = [[GKDYVideoModel alloc] initWithModel:obj]; +// model.source_name = self.headerView.model.author; +// model.author_avatar = self.headerView.model.author_icon; +// [videoView.videoList addObject:model]; +// }]; +// +// @weakify(self); +// [videoView setRequestBlock:^{ +// @strongify(self); +// [self requestMoreList]; +// }]; +// +// videoView.vc = self; +// videoView.index = index; +// [videoView show]; +// self.videoView = videoView; } - (void)requestMoreList { @@ -159,6 +178,15 @@ - (void)requestMoreList { }]; } +#pragma mark - GKDYListPlayerControllerDelegate +- (UIView *)sourceViewWithIndex:(NSInteger)index { + UICollectionViewCell *cell = [self.currentListVC.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]]; + if ([self.currentListVC.collectionView.visibleCells containsObject:cell]) { + return cell; + } + return nil; +} + #pragma mark - Lazy - (UILabel *)titleView { if (!_titleView) { diff --git a/GKDYVideo/Classes/Mine/View/GKDYScaleVideoView.m b/GKDYVideo/Classes/Mine/View/GKDYScaleVideoView.m index 6af5459..9ed3222 100644 --- a/GKDYVideo/Classes/Mine/View/GKDYScaleVideoView.m +++ b/GKDYVideo/Classes/Mine/View/GKDYScaleVideoView.m @@ -346,9 +346,9 @@ - (void)videoCell:(GKDYVideoPortraitCell *)cell didClickComment:(GKDYVideoModel self.playerW = frame.size.width; self.playerH = frame.size.height; - GKPopupController *controller = [[GKPopupController alloc] init]; - controller.delegate = self; - [controller show]; +// GKPopupController *controller = [[GKPopupController alloc] init]; +// controller.delegate = self; +// [controller show]; } #pragma mark - GKPopupProtocol diff --git a/GKDYVideo/Classes/Tools/GKPopupController/GKPopupController.h b/GKDYVideo/Classes/Tools/GKPopupController/GKPopupController.h deleted file mode 100644 index 32e5cc0..0000000 --- a/GKDYVideo/Classes/Tools/GKPopupController/GKPopupController.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// GKPopupController.h -// GKPopupController -// -// Created by QuintGao on 2024/1/12. -// - -#import -#import "GKPopupProtocol.h" - -NS_ASSUME_NONNULL_BEGIN - -typedef NS_ENUM(NSUInteger, GKPopupShowType) { - GKPopupShowTypeShort, - GKPopupShowTypeLong -}; - -@interface GKPopupController : UIViewController - -@property (nonatomic, weak) id delegate; - -@property (nonatomic, assign) GKPopupShowType showType; - -- (void)show; - -- (void)dismiss; - -- (void)refreshContentHeight; - -@end - -NS_ASSUME_NONNULL_END diff --git a/GKDYVideo/Classes/Tools/GKPopupController/GKPopupController.m b/GKDYVideo/Classes/Tools/GKPopupController/GKPopupController.m deleted file mode 100644 index 1db51e3..0000000 --- a/GKDYVideo/Classes/Tools/GKPopupController/GKPopupController.m +++ /dev/null @@ -1,458 +0,0 @@ -// -// GKPopupController.m -// GKPopupController -// -// Created by QuintGao on 2024/1/12. -// - -#import "GKPopupController.h" - -typedef NS_ENUM(NSUInteger, GKPopupPanGestureDirection) { - GKPopupPanGestureDirectionHorizontal, // 水平方向 - GKPopupPanGestureDirectionVelocity // 竖直方向 -}; - -int const static kPopupPanTranslationThreshold = 5; - -@interface GKPopupPanGestureRecognizer : UIPanGestureRecognizer - -@property (nonatomic, assign) GKPopupPanGestureDirection direction; - -@end - -@implementation GKPopupPanGestureRecognizer { - BOOL _isDrag; - int _moveX; - int _moveY; -} - -- (void)touchesMoved:(NSSet *)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 (!_isDrag) { - if (abs(_moveX) > kPopupPanTranslationThreshold) { - if (self.direction == GKPopupPanGestureDirectionVelocity) { - self.state = UIGestureRecognizerStateFailed; - }else { - _isDrag = YES; - } - }else if (abs(_moveY) > kPopupPanTranslationThreshold) { - if (self.direction == GKPopupPanGestureDirectionHorizontal) { - self.state = UIGestureRecognizerStateFailed; - }else { - _isDrag = YES; - } - } - } -} - -- (void)reset { - [super reset]; - _isDrag = NO; - _moveX = 0; - _moveY = 0; -} - -@end - -@interface GKPopupController () - -@property (nonatomic, strong) UIWindow *alertWindow; - -@property (nonatomic, strong) UIView *backgroundView; - -@property (nonatomic, weak) UIView *contentView; - -@property (nonatomic, assign) CGFloat contentHeight; - -@property (nonatomic, weak) UIScrollView *scrollView; - -@property (nonatomic, assign) BOOL isDragScrollView; - -@property (nonatomic, assign) CGPoint beginTranslation; - -@property (nonatomic, strong) UITapGestureRecognizer *tapGesture; - -@property (nonatomic, strong) GKPopupPanGestureRecognizer *horizontalPanGesture; - -@property (nonatomic, strong) GKPopupPanGestureRecognizer *velocityPanGesture; - -@end - -@implementation GKPopupController - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - [self.navigationController setNavigationBarHidden:YES]; -} - -#pragma mark - Public -- (void)show { - [self initUI]; - [self alertWindow]; - [self showWithCompletion:nil]; -} - -- (void)dismiss { - [self dismissWithCompletion:nil]; -} - -- (void)refreshContentHeight { - CGFloat contentHeight = [self.delegate contentHeight]; - if (contentHeight > self.contentHeight) { - CGRect frame = self.contentView.frame; - frame.size.height = contentHeight; - self.contentView.frame = frame; - } - self.contentHeight = contentHeight; - - [UIView animateWithDuration:self.animationDuration delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ - CGRect frame = self.contentView.frame; - frame.origin.y = CGRectGetHeight(self.view.frame) - self.contentHeight; - self.contentView.frame = frame; - if ([self.delegate respondsToSelector:@selector(contentViewRefreshAnimation)]) { - [self.delegate contentViewRefreshAnimation]; - } - } completion:^(BOOL finished) { - CGRect frame = self.contentView.frame; - frame.size.height = self.contentHeight; - self.contentView.frame = frame; - if ([self.delegate respondsToSelector:@selector(contentViewRefreshCompletion)]) { - [self.delegate contentViewRefreshCompletion]; - } - }]; -} - -#pragma mark - UIGestureRecognizerDelegate -- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { - if (gestureRecognizer == self.horizontalPanGesture || gestureRecognizer == self.velocityPanGesture) { - UIView *touchView = touch.view; - while (touchView != nil) { - if ([touchView isKindOfClass:UIScrollView.class]) { - self.scrollView = (UIScrollView *)touchView; - self.isDragScrollView = YES; - break; - }else if (touchView == self.contentView) { - self.isDragScrollView = NO; - break; - } - touchView = (UIView *)[touchView nextResponder]; - } - } - return YES; -} - -- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { - CGPoint point = [gestureRecognizer locationInView:self.contentView]; - if (gestureRecognizer == self.tapGesture) { - if ([self.contentView.layer containsPoint:point] && gestureRecognizer.view == self.view) { - return NO; - } - }else if (gestureRecognizer == self.horizontalPanGesture || gestureRecognizer == self.velocityPanGesture) { - if (![self.contentView.layer containsPoint:point] && gestureRecognizer.view == self.view) { - return NO; - } - } - return YES; -} - -- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { - if (gestureRecognizer == self.horizontalPanGesture || gestureRecognizer == self.velocityPanGesture) { - if ([otherGestureRecognizer isKindOfClass:NSClassFromString(@"UIScrollViewPanGestureRecognizer")] || [otherGestureRecognizer isKindOfClass:UIPanGestureRecognizer.class]) { - if ([otherGestureRecognizer.view isKindOfClass:UIScrollView.class]) { - return YES; - } - } - } - return NO; -} - -#pragma mark - Gesture Handle -- (void)handleTapGesture:(UITapGestureRecognizer *)tapGesture { - CGPoint point = [tapGesture locationInView:self.contentView]; - if (![self.contentView.layer containsPoint:point] && tapGesture.view == self.view) { - [self dismiss]; - } -} - -- (void)handlePanGesture:(GKPopupPanGestureRecognizer *)panGesture { - CGPoint translation = [panGesture locationInView:panGesture.view]; - CGPoint velocity = [panGesture velocityInView:panGesture.view]; - // 最小Y值 - CGFloat minY = CGRectGetHeight(self.view.frame) - self.contentHeight; - - switch (panGesture.state) { - case UIGestureRecognizerStateBegan: { - self.beginTranslation = translation; - // 横向滑动时,禁止UIScrollView滑动 - if (panGesture.direction == GKPopupPanGestureDirectionHorizontal) { - self.scrollView.panGestureRecognizer.enabled = NO; - } - if ([self.delegate respondsToSelector:@selector(panSlideBegan)]) { - [self.delegate panSlideBegan]; - } - } - break; - case UIGestureRecognizerStateChanged: { - if (panGesture.direction == GKPopupPanGestureDirectionHorizontal) { // 横向滑动 - // 滑动百分比 - CGFloat ratio = (translation.x - self.beginTranslation.x) / CGRectGetWidth(self.view.frame); - // 转换为Y值 - CGFloat scrollY = minY + self.contentHeight * ratio; - // 更新frame - [self updateContentViewFrameY:scrollY]; - if ([self.delegate respondsToSelector:@selector(panSlideChangeWithRatio:)]) { - [self.delegate panSlideChangeWithRatio:ratio]; - } - }else { // 纵向滑动 - CGFloat scrollY = minY + (translation.y - self.beginTranslation.y); - CGFloat ratio = (translation.y - self.beginTranslation.y) / self.contentHeight; - if (self.isDragScrollView) { // 拖拽scrollView - // 当UIScrollView在最顶端时,处理视图的滑动 - if (self.scrollView.contentOffset.y <= 0 && translation.y > 0) { - self.scrollView.contentOffset = CGPointZero; - self.scrollView.panGestureRecognizer.enabled = NO; - self.isDragScrollView = NO; - self.beginTranslation = translation; -// [self updateContentViewFrameY:scrollY]; - if ([self.delegate respondsToSelector:@selector(panSlideChangeWithRatio:)]) { - [self.delegate panSlideChangeWithRatio:ratio]; - } - } - }else { - [self updateContentViewFrameY:scrollY]; - if ([self.delegate respondsToSelector:@selector(panSlideChangeWithRatio:)]) { - [self.delegate panSlideChangeWithRatio:ratio]; - } - } - } - // 背景透明度 - CGFloat alpha = (CGRectGetHeight(self.view.frame) - CGRectGetMinY(self.contentView.frame)) / self.contentHeight; - self.backgroundView.alpha = alpha; - } - break; - case UIGestureRecognizerStateCancelled: - case UIGestureRecognizerStateEnded: { - // 平移距离 - CGFloat translationY = CGRectGetMinY(self.contentView.frame) - minY; - if (panGesture.direction == GKPopupPanGestureDirectionHorizontal) { - if (velocity.x > self.velocityThreshold || translationY > self.translationThreshold) { - [self dismissWithCompletion:nil]; - if ([self.delegate respondsToSelector:@selector(panSlideEnded:)]) { - [self.delegate panSlideEnded:NO]; - } - }else { - [self showWithCompletion:nil]; - if ([self.delegate respondsToSelector:@selector(panSlideEnded:)]) { - [self.delegate panSlideEnded:YES]; - } - } - }else { - if (velocity.y > self.velocityThreshold || translationY > self.translationThreshold) { - [self dismissWithCompletion:nil]; - if ([self.delegate respondsToSelector:@selector(panSlideEnded:)]) { - [self.delegate panSlideEnded:NO]; - } - }else { - [self showWithCompletion:nil]; - if ([self.delegate respondsToSelector:@selector(panSlideEnded:)]) { - [self.delegate panSlideEnded:YES]; - } - } - } - self.scrollView.panGestureRecognizer.enabled = YES; - } - break; - default: - break; - } -} - -#pragma mark - Private -- (void)initUI { - self.delegate.popupController = self; - - self.contentView = [self.delegate contentView]; - self.contentHeight = [self.delegate contentHeight]; - - CGRect frame = self.view.bounds; - self.backgroundView.frame = frame; - [self.view addSubview:self.backgroundView]; - - frame.origin.y = frame.size.height; - frame.size.height = self.contentHeight; - self.contentView.frame = frame; - [self.view addSubview:self.contentView]; - - BOOL allowsTap = YES; - if ([self.delegate respondsToSelector:@selector(allowsTapBackgroundToDismiss)]) { - allowsTap = [self.delegate allowsTapBackgroundToDismiss]; - } - if (allowsTap) { - [self.view addGestureRecognizer:self.tapGesture]; - } - BOOL allowsSlide = YES; - if ([self.delegate respondsToSelector:@selector(allowsSlideToDismiss)]) { - allowsSlide = [self.delegate allowsSlideToDismiss]; - } - if (allowsSlide) { - [self.view addGestureRecognizer:self.velocityPanGesture]; - BOOL allowRightSlide = YES; - if ([self.delegate respondsToSelector:@selector(allowsRightSlideToDismiss)]) { - allowRightSlide = [self.delegate allowsRightSlideToDismiss]; - } - if (allowRightSlide) { - [self.view addGestureRecognizer:self.horizontalPanGesture]; - } - } -} - -- (void)showWithCompletion:(void(^)(void))completion { - if ([self.delegate respondsToSelector:@selector(contentViewWillShow)]) { - [self.delegate contentViewWillShow]; - } - [UIView animateWithDuration:self.animationDuration delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ - CGRect frame = self.contentView.frame; - frame.origin.y = self.view.frame.size.height - self.contentHeight; - self.contentView.frame = frame; - self.backgroundView.alpha = 1; - if ([self.delegate respondsToSelector:@selector(contentViewShowAnimation)]) { - [self.delegate contentViewShowAnimation]; - } - } completion:^(BOOL finished) { - if ([self.delegate respondsToSelector:@selector(contentViewDidShow)]) { - [self.delegate contentViewDidShow]; - } - !completion ?: completion(); - }]; -} - -- (void)dismissWithCompletion:(void(^)(void))completion { - if ([self.delegate respondsToSelector:@selector(contentViewWillDismiss)]) { - [self.delegate contentViewWillDismiss]; - } - [UIView animateWithDuration:self.animationDuration delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ - CGRect frame = self.contentView.frame; - frame.origin.y = self.view.frame.size.height; - self.contentView.frame = frame; - self.backgroundView.alpha = 0; - if ([self.delegate respondsToSelector:@selector(contentViewDismissAnimation)]) { - [self.delegate contentViewDismissAnimation]; - } - } completion:^(BOOL finished) { - if ([self.delegate respondsToSelector:@selector(contentViewDidDismiss)]) { - [self.delegate contentViewDidDismiss]; - } - self.alertWindow.hidden = YES; - self.alertWindow.rootViewController = nil; - !completion ?: completion(); - }]; -} - -- (NSTimeInterval)animationDuration { - NSTimeInterval duration = 0.25; - if ([self.delegate respondsToSelector:@selector(animationDuration)]) { - duration = [self.delegate animationDuration]; - } - return duration; -} - -- (void)updateContentViewFrameY:(CGFloat)y { - CGFloat minY = CGRectGetHeight(self.view.frame) - self.contentHeight; - CGRect frame = self.contentView.frame; - frame.origin.y = MAX(minY, y); - self.contentView.frame = frame; -} - -- (CGFloat)velocityThreshold { - CGFloat velocity = 300; - if ([self.delegate respondsToSelector:@selector(velocityThreshold)]) { - velocity = [self.delegate velocityThreshold]; - } - return velocity; -} - -- (CGFloat)translationThreshold { - CGFloat translation = self.contentHeight / 2; - if ([self.delegate respondsToSelector:@selector(translationThreshold)]) { - translation = [self.delegate translationThreshold]; - } - return translation; -} - -#pragma mark - Lazy -- (UIWindow *)alertWindow { - if (!_alertWindow) { - if (@available(iOS 13.0, *)) { - UIScene *scene = [UIApplication sharedApplication].connectedScenes.allObjects.firstObject; - if (scene && [scene isKindOfClass:UIWindowScene.class]) { - _alertWindow = [[UIWindow alloc] initWithWindowScene:(UIWindowScene *)scene]; - } - } - if (!_alertWindow) { - _alertWindow = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds]; - } - _alertWindow.windowLevel = UIWindowLevelStatusBar; - _alertWindow.backgroundColor = UIColor.clearColor; - _alertWindow.hidden = NO; - - BOOL needAddNav = YES; - if ([self.delegate respondsToSelector:@selector(needAddNavigationController)]) { - needAddNav = [self.delegate needAddNavigationController]; - } - if (needAddNav) { - UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:self]; - nav.view.backgroundColor = UIColor.clearColor; - _alertWindow.rootViewController = nav; - }else { - _alertWindow.rootViewController = self; - } - } - return _alertWindow; -} - -- (UIView *)backgroundView { - if (!_backgroundView) { - _backgroundView = [[UIView alloc] init]; - if ([self.delegate respondsToSelector:@selector(backColor)]) { - _backgroundView.backgroundColor = [self.delegate backColor]; - }else { - _backgroundView.backgroundColor = [UIColor.blackColor colorWithAlphaComponent:0.5]; - } - _backgroundView.alpha = 0; - } - return _backgroundView; -} - -- (UITapGestureRecognizer *)tapGesture { - if (!_tapGesture) { - _tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)]; - _tapGesture.delegate = self; - } - return _tapGesture; -} - -- (GKPopupPanGestureRecognizer *)horizontalPanGesture { - if (!_horizontalPanGesture) { - _horizontalPanGesture = [[GKPopupPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)]; - _horizontalPanGesture.delegate = self; - _horizontalPanGesture.direction = GKPopupPanGestureDirectionHorizontal; - } - return _horizontalPanGesture; -} - -- (GKPopupPanGestureRecognizer *)velocityPanGesture { - if (!_velocityPanGesture) { - _velocityPanGesture = [[GKPopupPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)]; - _velocityPanGesture.delegate = self; - _velocityPanGesture.direction = GKPopupPanGestureDirectionVelocity; - } - return _velocityPanGesture; -} - -@end diff --git a/GKDYVideo/Classes/Tools/GKPopupController/GKPopupProtocol.h b/GKDYVideo/Classes/Tools/GKPopupController/GKPopupProtocol.h deleted file mode 100644 index 721a1d0..0000000 --- a/GKDYVideo/Classes/Tools/GKPopupController/GKPopupProtocol.h +++ /dev/null @@ -1,75 +0,0 @@ -// -// GKPopupProtocol.h -// Pods -// -// Created by QuintGao on 2024/1/12. -// - -#import - -@class GKPopupController; - -@protocol GKPopupProtocol - -@property (nonatomic, weak) GKPopupController *popupController; - -@required - -// 内容视图 -- (UIView *)contentView; - -// 内容视图高度 -- (CGFloat)contentHeight; - -@optional - -// 是否需要添加导航控制器,默认YES -- (BOOL)needAddNavigationController; - -// 显示或隐藏时的动画时间,默认0.25 -- (NSTimeInterval)animationDuration; - -// 背景色,默认黑色0.5透明度 -- (UIColor *)backColor; - -// 是否允许点击背景隐藏,默认YES -- (BOOL)allowsTapBackgroundToDismiss; - -// 是否支持滑动返回(包括下滑和右滑),默认YES -- (BOOL)allowsSlideToDismiss; - -// 是否支持右滑返回,默认YES -- (BOOL)allowsRightSlideToDismiss; - -// 滑动返回时的速度阈值,超过此阈值会dismiss,默认300 -- (CGFloat)velocityThreshold; - -// 滑动返回时的平移阈值,超过此阈值会dismiss,默认contentView高度的一半 -- (CGFloat)translationThreshold; - -// 滑动开始 -- (void)panSlideBegan; - -// 滑动中,滑动比例 -- (void)panSlideChangeWithRatio:(CGFloat)ratio; - -// 滑动结束,isShow是否显示 -- (void)panSlideEnded:(BOOL)isShow; - -- (void)contentViewWillShow; - -- (void)contentViewShowAnimation; - -- (void)contentViewDidShow; - -- (void)contentViewWillDismiss; - -- (void)contentViewDismissAnimation; - -- (void)contentViewDidDismiss; - -- (void)contentViewRefreshAnimation; - -- (void)contentViewRefreshCompletion; - -@end diff --git a/GKDYVideo/Classes/Tools/GKScaleTransition/GKScaleAnimation.h b/GKDYVideo/Classes/Tools/GKScaleTransition/GKScaleAnimation.h new file mode 100644 index 0000000..940bfac --- /dev/null +++ b/GKDYVideo/Classes/Tools/GKScaleTransition/GKScaleAnimation.h @@ -0,0 +1,26 @@ +// +// GKScaleAnimation.h +// GKDYVideo +// +// Created by QuintGao on 2024/9/12. +// Copyright © 2024 QuintGao. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSUInteger, GKScaleType) { + GKScaleType_Present, + GKScaleType_Dismiss +}; + +@class GKScaleTransition; + +@interface GKScaleAnimation : NSObject + +- (instancetype)initWithType:(GKScaleType)type transition:(GKScaleTransition *)transition; + +@end + +NS_ASSUME_NONNULL_END diff --git a/GKDYVideo/Classes/Tools/GKScaleTransition/GKScaleAnimation.m b/GKDYVideo/Classes/Tools/GKScaleTransition/GKScaleAnimation.m new file mode 100644 index 0000000..26ebd51 --- /dev/null +++ b/GKDYVideo/Classes/Tools/GKScaleTransition/GKScaleAnimation.m @@ -0,0 +1,142 @@ +// +// GKScaleAnimation.m +// GKDYVideo +// +// Created by QuintGao on 2024/9/12. +// Copyright © 2024 QuintGao. All rights reserved. +// + +#import "GKScaleAnimation.h" +#import "GKScaleTransition.h" + +@interface GKScaleAnimation() + +@property (nonatomic, assign) GKScaleType type; + +@property (nonatomic, weak) GKScaleTransition *transition; + +@property (nonatomic, weak) UIViewController *fromVC; +@property (nonatomic, weak) UIViewController *toVC; + +@end + +@implementation GKScaleAnimation + +- (instancetype)initWithType:(GKScaleType)type transition:(nonnull GKScaleTransition *)transition { + if (self = [super init]) { + self.type = type; + self.transition = transition; + } + return self; +} + +#pragma mark - UIViewControllerAnimatedTransitioning +- (NSTimeInterval)transitionDuration:(id)transitionContext { + return 0.25; +} + +- (void)animateTransition:(id)transitionContext { + self.fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; + self.toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; + switch (self.type) { + case GKScaleType_Present: + [self presentAnimation:transitionContext]; + break; + case GKScaleType_Dismiss: + [self dismissAnimation:transitionContext]; + break; + } +} + +- (void)presentAnimation:(id)transitionContext { + UIView *containerView = transitionContext.containerView; + [containerView addSubview:self.toVC.view]; + + UIView *cell = nil; + if ([self.transition.delegate respondsToSelector:@selector(sourceView)]) { + cell = self.transition.delegate.sourceView; + } + + __block UIView *snapshotView = [cell snapshotViewAfterScreenUpdates:NO]; + if (snapshotView) { + snapshotView.frame = self.toVC.view.bounds; + [self.toVC.view addSubview:snapshotView]; + } + + CGRect initialFrame = [cell.superview convertRect:cell.frame toView:self.fromVC.view]; + CGRect finalFrame = [transitionContext finalFrameForViewController:self.toVC]; + + self.toVC.view.center = CGPointMake(initialFrame.origin.x + initialFrame.size.width / 2, initialFrame.origin.y + initialFrame.size.height / 2); + self.toVC.view.transform = CGAffineTransformMakeScale(initialFrame.size.width/finalFrame.size.width, initialFrame.size.height/finalFrame.size.height); + + UIViewController *toTopVC = nil; + if ([self.toVC isKindOfClass:UINavigationController.class]) { + toTopVC = [(UINavigationController *)self.toVC topViewController]; + [toTopVC beginAppearanceTransition:YES animated:YES]; + } + + NSTimeInterval duration = [self transitionDuration:transitionContext]; + [UIView animateWithDuration:duration +// delay:0 usingSpringWithDamping:0.8 initialSpringVelocity:0.2 options:UIViewAnimationOptionLayoutSubviews + animations:^{ + self.toVC.view.center = CGPointMake(finalFrame.origin.x + finalFrame.size.width/2, finalFrame.origin.y + finalFrame.size.height/2); + self.toVC.view.transform = CGAffineTransformMakeScale(1, 1); + snapshotView.alpha = 0; + } completion:^(BOOL finished) { + [transitionContext completeTransition:!transitionContext.transitionWasCancelled]; + if (toTopVC) { + [toTopVC endAppearanceTransition]; + } + if (snapshotView) { + [snapshotView removeFromSuperview]; + snapshotView = nil; + } + }]; +} + +- (void)dismissAnimation:(id)transitionContext { + __block UIView *snapshotView; + CGRect finalFrame; + CGFloat scaleRatio; + + UIView *cell = nil; + if ([self.transition.delegate respondsToSelector:@selector(sourceView)]) { + cell = self.transition.delegate.sourceView; + } + if (cell) { + snapshotView = [cell snapshotViewAfterScreenUpdates:NO]; + snapshotView.layer.zPosition = 20; + + scaleRatio = self.fromVC.view.frame.size.width / cell.frame.size.width; + finalFrame = [cell.superview convertRect:cell.frame toView:self.toVC.view]; + }else { + snapshotView = [self.fromVC.view snapshotViewAfterScreenUpdates:NO]; + CGSize toSize = self.toVC.view.frame.size; + scaleRatio = self.fromVC.view.frame.size.width / toSize.width; + finalFrame = CGRectMake((toSize.width - 5)/2, (toSize.height - 5)/2, 5, 5); + } + + UIView *containerView = transitionContext.containerView; + [containerView addSubview:snapshotView]; + + self.fromVC.view.alpha = 0; + snapshotView.center = self.fromVC.view.center; + snapshotView.transform = CGAffineTransformMakeScale(scaleRatio, scaleRatio); + + NSTimeInterval duration = [self transitionDuration:transitionContext]; + [UIView animateWithDuration:duration +// delay:0 usingSpringWithDamping:0.8 initialSpringVelocity:0.2 options:UIViewAnimationOptionCurveEaseInOut + animations:^{ + snapshotView.transform = CGAffineTransformMakeScale(scaleRatio, scaleRatio); + snapshotView.frame = finalFrame; + snapshotView.alpha = 1; + } completion:^(BOOL finished) { + [transitionContext finishInteractiveTransition]; + [transitionContext completeTransition:!transitionContext.transitionWasCancelled]; + [snapshotView removeFromSuperview]; + snapshotView = nil; + [self.transition dismiss]; + }]; +} + +@end diff --git a/GKDYVideo/Classes/Tools/GKScaleTransition/GKScaleTransition.h b/GKDYVideo/Classes/Tools/GKScaleTransition/GKScaleTransition.h new file mode 100644 index 0000000..3e4de71 --- /dev/null +++ b/GKDYVideo/Classes/Tools/GKScaleTransition/GKScaleTransition.h @@ -0,0 +1,45 @@ +// +// GKScaleTransition.h +// GKDYVideo +// +// Created by QuintGao on 2024/9/12. +// Copyright © 2024 QuintGao. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@protocol GKScaleTransitionDelegate + +@optional + +/// 来源视图,用于显示及恢复 +@property (nonatomic, weak, nullable) UIView *sourceView; + +/// 横向滑动的scrollView,解决滑动冲突 +@property (nonatomic, weak, nullable) UIScrollView *horizontalScrollView; + +/// 滑动开始 +- (void)transitionPanBegan; + +/// 滑动改变 +- (void)transitionPanChange; + +/// 滑动结束 +- (void)transitionPanEnded:(BOOL)isDismiss; + +@end + +@interface GKScaleTransition : UIPercentDrivenInteractiveTransition + +@property (nonatomic, weak) id delegate; + ++ (void)connectToViewController:(UIViewController *)viewController; +- (void)connectToViewController:(UIViewController *)viewController; + +- (void)dismiss; + +@end + +NS_ASSUME_NONNULL_END diff --git a/GKDYVideo/Classes/Tools/GKScaleTransition/GKScaleTransition.m b/GKDYVideo/Classes/Tools/GKScaleTransition/GKScaleTransition.m new file mode 100644 index 0000000..249bc59 --- /dev/null +++ b/GKDYVideo/Classes/Tools/GKScaleTransition/GKScaleTransition.m @@ -0,0 +1,169 @@ +// +// GKScaleTransition.m +// GKDYVideo +// +// Created by QuintGao on 2024/9/12. +// Copyright © 2024 QuintGao. All rights reserved. +// + +#import "GKScaleTransition.h" +#import "GKScaleAnimation.h" + +static GKScaleTransition *_transition; + +@interface GKScaleTransition() + +@property (nonatomic, weak) UIViewController *presentVC; + +@property (nonatomic, assign) CGPoint viewCenter; + +@property (nonatomic, assign) BOOL interacting; + +@end + +@implementation GKScaleTransition + ++ (void)connectToViewController:(UIViewController *)viewController { + GKScaleTransition *transition = [[GKScaleTransition alloc] init]; + [transition connectToViewController:viewController]; + _transition = transition; +} + +- (void)connectToViewController:(UIViewController *)viewController { + self.presentVC = viewController; + + viewController.modalPresentationStyle = UIModalPresentationOverCurrentContext; + viewController.transitioningDelegate = self; + + // 添加手势 + UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; + pan.delegate = self; + [viewController.view addGestureRecognizer:pan]; +} + +- (void)dismiss { + _transition = nil; +} + +- (CGFloat)completionSpeed { + return 1 - self.percentComplete; +} + +- (UIScrollView *)scrollView { + if ([self.delegate respondsToSelector:@selector(horizontalScrollView)]) { + return self.delegate.horizontalScrollView; + } + return nil; +} + +#pragma mark - UIGestureRecognizerDelegate +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { + if (self.scrollView && self.scrollView.contentOffset.x > 0) { + return NO; + } + return YES; +} + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { + if ([otherGestureRecognizer isKindOfClass:NSClassFromString(@"UIScrollViewPanGestureRecognizer")] || [otherGestureRecognizer isKindOfClass:UIPanGestureRecognizer.class]) { + if (otherGestureRecognizer.view == self.scrollView) { + return YES; + } + } + return NO; +} + +#pragma mark - Handle Pan +- (void)handlePan:(UIPanGestureRecognizer *)pan { + CGPoint translation = [pan translationInView:pan.view.superview]; + if (!self.interacting && (translation.x < 0 || translation.y < 0 || translation.x < translation.y)) { + return; + } + switch (pan.state) { + case UIGestureRecognizerStateBegan: + [self handlePanBegan:pan]; + break; + case UIGestureRecognizerStateChanged: + [self handlePanChange:pan]; + break; + case UIGestureRecognizerStateCancelled: + case UIGestureRecognizerStateEnded: + [self handlePanEnded:pan]; + break; + default: + break; + } +} + +- (void)handlePanBegan:(UIPanGestureRecognizer *)pan { + // 修复当从右侧向左滑动时的bug,避免开始的时候从右向左滑动 + CGPoint vel = [pan velocityInView:pan.view]; + if (!self.interacting && vel.x < 0) { + self.interacting = NO; + return; + } + + self.interacting = YES; + self.viewCenter = self.presentVC.view.center; + if ([self.delegate respondsToSelector:@selector(transitionPanBegan)]) { + [self.delegate transitionPanBegan]; + } +} + +- (void)handlePanChange:(UIPanGestureRecognizer *)pan { + CGPoint translation = [pan translationInView:pan.view.superview]; + CGFloat progress = [self progressForPanGesture:pan]; + CGFloat ratio = 1 - progress * 0.5; + self.presentVC.view.center = CGPointMake(self.viewCenter.x + translation.x * ratio, self.viewCenter.y + translation.y * ratio); + self.presentVC.view.transform = CGAffineTransformMakeScale(ratio, ratio); + [self updateInteractiveTransition:progress]; + if ([self.delegate respondsToSelector:@selector(transitionPanChange)]) { + [self.delegate transitionPanChange]; + } +} + +- (void)handlePanEnded:(UIPanGestureRecognizer *)pan { + CGFloat progress = [self progressForPanGesture:pan]; + if (progress < 0.2) { + [UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ + self.presentVC.view.center = self.viewCenter; + self.presentVC.view.transform = CGAffineTransformIdentity; + } completion:^(BOOL finished) { + self.interacting = NO; + [self cancelInteractiveTransition]; + if ([self.delegate respondsToSelector:@selector(transitionPanEnded:)]) { + [self.delegate transitionPanEnded:NO]; + } + }]; + }else { + self.interacting = NO; + [self finishInteractiveTransition]; + [self.presentVC dismissViewControllerAnimated:YES completion:nil]; + if ([self.delegate respondsToSelector:@selector(transitionPanEnded:)]) { + [self.delegate transitionPanEnded:YES]; + } + } +} + +- (CGFloat)progressForPanGesture:(UIPanGestureRecognizer *)pan { + UIView *superview = pan.view.superview; + CGPoint translation = [pan translationInView:superview]; + CGFloat progress = translation.x / superview.bounds.size.width; + progress = fminf(fmaxf(progress, 0.0), 1.0); + return progress; +} + +#pragma mark - UIViewControllerTransitioningDelegate +- (id)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { + return [[GKScaleAnimation alloc] initWithType:GKScaleType_Present transition:self]; +} + +- (id)animationControllerForDismissedController:(UIViewController *)dismissed { + return [[GKScaleAnimation alloc] initWithType:GKScaleType_Dismiss transition:self]; +} + +- (id)interactionControllerForDismissal:(id)animator { + return self.interacting ? self : nil; +} + +@end diff --git a/GKDYVideo/Classes/Tools/GKSlidePopupView/GKSlidePopupView.h b/GKDYVideo/Classes/Tools/GKSlidePopupView/GKSlidePopupView.h deleted file mode 100644 index da72b36..0000000 --- a/GKDYVideo/Classes/Tools/GKSlidePopupView/GKSlidePopupView.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// GKSlidePopupView.h -// GKDYVideo -// -// Created by QuintGao on 2019/4/27. -// Copyright © 2019 QuintGao. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface GKSlidePopupView : UIView - -+ (instancetype)popupViewWithFrame:(CGRect)frame contentView:(UIView *)contentView; - -- (instancetype)initWithFrame:(CGRect)frame contentView:(UIView *)contentView; - -- (void)showFrom:(UIView *)fromView completion:(void (^)(void))completion; - -- (void)dismissCompletion:(nullable void(^)(void))completion; - -@end - -NS_ASSUME_NONNULL_END diff --git a/GKDYVideo/Classes/Tools/GKSlidePopupView/GKSlidePopupView.m b/GKDYVideo/Classes/Tools/GKSlidePopupView/GKSlidePopupView.m deleted file mode 100644 index aa9a27d..0000000 --- a/GKDYVideo/Classes/Tools/GKSlidePopupView/GKSlidePopupView.m +++ /dev/null @@ -1,191 +0,0 @@ -// -// GKSlidePopupView.m -// GKDYVideo -// -// Created by QuintGao on 2019/4/27. -// Copyright © 2019 QuintGao. All rights reserved. -// - -#import "GKSlidePopupView.h" - -@interface GKSlidePopupView() - -@property (nonatomic, weak) UIView *contentView; - -@property (nonatomic, strong) UITapGestureRecognizer *tapGesture; -@property (nonatomic, strong) UIPanGestureRecognizer *panGesture; - -@property (nonatomic, weak) UIScrollView *scrollView; -@property (nonatomic, assign) BOOL isDragScrollView; -@property (nonatomic, assign) CGFloat lastTransitionY; - -@end - -@implementation GKSlidePopupView - -+ (instancetype)popupViewWithFrame:(CGRect)frame contentView:(UIView *)contentView { - return [[GKSlidePopupView alloc] initWithFrame:frame contentView:contentView]; -} - -- (instancetype)initWithFrame:(CGRect)frame contentView:(UIView *)contentView { - if (self = [super initWithFrame:frame]) { - self.contentView = contentView; - - // 默认不展示内容视图 - CGRect contentFrame = contentView.frame; - contentFrame.origin.y = frame.size.height; - self.contentView.frame = contentFrame; - [self addSubview:self.contentView]; - - // 添加手势 - [self addGestureRecognizer:self.tapGesture]; - [self addGestureRecognizer:self.panGesture]; - } - return self; -} - -- (void)showFrom:(UIView *)fromView completion:(nonnull void (^)(void))completion { - [fromView addSubview:self]; - - [self showWithCompletion:completion]; -} - -- (void)showWithCompletion:(void (^)(void))completion { - [UIView animateWithDuration:0.25f animations:^{ - CGRect frame = self.contentView.frame; - frame.origin.y = self.frame.size.height - frame.size.height; - self.contentView.frame = frame; - } completion:^(BOOL finished) { - !completion ? : completion(); - }]; -} - -- (void)dismissCompletion:(void (^)(void))completion { - [UIView animateWithDuration:0.25f animations:^{ - CGRect frame = self.contentView.frame; - frame.origin.y = self.frame.size.height; - self.contentView.frame = frame; - }completion:^(BOOL finished) { - [self removeFromSuperview]; - !completion ?: completion(); - }]; -} - -#pragma mark - UIGestureRecognizerDelegate -- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { - if (gestureRecognizer == self.panGesture) { - UIView *touchView = touch.view; - while (touchView != nil) { - if ([touchView isKindOfClass:[UIScrollView class]]) { - self.scrollView = (UIScrollView *)touchView; - self.isDragScrollView = YES; - break; - }else if (touchView == self.contentView) { - self.isDragScrollView = NO; - break; - } - touchView = (UIView *)[touchView nextResponder]; - } - } - return YES; -} - -- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { - if (gestureRecognizer == self.tapGesture) { - CGPoint point = [gestureRecognizer locationInView:self.contentView]; - if ([self.contentView.layer containsPoint:point] && gestureRecognizer.view == self) { - return NO; - } - }else if (gestureRecognizer == self.panGesture) { - return YES; - } - return YES; -} - -// 是否与其他手势共存 -- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { - if (gestureRecognizer == self.panGesture) { - if ([otherGestureRecognizer isKindOfClass:NSClassFromString(@"UIScrollViewPanGestureRecognizer")] || [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) { - if ([otherGestureRecognizer.view isKindOfClass:[UIScrollView class]]) { - return YES; - } - } - } - return NO; -} - -#pragma mark - HandleGesture -- (void)handleTapGesture:(UITapGestureRecognizer *)tapGesture { - CGPoint point = [tapGesture locationInView:self.contentView]; - if (![self.contentView.layer containsPoint:point] && tapGesture.view == self) { - [self dismissCompletion:nil]; - } -} - -- (void)handlePanGesture:(UIPanGestureRecognizer *)panGesture { - CGPoint translation = [panGesture translationInView:panGesture.view]; - if (self.isDragScrollView) { - // 当UIScrollView在最顶部时,处理视图的滑动 - if (self.scrollView.contentOffset.y <= 0) { - if (translation.y > 0) { // 向下拖拽 - self.scrollView.contentOffset = CGPointZero; - self.scrollView.panGestureRecognizer.enabled = NO; - self.isDragScrollView = NO; - - CGRect contentFrame = self.contentView.frame; - contentFrame.origin.y += translation.y; - self.contentView.frame = contentFrame; - } - } - }else { - CGFloat contentM = (self.frame.size.height - self.contentView.frame.size.height); - - if (translation.y > 0) { // 向下拖拽 - CGRect contentFrame = self.contentView.frame; - contentFrame.origin.y += translation.y; - self.contentView.frame = contentFrame; - }else if (translation.y < 0 && self.contentView.frame.origin.y > contentM) { // 向上拖拽 - CGRect contentFrame = self.contentView.frame; - contentFrame.origin.y = MAX((self.contentView.frame.origin.y + translation.y), contentM); - self.contentView.frame = contentFrame; - } - NSLog(@"%f", translation.x); - } - - [panGesture setTranslation:CGPointZero inView:panGesture.view]; - - if (panGesture.state == UIGestureRecognizerStateEnded) { - CGPoint velocity = [panGesture velocityInView:panGesture.view]; - - self.scrollView.panGestureRecognizer.enabled = YES; - - // 结束时的速度>0 滑动距离> 5 且UIScrollView滑动到最顶部 - NSLog(@"%f", self.lastTransitionY); - if (velocity.y > 0 && self.lastTransitionY > 5 && !self.isDragScrollView) { - [self dismissCompletion:nil]; - }else { - [self showWithCompletion:nil]; - } - } - - self.lastTransitionY = translation.y; -} - -#pragma mark - 懒加载 -- (UITapGestureRecognizer *)tapGesture { - if (!_tapGesture) { - _tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)]; - _tapGesture.delegate = self; - } - return _tapGesture; -} - -- (UIPanGestureRecognizer *)panGesture { - if (!_panGesture) { - _panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)]; - _panGesture.delegate = self; - } - return _panGesture; -} - -@end diff --git a/Podfile b/Podfile index 174bc6c..bcd878c 100644 --- a/Podfile +++ b/Podfile @@ -14,6 +14,7 @@ target 'GKDYVideo' do pod 'GKVideoScrollView' pod 'GKPageSmoothView' pod 'GKSliderView' + pod 'GKPopupController' pod 'MJRefresh' pod 'JXCategoryView' pod 'ZFPlayer/AVPlayer'