美文网首页
iOS仿微博发现页实现

iOS仿微博发现页实现

作者: 左左4143 | 来源:发表于2019-06-17 13:52 被阅读0次

    某一天接到一个需求,要求做一个类似微博发现页的页面,需要支持上下滑动的同时可以左右滑动展示更多的内容,就像下图这样

    WX20190617-135231.png

    蓝框下方的部分可以左右滑动,蓝框以及蓝框上边的部分不可以左右滑,点击蓝框中的title蓝框下方会切换不同的页面,左右滑蓝框下方的页面蓝框里的title也会实时变化为高亮,往上滑的时候蓝框内的部分会吸顶

    大致的实现方法是用一个大的TableView实现,这个页面大概可以分为三部分


    WX20190617-135136.png
    • 第一部分是固定的,其实就是tableView的HeadView
    • 第二部分(暂且叫做categoryView) 其实是tableView的第一个section的headerView,内部有一个点击切换的效果
    • 第三部分是tableView的一个Cell,Cell内部是一个UICollectionView,可以左右滑动,滑动时与categoryView联动,collectionView的每一个cell是一个TableView,在categoryView吸顶的时候可以自由滑动

    难题一:当视图滑动一部分之后,手指在第三部分滑动的时候,会触发第三部分视图内的某个TableView的滑动,这时候外部的大的tableView就会失去滑动效果,想要滑动只能是滑动第三部分上方的视图。

    解决方案:将最外部的tableView变成新建的一个tableView类,(继承自UITableView)然后将它的- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer方法重写

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
        return [gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]];
    }
    

    这样可以保证你在滑动第三部分里的小的tableView时,外部的大的tableView依然可以滑动,但这时候这两种滑动会重叠,也就是说你滑动第三部分的tableView时,大的tableView也在滑动,我们要的效果是无论何时只有一个tableView在滑动,所以我们要实时监测这两个tableView的偏移量,当一个tableView滑动的时候让另一个tableView的contentOffset始终为0,造成一种不动的错觉,分两种情况:

    • 第二部分没有吸顶的时候,保持外部的大tableView滑动效果,小tableView虽然也可以滑动,但是要造成它不动的效果
    • 第二部分吸顶的时候,只让小的tableView滑动,外部的大tableView要造成不动的效果

    同时检测这两个tableView的代理方法- (void)scrollViewDidScroll:(UIScrollView *)scrollView,针对大的TableView:

        if (self.currentScrollingListView != nil && self.currentScrollingListView.contentOffset.y > 0) {
            //mainTableView的header已经滚动不见,开始滚动某一个listView,那么固定mainTableView的contentOffset,让其不动
            self.mainTableView.contentOffset = CGPointMake(0, [self.delegate tableHeaderViewHeightInPagerView:self]);
        }
    
        if (scrollView.contentOffset.y < [self.delegate tableHeaderViewHeightInPagerView:self]) {
            //mainTableView已经显示了header,listView的contentOffset需要重置
            NSArray *listViews = [self.delegate listViewsInPagerView:self];
            for (UIView <JXPagerViewListViewDelegate>* listView in listViews) {
                [listView listScrollView].contentOffset = CGPointZero;
            }
        }
    

    针对小的tableView

        if (self.mainTableView.contentOffset.y < [self.delegate tableHeaderViewHeightInPagerView:self]) {
            //mainTableView的header还没有消失,让listScrollView一直为0
            scrollView.contentOffset = CGPointZero;
            scrollView.showsVerticalScrollIndicator = NO;
        }else {
            //mainTableView的header刚好消失,固定mainTableView的位置,显示listScrollView的滚动条
            self.mainTableView.contentOffset = CGPointMake(0, [self.delegate tableHeaderViewHeightInPagerView:self]);
            scrollView.showsVerticalScrollIndicator = YES;
        }
    

    这样就可以实现一种自动吸顶同时又比较顺滑的滑动效果

    难题二: categoryView与第三部分多个View的联动效果

    categoryView的实现方式是用一个collectionView实现的,下方第三部分也是一个collectionView, 在封装第二部分视图的时候,里边有一个UIScrollview类型的属性,将第三部分的collectionView赋给这个属性,然后通过KVO监听第三部分collectionView的滑动,就可以将第二部分的collectionView的cell的点击事件和第三个collectionView的滑动关联起来

    [contentScrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
    
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
    {
        if ([keyPath isEqualToString:@"contentOffset"] && (self.contentScrollView.isTracking || self.contentScrollView.isDecelerating)) {
            //用户滚动引起的contentOffset变化,才处理。
            CGPoint contentOffset = [change[NSKeyValueChangeNewKey] CGPointValue];
            [self contentOffsetOfContentScrollViewDidChanged:contentOffset];
        }
    }
    

    这里只是记录了大体的思路,来理解这个效果是怎样实现的,其实还有很多需要注意的细节,源代码是两个第三方JXCategoryViewJXPagingView

    相关文章

      网友评论

          本文标题:iOS仿微博发现页实现

          本文链接:https://www.haomeiwen.com/subject/adrafctx.html