2016-03-05 65 views
1

我有一个UITableViewUITableViewController,我在我的应用程序中使用多个屏幕。堆栈两个UITableViews

我最近与我的组织的产品团队交谈过,他们要求对于其中一个屏幕,我预留了大约15个单元,其外观和功能差别很大

围绕谷歌搜索后,似乎要做到这一点的唯一方法是对每个实施UITableViewDelegate法类似复杂:

if section == 0 { 
    ... 
} 
if section == 1 { 
    ... 
} 

我并不想这样做,因为其他的屏幕,显示这张表,不需要这个逻辑,突然重复使用变得更加复杂。

理想情况下,我想要的是垂直堆叠两个表视图,这样一个附加到另一个的底部。

我的架构出了什么问题,还是在IOS中没有好的方法?

+0

Subclass current one then put these code in? –

回答

0

@Fennelouski,非常感谢你对你的提示,我居然结束了你的不推荐的第4个选项会:

放入容器视图

主要的原因既表视图我朝这个方向前进是因为在过去,当试图将滚动视图放入其他滚动视图时,我发现了有关弹跳的意外行为。即使我在嵌套滚动视图上将bounces设置为false,我发现当使用嵌套滚动视图开始拖动时,父滚动视图不会在其内容结束时移动。

我的解决方案并没有太糟糕(部分原因是我的应用程序是用我设计的框架构建的,它允许漂亮的事件发生)。我会在这里概括它:

  1. 两个表,firstsecond添加到一个UIView,container由一个UIViewController,controller控制。
  2. 将两个表的大小设置为container的大小。
  3. 设置first.contentInset.bottomsecond.contentSize.height并设置second.contentInset.top等于first.contentSize.height(这是一定要做,以允许轻弹一个表够硬,打其他表的末尾..而且必须再次随时随地做任何的改变表高度)
  4. 设置second.backgroundColorclear
  5. 定义second的则hitTest方法pointInside:withEvent:return point.y > 0(做到这一点,所以在上面second空白处的触摸事件将转化到first
  6. 当任一表的委托方法调用,存储哪个表开始拖动(我用了一个名为last_dragged的属性)。
  7. 当任一表的委托方法scrollViewDidScroll:被调用时,定位表不是last_dragged基于该表的偏移last_dragged

这是我使用的代码对于controller(这是的,是写在红宝石,但希望你可以阅读它作为sudo代码)

def load_view 
    content.add_subview first, size: content.size 
    content.add_subview second, size: content.size 
    set_content_offsets 
    listen_for_events 
    set_second_y 
end 

def set_content_offsets 
    first.content_inset_bottom = second.content_size_height 
    second.content_inset_top = first.content_size_height 
end 

def listen_for_events 
    listen_to_first 
    listen_to_second 
end 

def listen_to_first 
    first.on('refresh', method(:set_content_offsets)) 
    first.on('begin_drag', method(:second_dragged)) 
    first.on('scroll', method(:scroll)) 
end 

def listen_to_second 
    second.on('refresh', method(:set_content_offsets)) 
    second.on('begin_drag', method(:second_dragged)) 
    second.on('scroll', method(:scroll)) 
end 

def first_dragged 
    @last_dragged = :first 
end 

def second_dragged 
    @last_dragged = :second 
end 

def scroll 
    if @last_dragged == :first 
    set_second_y 
    else 
    set_first_y 
    end 
end 

def set_first_y 
    first.content_offset_y = 
    first.content_size_height + 
    second.content_offset_y 
end 

def set_second_y 
    second.content_offset_y = 
    first.content_offset_y - 
    first.content_size_height 
end 
3

我不得不做类似的事情了几个不同的时代,这里是我剩下什么:

  1. 添加基于部分特殊情况。令人惊讶的是,我发现这是最容易阅读和维护的。只需使用静态和清除变量名称而不是if (section == 0)

  2. 为行0创建一个包含表视图的特殊单元格。这不是最简单的事情,但它可以很好地工作,以便能够将代码分解为多个文件,这些文件通常更适合维护。当你对委托方法进行排序时,这确实会变成一件痛苦的事情,但一旦解决了,那么它就是一个非常动态的解决方案。

  3. 如果您没有使用标题,那么请执行与#2相同的操作,但对您的特例使用标题。当规范发生变化时,这可以很好地工作(如果可用),因为您可以将视图放在不同的页眉或页脚中。

  4. 将两个表视图放在某种容器视图中。我试过这个,它不漂亮。我不推荐。

  5. 将这两个表添加到另一个表中。这可以用来分配细胞来自哪里。这样做,您可以继承UITableView,并创建一个标志将特殊表添加到表中。这不仅仅是一个建议和一个起点的解决方案。

无论您选择哪个选项,请确保它清晰可辨。当你不在脑海中时,UITableView会变得复杂。

+0

非常感谢您的提示,我已经添加了关于我最终做了什么的详细答案。我很想知道是否存在您列出的其他选项之一的实现,它不会遇到我在下面描述的嵌套的scrollview问题。 – BananaNeil

+0

我很高兴你能解决这个问题。选项1在弹跳或异常行为方面没有任何问题,但那是因为它只是一个表视图。对于选项2和3,我将采用较小的表格视图并禁用滚动,同时使单元格变为表格视图的大小,这样只有一个表格视图正在滚动。如果这个表格视图不是特别大,那么它工作得很好。 – Fennelouski