想了解更丰富的个人主页效果或有疑问,请点击参看JXPagingView库
JXCategoryListContainerType_ScrollView
表示内部创建了UIScrollView
来当做列表视图的容器,所有的列表返回的listView
会被addSubview到UIScrollView
。
JXCategoryListContainerType_CollectionView
表示内部创建了UICollectionView
来当做列表视图的容器,所有的列表返回的listView
会被addSubview到UICollectionView
的UICollectionVeiwCell
上面。
- 优势:因为列表视图被添加到
UICollectionVeiwCell
上面,所以受到cell重用机制的影响,未显示的列表不会出现在视图层级里面。视图的内存占用会相对小一些。 - 劣势:真是因为
UICollectionVeiwCell
的重用机制,会有一些副作用,下面是已知的一个问题:
//因为`JXCategoryListContainerView`内部通过`UICollectionView`的cell加载列表。当切换tab的时候,之前的列表所在的cell就被回收到缓存池,就会从视图层级树里面被剔除掉,即没有显示出来且不在视图层级里面。这个时候MJRefreshHeader所持有的UIActivityIndicatorView就会被设置hidden。所以需要在列表显示的时候,且isRefreshing==YES的时候,再让UIActivityIndicatorView重新开启动画。
if (self.tableView.mj_header.isRefreshing) {
UIActivityIndicatorView *activity = [self.tableView.mj_header valueForKey:@"loadingView"];
[activity startAnimating];
}
- 优势:没有副作用
- 劣势:视图内存占用对多一点。
基于此:默认推荐使用JXCategoryListContainerType_ScrollView
。如果你的列表视图都比较复杂,内存占用比较大的情况,才推荐使用JXCategoryListContainerType_CollectionView
。具体的内存对比,你可以自己针对相同的页面对比使用,查看XCode的内存使用统计就可以知道了。
因为列表容器可以左右滑动,如果要开启左滑删除,这个时候系统会响应列表容器的左右滑动,而不是列表cell的左滑删除。所以,建议的方案是禁止列表容器滑动,这样就可以响应列表的左滑删除了。 列表容器滑动禁止,使用下面的代码:
self.listContainerView.scrollView.scrollEnabled = NO;
FDFullscreenPopGesture
等全屏手势处理文档地址
初始化过后,有新的数据源、属性配置有变动时(比如从服务器拉取回来数据,重新赋值titles),需要调用reloadData
方法刷新状态。
reloadDataWithoutListContainer
与reloadData
相比,只是reloadDataWithoutListContainer
方法内部没有调用[self.listContainer reloadData];
方法。用于只是想刷新JXCategoryView
的UI的情况,比如刷新cell上的数字、红点等,而不需要刷新列表容器。
JXCategoryView没有与listContainer或contentScrollView强关联,你甚至可以不设置这个属性,把JXCategoryView
当做简单的SegmentedControl。他们之间布局没有任何要求,可以把JXCategoryView放入导航栏、UITableViewSectionHeader等任何你想要的地方。
系统内部通过代码[self.contentScrollView setContentOffset:CGPointMake(targetIndex*self.contentScrollView.bounds.size.width, 0) animated:self.isContentScrollViewClickTransitionAnimationEnabled];
实现切换。
设置contentScrollViewClickTransitionAnimationEnabled
属性即可控制是否animated
如果你的列表是UIViewController
类,直接使用self.navigationController
即可。
如果你的列表是UIView
类,就需要给列表新增一个属性:@property (nonatomic, strong) UINavigationController *naviController
,然后将父VC的navigationController赋值给它。这样列表的cell点击就可以通过自定义的naviController
属性进行跳转了。详情参考源码LoadDataListBaseViewController
如果你的列表是UIViewController
类,直接使用self.navigationController
来present即可。
如果列表是视图,就参考上面【列表cell点击跳转示例】示例,需要传递UINavigationController
给列表的naviController
属性,然后用naviController
调用presentViewController
。
当业务需要某个时刻要跳转到指定index,比如当前index=0,用户点击了某个按钮,需要立即跳转到index=3的位置,使用下列代码即可:
[self.categoryView selectItemAtIndex:3];
高度取整代码:
- (void)layoutSubviews {
[super layoutSubviews];
self.collectionView.frame = CGRectMake(0, 0, self.bounds.size.width, floor(self.bounds.size.height));
}
部分使用者为了适配不同的手机屏幕尺寸,JXCategoryView的宽高比要求保持一样。所以它的高度就会因为不同宽度的屏幕而不一样。计算出来的高度,有时候会是位数很长的浮点数,如果把这个高度设置给UICollectionView就会触发内部的一个错误。所以,为了规避这个问题,在这里对高度统一向下取整。 如果向下取整导致了你的页面异常,请自己重新设置JXCategoryView的高度,保证为整数即可。
因为JXCategoryView内部使用了UICollectionView,在某些系统会对内部的UICollectionView进行错误的调整。所以,内部会自己找到父VC,然后将其automaticallyAdjustsScrollViewInsets属性设置为NO。
- (void)willMoveToSuperview:(UIView *)newSuperview {
[super willMoveToSuperview:newSuperview];
UIResponder *next = newSuperview;
while (next != nil) {
if ([next isKindOfClass:[UIViewController class]]) {
((UIViewController *)next).automaticallyAdjustsScrollViewInsets = NO;
break;
}
next = next.nextResponder;
}
}
通过设置JXCategoryTitleView
的titleNumberOfLines
属性为指定行数,比如2就是显示两行。但是因为内部实现原理限制,目前暂不支持自动换行,需要自己插入\n换行符。详情请参考【多行文本】使用示例。
容器VC创建代码如下:
_containerVC = [[JXCategoryListContainerViewController alloc] init];
self.containerVC.view.backgroundColor = [UIColor clearColor];
[self addSubview:self.containerVC.view];
然后作为列表视图容器的UIScrollView添加到containerVC.view,代码如下:
[self.containerVC.view addSubview:self.scrollView];
containerVC通过如下代码被parent Conttroller调用addChildViewController:
- (void)willMoveToSuperview:(UIView *)newSuperview {
[super willMoveToSuperview:newSuperview];
UIResponder *next = newSuperview;
while (next != nil) {
if ([next isKindOfClass:[UIViewController class]]) {
[((UIViewController *)next) addChildViewController:self.containerVC];
break;
}
next = next.nextResponder;
}
}
然后当列表是UIViewController类的时候,被添加到列表容器视图,会自动调用addChildViewController
方法,这样列表VC的生命周期方法就可以完美触发了。
list = [self.delegate listContainerView:self initListForIndex:index];
if ([list isKindOfClass:[UIViewController class]]) {
[self.containerVC addChildViewController:(UIViewController *)list];
}
所以,如果你的界面有任何异常情况,请注意JXCategoryListContainerView
整个视图层级,是否跟这个有关系。
添加如下代码即可:
self.listContainerView.scrollView.scrollEnabled = NO;
调用- (void)reloadCellAtIndex:(NSInteger)index;
方法刷新指定index。
某些情况需要刷新某一个cell的UI显示,比如红点示例里面。
目前指示器的过渡效果分为:跟随列表滚动、点击item过渡两种。它们分开处理,如果你希望点击item时和跟随列表滚动效果一致,请参考如下代码:
indicatorLineView.scrollStyle = JXCategoryIndicatorScrollStyleSameAsUserScroll;
目前仅支持JXCategoryIndicatorLineView
、JXCategoryIndicatorDotLineView
类。如果是自定义的指示器请参考它们的处理方式支持该效果,其实就是通过动画的方式模拟跟随列表滚动的效果。
JXCategoryView
即使提供了灵活扩展,也不可能满足所有情况。未能满足特殊需求的情况,建议通过fork仓库,实现特殊效果。