欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS中UIScrollView嵌套UITableView的实践教程

程序员文章站 2024-02-13 08:55:58
前言 最近因为工作项目中需要用到uiscrollview嵌套uitableview嵌套交互问题,顺便网上搜了下的demo,发现实现的效果并不是很理想,滑动偶尔会有延迟现象...

前言

最近因为工作项目中需要用到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中代码如下:

#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];
 }
}
#pragma mark - 底部的scrollviuew的代理方法scrollviewdidenddecelerating

- (void)scrollviewdidenddecelerating:(uiscrollview *)scrollview
{ 
 nsinteger index = ceilf(scrollview.contentoffset.x / kscreen_width);
 self.topview.selecteditemindex = index;
}

controller中view的代码如下

#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];
 }
}
#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;
  }
 }
}
#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;
 }
}
#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://xiazai.jb51.net/201705/yuanma/nestscrollview(jb51.net).rar

总结

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