123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- //
- // HDMultipleScrollListView.m
- // HDCollectionView_Example
- //
- // Created by HaoDong chen on 2019/5/20.
- // Copyright © 2019 donggelaile. All rights reserved.
- //
- #import "HDMultipleScrollListView.h"
- #import "HDCollectionView+MultipleScroll.h"
- #import "HDMultipleScrollListSubVC.h"
- #import <objc/runtime.h>
- @implementation HDMultipleScrollListViewTitleHeader
- - (void)layoutSubviews
- {
- [super layoutSubviews];
- if (![self.subviews containsObject:[self rootView].jxTitle]) {
- [self insertSubview:self.rootView.jxTitle atIndex:0];
- }
- self.rootView.jxTitle.frame = self.bounds;
- }
- - (void)updateSecVUI:(__kindof HDSectionModel *)model
- {
-
- }
- - (HDMultipleScrollListView *)rootView
- {
- HDMultipleScrollListView *resultView;
- if (!resultView) {
- UIView *view = self;
- while (view!=nil && ![view isKindOfClass:NSClassFromString(@"HDMultipleScrollListView")]) {
- view = view.superview;
- }
- resultView = (HDMultipleScrollListView*)view;
- }
- return resultView;
- }
- @end
- @interface HDMultipleScrollListViewContentCell : HDCollectionCell
- @end
- @implementation HDMultipleScrollListViewContentCell
- - (void)updateCellUI:(__kindof HDCellModel *)model
- {
- [self.contentView.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
- [obj removeFromSuperview];
- }];
- HDMultipleScrollListSubVC <HDMultipleScrollListViewScrollViewDidScroll>*VC = model.orgData;
- __weak typeof(self) weakSelf = self;
- if ([VC isKindOfClass:[UIViewController class]] && [VC respondsToSelector:@selector(HDMultipleScrollListViewScrollViewDidScroll:)]) {
- [VC HDMultipleScrollListViewScrollViewDidScroll:^(UIScrollView * _Nonnull sc) {
- if ([sc isKindOfClass:[UIScrollView class]]) {
- [weakSelf hd_setSubScrollViewDidScrollCallback:sc];
- }
- }];
- VC.view.frame = self.bounds;
- [self.contentView addSubview:VC.view];
- }
- if ([VC isKindOfClass:[HDMultipleScrollListSubVC class]]) {
- //监听主HDCollectionView的滑动回调
- HDMultipleScrollListView *rootView = [self rootView];
- [rootView.mainCollecitonV hd_autoDealScrollViewDidScrollEvent:self.superCollectionV topH:[self topH]];
- }
- }
- - (void)hd_setSubScrollViewDidScrollCallback:(UIScrollView *)sc
- {
- UIScrollView *mainRealSc = [self mainScrollV];
- HDCollectionView *mainHDCV = [self rootView].mainCollecitonV;
- [mainHDCV setCurrentSubSc:sc];
- CGFloat topH = [self topH];
-
- if (mainRealSc.contentOffset.y < topH) {
- sc.contentOffset = CGPointMake(0, -sc.contentInset.top);
- }else{
- mainRealSc.contentOffset = CGPointMake(mainRealSc.contentOffset.x, topH);
- }
- }
- - (UIScrollView*)mainScrollV
- {
- HDMultipleScrollListView *rootView = [self rootView];
- UIScrollView *mainRealSc = rootView.mainCollecitonV.collectionV;
- return mainRealSc;
- }
- - (CGFloat)topH
- {
- HDMultipleScrollListView *rootView = [self rootView];
- NSIndexPath *titleHeaderIndexP = [NSIndexPath indexPathWithIndex:rootView.confingers.topSecArr.count];
- UICollectionViewLayoutAttributes*titleHeaderAtt = [rootView.mainCollecitonV.collectionV layoutAttributesForSupplementaryElementOfKind:UICollectionElementKindSectionHeader atIndexPath:titleHeaderIndexP];
- CGFloat titleHeaderY = titleHeaderAtt.frame.origin.y;
- UIScrollView *mainRealSc = rootView.mainCollecitonV.collectionV;
-
- CGFloat topH = [self convertRect:self.frame toView:mainRealSc].origin.y;
- if (rootView.confingers.isHeaderNeedStop) {
- topH = titleHeaderY;
- }
- return topH;
- }
- - (HDMultipleScrollListView*)rootView
- {
- HDMultipleScrollListView *resultView;
- if (!resultView) {
- UIView *view = self;
- while (view!=nil && ![view isKindOfClass:NSClassFromString(@"HDMultipleScrollListView")]) {
- view = view.superview;
- }
- resultView = (HDMultipleScrollListView*)view;
- }
- return resultView;
- }
- @end
- @interface HDMultipleScrollListViewContentHeader:HDSectionView
- @property (nonatomic, strong) HDCollectionView *contentCV;
- @end
- @implementation HDMultipleScrollListViewContentHeader
- - (instancetype)initWithFrame:(CGRect)frame
- {
- self = [super initWithFrame:frame];
- if (self) {
- self.contentCV = [HDCollectionView hd_makeHDCollectionView:^(HDCollectionViewMaker *maker) {
- maker
- .hd_scrollDirection(UICollectionViewScrollDirectionHorizontal)
- .hd_isCalculateCellHOnCommonModes(YES);
- }];
- self.contentCV.collectionV.pagingEnabled = YES;
- self.contentCV.collectionV.bounces = NO;
- if (@available(iOS 11.0, *)) {
- _contentCV.collectionV.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
- } else {
- // Fallback on earlier versions
- }
- [self addSubview:self.contentCV];
- }
- __hd_WeakSelf
- [self.contentCV hd_setShouldRecognizeSimultaneouslyWithGestureRecognizer:^BOOL(UIGestureRecognizer *selfGestture, UIGestureRecognizer *otherGesture) {
- return [weakSelf dealFullScrrenBackGesture:otherGesture];
- }];
- return self;
- }
- - (BOOL)dealFullScrrenBackGesture:(UIGestureRecognizer*)otherGes
- {
- BOOL isRes = NO;
- NSInteger curPage = self.contentCV.collectionV.contentOffset.x/self.contentCV.frame.size.width;
- if (curPage == 0) {
- if ([otherGes isKindOfClass:[UIPanGestureRecognizer class]] &&
- [otherGes.view isKindOfClass:NSClassFromString(@"UILayoutContainerView")]) {
- isRes = YES;
- }
- }
- return isRes;
- }
- - (void)updateSecVUI:(__kindof HDSectionModel *)model
- {
- HDSectionModel *firstSec = [self.contentCV.innerAllData firstObject];
- if (!firstSec.sectionDataArr.count) {
- [self.contentCV hd_setAllDataArr:model.headerObj];
- }
- [self rootView].jxTitle.contentScrollView = self.contentCV.collectionV;
- }
- - (HDMultipleScrollListView*)rootView
- {
- HDMultipleScrollListView *resultView;
- if (!resultView) {
- UIView *view = self;
- while (view!=nil && ![view isKindOfClass:NSClassFromString(@"HDMultipleScrollListView")]) {
- view = view.superview;
- }
- resultView = (HDMultipleScrollListView*)view;
- }
- return resultView;
- }
- - (void)layoutSubviews
- {
- [super layoutSubviews];
- self.contentCV.frame = self.bounds;
- }
- @end
- #pragma mark - configer
- @implementation HDMultipleScrollListConfiger
- @end
- @interface HDMultipleScrollListView()
- {
- void(^configFinishGlobal)(HDMultipleScrollListConfiger*);
- }
- @property (nonatomic, strong) NSMutableArray *finalSecArr;
- @end
- #pragma mark - HDMultipleScrollListView
- @implementation HDMultipleScrollListView
- {
- CGRect lastViewFrame;
- }
- @synthesize mainCollecitonV = _mainCollecitonV,jxTitle = _jxTitle, jxLineView = _jxLineView, confingers = _confingers;
- - (instancetype)init
- {
- self = [super init];
- if (self) {
- }
- lastViewFrame = CGRectZero;
- return self;
- }
- - (instancetype)initWithFrame:(CGRect)frame
- {
- self = [super initWithFrame:frame];
- if (self) {
- }
- lastViewFrame = CGRectZero;
- return self;
- }
- - (NSMutableArray *)finalSecArr
- {
- if (!_finalSecArr) {
- _finalSecArr = @[].mutableCopy;
- }
- return _finalSecArr;
- }
- - (JXCategoryTitleView *)jxTitle
- {
- if (!_jxTitle) {
- _jxTitle = [[JXCategoryTitleView alloc] init];
- _jxTitle.indicators = @[self.jxLineView];
- _jxTitle.backgroundColor = [UIColor whiteColor];
- }
- return _jxTitle;
- }
- - (JXCategoryIndicatorLineView *)jxLineView
- {
- if (!_jxLineView) {
- _jxLineView = [[JXCategoryIndicatorLineView alloc] init];
- _jxLineView.indicatorHeight = 2;
- _jxLineView.indicatorCornerRadius = JXCategoryViewAutomaticDimension;
- }
- return _jxLineView;
- }
- - (HDCollectionView *)mainCollecitonV
- {
- if (!_mainCollecitonV) {
- _mainCollecitonV = [HDCollectionView hd_makeHDCollectionView:^(HDCollectionViewMaker *maker) {
- maker.hd_isNeedTopStop(YES)
- .hd_isCalculateCellHOnCommonModes(YES);
- }];
- // _mainCollecitonV.collectionV.bounces = NO;
- _mainCollecitonV.collectionV.showsVerticalScrollIndicator = NO;
- _mainCollecitonV.collectionV.showsHorizontalScrollIndicator = NO;
- if (@available(iOS 11.0, *)) {
- _mainCollecitonV.collectionV.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
- } else {
- // Fallback on earlier versions
- }
- //让主滑动view contentSize不至于过小,从而存在一个滑动惯性。
- //这样可以使顶部高度过低时,从底部滑动到顶部时不卡顿
- _mainCollecitonV.collectionV.contentInset = UIEdgeInsetsMake(HDMainDefaultTopEdge, 0, 0, 0);
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- self->_mainCollecitonV.collectionV.contentOffset=CGPointZero;
- });
-
- //初始化时仅保证大于0
- [_mainCollecitonV hd_setScrollViewDidScrollCallback:^(UIScrollView *scrollView) {
- if (scrollView.contentOffset.y<0) {
- scrollView.contentOffset = CGPointZero;
- }
- }];
- }
- [self addSubview:_mainCollecitonV];
- _mainCollecitonV.collectionV.bounces = NO;
- return _mainCollecitonV;
- }
- - (void)layoutSubviews
- {
- [super layoutSubviews];
- self.mainCollecitonV.frame = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, self.bounds.size.width, self.bounds.size.height);
- if (!CGRectEqualToRect(lastViewFrame, self.frame)) {
- [self updateData];
- }
- lastViewFrame = self.frame;
- }
- - (void)configWithConfiger:(void (^)(HDMultipleScrollListConfiger * _Nonnull configer))config
- {
- HDMultipleScrollListConfiger *configer = [HDMultipleScrollListConfiger new];
- if (config) {
- config(configer);
- }
- _confingers = configer;
- self.jxTitle.titles = configer.titles;
- if (configFinishGlobal) {
- configFinishGlobal(configer);
- }
-
- [self updateData];
- }
- - (void)configFinishCallback:(void (^)(HDMultipleScrollListConfiger * _Nonnull))configFinish
- {
- if (configFinish) {
- configFinishGlobal = configFinish;
- }
- }
- - (void)updateData
- {
- if (self.confingers.controllers.count != self.confingers.titles.count) {
- return;
- }
- self.finalSecArr = @[].mutableCopy;
- [self.finalSecArr addObjectsFromArray:self.confingers.topSecArr];
- if (self.confingers.controllers && self.confingers.controllers.count > 0) {
- [self addMiddleData];
- }
- [self.finalSecArr addObjectsFromArray:self.confingers.bottomSecArr];
- [self.mainCollecitonV hd_setAllDataArr:self.finalSecArr];
- }
- - (void)addMiddleData
- {
- [self.finalSecArr addObject:[self HDMultipleScrollListViewTitleHeaderSec]];
- [self.finalSecArr addObject:[self HDMultipleScrollListViewContentHeaderSec]];
- }
- - (HDSectionModel*)HDMultipleScrollListViewTitleHeaderSec
- {
- NSString *clsStr = @"HDMultipleScrollListViewTitleHeader";
- if (self.confingers.diyHeaderClsStr) {
- Class cls = NSClassFromString(self.confingers.diyHeaderClsStr);
- if ([cls isKindOfClass:object_getClass(NSClassFromString(clsStr))]) {
- clsStr = self.confingers.diyHeaderClsStr;
- }
- }
- HDSectionModel *titleSec = [self normalSecWithCellModelArr:nil headerSize:self.confingers.titleContentSize headerClsStr:clsStr autoCountCellH:NO];
- titleSec.headerObj = self.confingers.titles;;
- titleSec.headerTopStopType = self.confingers.isHeaderNeedStop?HDHeaderStopOnTopTypeNormal:HDHeaderStopOnTopTypeNone;
- return titleSec;
- }
- - (HDSectionModel*)HDMultipleScrollListViewContentHeaderSec
- {
- HDSectionModel *secModel = [self normalSecWithCellModelArr:@[].mutableCopy headerSize:[self realContentSize] headerClsStr:@"HDMultipleScrollListViewContentHeader" autoCountCellH:NO];
- secModel.headerObj = @[[self realContentSec]];
- secModel.headerTopStopType = HDHeaderStopOnTopTypeNormal;
-
- return secModel;
- }
- - (HDSectionModel *)realContentSec
- {
- //该段cell数据源
- static NSInteger index = 0;
- NSMutableArray *cellModelArr = @[].mutableCopy;
- NSInteger cellCount = self.confingers.controllers.count;
-
- for (int i =0; i<cellCount; i++) {
- UIViewController *vc = self.confingers.controllers[i];
- HDCellModel *model = [HDCellModel new];
- model.orgData = vc;
- model.cellSize = [self realContentSize];
- model.cellClassStr = @"HDMultipleScrollListViewContentCell";
- model.reuseIdentifier = [NSString stringWithFormat:@"HDMultipleScrollListViewContentCell_%zd",index];
- [cellModelArr addObject:model];
- index ++;
- }
-
- //该段layout
- HDYogaFlowLayout *layout = [HDYogaFlowLayout new];//isUseSystemFlowLayout为YES时只支持HDBaseLayout
-
- //该段的所有数据封装
- HDSectionModel *secModel = [HDSectionModel new];
- secModel.sectionDataArr = cellModelArr;
- secModel.layout = layout;
- return secModel;
- }
- - (CGSize)realContentSize {
- if (self.confingers.controllers && self.confingers.controllers.count > 0) {
- if (self.confingers.isHeaderNeedStop) {
- if (self.confingers.listHeight) {
- return CGSizeMake(self.mainCollecitonV.frame.size.width, self.confingers.listHeight);
- }else {
- return CGSizeMake(self.mainCollecitonV.frame.size.width, self.mainCollecitonV.frame.size.height - self.confingers.titleContentSize.height);
- }
- }else{
- return self.mainCollecitonV.frame.size;
- }
- }else {
- return CGSizeMake(self.mainCollecitonV.frame.size.width, 0);
- }
- }
- - (HDSectionModel*)normalSecWithCellModelArr:(NSArray*)cellModelArr headerSize:(CGSize)headerSize headerClsStr:(NSString*)headerClsStr autoCountCellH:(BOOL)autoCountCellH
- {
- //该段layout
- HDYogaFlowLayout *layout = [HDYogaFlowLayout new];//isUseSystemFlowLayout为YES时只支持HDBaseLayout
- layout.justify = YGJustifySpaceBetween;
- layout.headerSize = headerSize;
-
- //该段的所有数据封装
- HDSectionModel *secModel = [HDSectionModel new];
- secModel.sectionHeaderClassStr = headerClsStr;
- secModel.isNeedAutoCountCellHW = autoCountCellH;
- secModel.sectionDataArr = cellModelArr.mutableCopy;
- secModel.layout = layout;
- return secModel;
- }
- - (void)dealloc
- {
-
- }
- @end
|