项目需求---scrollview嵌套导致滚动卡顿问题

来源:互联网 时间:2017-01-22


更新

谢谢各位朋友帮我想主意。此项目需求解决方案总结如下:





tableview或者collection view通用办法,设置两个组。第一个组没有item或者cell,只有SectionHeader
(这里如果是collectionview并且iOS9以下想要达到tableviewSectionHeaderView那样的悬停效果需要自定义布局。如果是iOS9以上可以通过一下两个属性设置

 @property (nonatomic) BOOL sectionHeadersPinToVisibleBounds NS_AVAILABLE_IOS(9_0);
@property (nonatomic) BOOL sectionFootersPinToVisibleBounds NS_AVAILABLE_IOS(9_0);

)

2.如果是tableview,还可以同时设置headerView以及sectionHeaderView,因为sectionHeaderView在tableview是plain的方式下是悬停的,而headerView是不悬停的。


3.本文章所写的最土的方法




最近在做一个项目,首页是这样设计的



首页.jpg


问题背景

整体首页是一个scrollview。从上到下依次是banner,三个按钮,目录,collectionview


希望滚动时,目录滚动导航栏下方时可以悬停,只有collectionview继续滚动


思考方式

创建collectionview时设置scrollEnabled为No,在- (void)scrollViewDidScroll:(UIScrollView *)scrollView中根据contentOffset.y判断开启或关闭首页整体scrollviewcollectionviewscrollEnabled属性。


 - (void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (scrollView != _scrollview){//滚动的是 collectionview
if (scrollView.contentOffset.y <=0) {
_scrollView.scrollEnabled = NO;
}
}else{//滚动的主scrollview
CGFloat bottomOffset = _scrollview.contentSize.height - _scrollview.bounds.size.height ;
if ((int)scrollView.contentOffset.y > (int)(bottomOffset) + 45) {
[scrollView setContentOffset:CGPointMake(0, bottomOffset + 49) animated:NO];
_collectionview.scrollEnabled = YES;
}else {
[_collectionview setContentOffset:CGPointZero animated:NO];
_collectionview.scrollEnabled = NO;
}
}
}

问题

很快就引出来问题,因为两个scrollview嵌套,同一个手势不会同时控制两个scrollview。最明显的表现就是,手势拖动目录悬停在导航栏下面,但是collectionview无法继续滚动,也就是继续向下滚动无效。并且,如果通过collectionview向上滚动到顶部时scrollview无法继续滚动。也就是继续向上滚动无效。


我思考着因为这是同一个拖拽手势,因此手势对象不变的话,或许应该改变手势所被添加的view上面,这样就改变了手势所操作的view
因此,在- (void)scrollViewDidScroll:(UIScrollView *)scrollView判断中,将scrollEnabled的设置改成scrollview.panGestureRecognizer这一对象所操作的view的设置,于是尝试了以下代码


 [scrollView removeGestureRecognizer:scrollView.panGestureRecognizer];
[_collectionview addGestureRecognizer:scrollView.panGestureRecognizer];


但是完全没有效果。之后也尝试了设置panGestureRecognizer.Enable属性,效果与scrollEnabled的设置是一样的,会出现卡顿。
google了一番,也没有找到合适的结局办法。只能动用一些土法子了。

因为赶项目并且能力有限,实在没办法深入研究。心里总想着更改panGestureRecognizer某些设置可以达到效果。如果有哪位大神已经做到,还请告知,小弟感激不尽。



解决方法

直接设置collectionview不可以滚动,根据请求到得数据动态设置collection view的高度,以及scrollviewcontentSize属性。
但需求要求目录悬停,因此创建了两个目录,一个添加在scrollview的上面,一个添加在window上面。在- (void)scrollViewDidScroll:(UIScrollView *)scrollView判断,设置window上面的显示或隐藏。
这样确实完美解决了同一个手势滑动两个scrollview卡顿的问题。


引出问题


这个问题也是我不喜欢把东西加载window上面的原因。因为上面的解决方式,多创建了一个目录在window上。大家如果用UIAlertController会有这种体验(UIAlertView不会),AlertController与我们自己加在window上得view在同一个window上面,并且系统默认的阴影效果盖不住我们创建的view,这样也就不会影响view在有弹框时的操作。



已经结局了问题.png

解决方法

幸好controller的view是UIView,在view的基础上直接创建了一个目录添加view上面,使其覆盖scrollview。这样的思路,让我想起以前,在tableviewController上需要添加悬浮view也可以这样应用。
你若问为啥不用UIAlertView就不存在这种问题了。臣妾做不到啊。



问题虽然也解决了,但方法还有待优化。还是那句话,如有大神已经找到更好的解决方法,还请告知,小弟感激不尽。




相关阅读:
Top