iOS中UIScrollView嵌套UITableView的实践教程

时间:2022-09-19 16:48:48

前言

最近因为工作项目中需要用到uiscrollview嵌套uitableview嵌套交互问题,顺便网上搜了下的demo,发现实现的效果并不是很理想,滑动偶尔会有延迟现象,所以自己想了个办法,顺便把自己实现写了个demo分享出来,一起来看看吧。

iOS中UIScrollView嵌套UITableView的实践教程

实现过程

最底部放置的为一个uiscrollview,设置scrollview的contentsize属性,使可以发生横向滚动,同时隐藏横向滚动条,设置代理为当前控制器本身。然后,在最底部的uiscrollview上放置2个uitableview,因为只有2个所以没有考虑重用问题,如果数量大于3个建议写下uiscrollview子视图的重用。最后在最上面覆盖一个topview,使得它可以和tableview发生纵向滚动,为了实现最上面的topview可以随着tableview发生一起滚动,需要在tableview的scrollviewdidscroll代理方法中获取tableview的contentoffset偏移量,随便改变topview的frame。

当手势点开始落在从topview上时候,在controller的loadview方法中设置自定义view,通过在自定义view中重载hittest方法,判断是否需要让tableview进行交互。此时需要注意的是因为有自定义的左右选择segmentcontrol,这么设置的时候segmentcontroller是不会相应点击方法的。为了让segmentcontroller可以实现随着tableview滚动并且可以相应单击事件,我在在controller的view上添加了单击手势,判定是否点击在了自定义的segmentcontroll上(因为tableview本身不会相应- (void)touchesbegan:(nsset<uitouch *> )touches withevent:(uievent )event事件,所以也可以自定义一个tablevuew,重载touchbegin 等方法,然后把tableview继承自这个tableview, 这样就可以相应相应的touchbegin等方法了), 好了,下面直接上代码

controller中代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#pragma mark - 底部的scrollviuew的代理方法scrollviewdidscroll
 
- (void)scrollviewdidscroll:(uiscrollview *)scrollview
{
 cgfloat placeholderoffset = 0;
 if (self.topview.getselecteditemindex == 0) {
  if (self.firsttableview.contentoffset.y > self.topview.height - kitemheight) {
   placeholderoffset = self.topview.height - kitemheight;
  }
  else {
   placeholderoffset = self.firsttableview.contentoffset.y;
  }
  [self.secondtableview setcontentoffset:cgpointmake(0, placeholderoffset) animated:no];
 }
 else {
  if (self.secondtableview.contentoffset.y > self.topview.height - kitemheight) {
   placeholderoffset = self.topview.height - kitemheight;
  }
  else {
   placeholderoffset = self.secondtableview.contentoffset.y;
  }
  [self.firsttableview setcontentoffset:cgpointmake(0, placeholderoffset) animated:no];
 }
}
?
1
2
3
4
5
6
7
#pragma mark - 底部的scrollviuew的代理方法scrollviewdidenddecelerating
 
- (void)scrollviewdidenddecelerating:(uiscrollview *)scrollview
{
 nsinteger index = ceilf(scrollview.contentoffset.x / kscreen_width);
 self.topview.selecteditemindex = index;
}

controller中view的代码如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#pragma mark - 重载系统的hittest方法
 
- (uiview *)hittest:(cgpoint)point withevent:(uievent *)event
{
 viewcontroller *currentvc = (viewcontroller *)self.nextresponder;
 currentvc.printpoint = point;
 if ([self.topview pointinside:point withevent:event]) {
  self.scrollview.scrollenabled = no;
  if (self.scrollview.contentoffset.x < kscreen_width *0.5) {
   return self.firsttableview;
  } else {
   return self.secondtableview;
  }
 } else {
  self.scrollview.scrollenabled = yes;
  return [super hittest:point withevent:event];
 }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#pragma mark - 添加手势的相应方法
 
- (void)tapgestureaction:(uitapgesturerecognizer *)gesture
{
 cgpoint point = [gesture locationinview:self.topview];
 if (cgrectcontainspoint(self.topview.leftbtnframe, point)) {
  if (self.scrollview.contentoffset.x > 0.5 * kscreen_width) {
   [self.scrollview setcontentoffset:cgpointmake(0, 0) animated:no];
   self.topview.selecteditemindex = 0;
  }
 } else if (cgrectcontainspoint(self.topview.rightbtnframe, point)) {
  if (self.scrollview.contentoffset.x < 0.5 * kscreen_width) {
   [self.scrollview setcontentoffset:cgpointmake(kscreen_width, 0) animated:no];
   self.topview.selecteditemindex = 1;
  }
 }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#pragma mark - firsttableview的代理方法scrollviewdidscroll
 
- (void)scrollviewdidscroll:(uiscrollview *)scrollview
{
 cgfloat placeholderheight = self.topview.height - self.topview.itemheight;
 
 cgfloat offsety = scrollview.contentoffset.y;
 
 if (offsety >= 0 && offsety <= placeholderheight) {
  self.topview.y = -offsety;
 }
 else if (offsety > placeholderheight) {
  self.topview.y = - placeholderheight;
 }
 else if (offsety <0) {
  self.topview.y = - offsety;
 }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#pragma mark - secondtableview的代理方法scrollviewdidscroll
 
- (void)scrollviewdidscroll:(uiscrollview *)scrollview
{
 cgfloat placeholderheight = self.topview.height - self.topview.itemheight;
 cgfloat offsety = scrollview.contentoffset.y;
 if (offsety >= 0 && offsety <= placeholderheight) {
  self.topview.y = -offsety;
 } else if (offsety > placeholderheight) {
  self.topview.y = - placeholderheight;
 } else if (offsety <0) {
  self.topview.y = - offsety;
 }
}

完整项目下载地址如下:https://github.com/maxzhang123/nestscrollview

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。

原文链接:http://www.jianshu.com/p/c51665f7f48b