[iOS 开发] 请教大家这种页面如何实现比较优雅?

2015-12-03 11:17:22 +08:00
 hustlzp



类似上图的页面,上面有个 tab ,点击可以切换下面的视图,下面的视图可能是 tableview 或 collection view 或普通的 uiview 。

如果 tab 是固定在上方的,实现起来比较简单,可以把下面的页面拆分到一个个独立的 view controller 中,然后作为 child view controller 加进来。切换上面的 tab 时,只需显示 /隐藏 child view controller 的 view 就行。

但这个 tab 需要跟着页面上下滚动。目前想到的方式是在当前 view controller 中实现一个 tableview ,把 tab 作为 tableview 的 header view 。然后如果点击 tab 切换到 tableview 类型的视图,那么就在 tableview 协议中根据不同的 tab 返回对应类型的 cell 。如果是其他类型的,那么 tableview 的 rows 返回 1 ,然后把整个 view 塞到这个 cell 中(比如把整个 collection view 塞到这个 cell 中)。

但这样做的问题是维护性差,单个 view controller 塞进了太多的逻辑。如果能拆开就好了。

不知道大家有没有遇到这样的问题,或者有更好的想法。
9598 次点击
所在节点    iDev
27 条回复
hustlzp
2015-12-03 11:49:28 +08:00
想到了一种减负的方法:

将 datasource 和 delegate 拆分到独立的 class 中,切换 tab 时,同时切换 tableview 的 datasource 和 delegate :

if (didPressedATab) {
self.tableView.delegate = instanceOfMyClassA;
self.tableView.datasource = instanceOfMyClassA;
} else {
self.tableView.delegate = instanceOfMyClassB;
self.tableView.datasource = instanceOfMyClassB;
}

然后再 reloadData 一下。不知道这样可以不可以,去试试~
loveuqian
2015-12-03 11:55:02 +08:00
header 是 tag
footer 是或者 cell 是 scrollView
切换 tag 就滚动
这样可以嘛
blacknight
2015-12-03 11:59:46 +08:00
view controller 的本质还是 view ,这几个 tab 对应的页面你可以单独写在每一个 view controller 中,添加的时候只使用 view controller 的 view 即可。这样整个页面处理的实际上就是一个如图的 header 和一个 tab 。
mornlight
2015-12-03 12:00:34 +08:00
@hustlzp 每次切换一个 tab 就 reload 一次,这个方式好像太野蛮了。
「这个 tab 需要跟着页面上下滚动」 这个滚不滚动对实现方式有很大影响吗?
hustlzp
2015-12-03 12:11:41 +08:00
@mornlight

「这个方式好像太野蛮了。」
看起来确实有点野蛮...不过 tableview 的 reloadData 只会 reload 当前可见的 rows ,而且 cell 是可以 dequeue 复用的, cell height 也可以做 cache ,所以 reload 的代价个人觉得其实还好。

主要还是可维护性方面的考虑,因为太多逻辑堆到一个 controller 里面看起来太虐心了...

「这个滚不滚动对实现方式有很大影响吗?」 不滚动,我就可以把下面的视图拆分到 view controllers 中,如 @blacknight 所说, tab 和 child view controller 的 view 是兄弟关系。

但如果需要 tab 跟着 tableview 滚动,需要把它作为 tableview 的 header view 才行(目前我只想到这样做), tab 和 child view controller 的 view 是从属关系。
hustlzp
2015-12-03 12:12:19 +08:00
@blacknight 恩,我明白你的意思。这个我在帖子中提到了。
blacknight
2015-12-03 12:27:32 +08:00
@hustlzp 我再说详细一点吧,这个界面可以分成三部分,最上面的 header , 中间的 tab ,最下面的一个混合视图。其实三个部分都可以用 view 来实现,最上面的是 uiview ,中间是 uiview ,下面可以用 scrollview ,暂称为 sub scrollview 。然后再用一个 scrollview 来容纳这三个 view 。上下滑动的时候,根据 scrollview 的位移来让 tab 随页面滚动,点击 tab 的时候,设置 tab 在 scrollview 中的位置和切换 sub scrollview 中的 view controller 。

这样做, scrollview 里的逻辑仅处理 tab 的跟随和 sub scrollview 的切换,具体的页面都划分到了各个 view controller 中去
hustlzp
2015-12-03 12:38:36 +08:00
@blacknight 感谢回复,你的思路可行。我没有想到把 tableview 放到 scrollview 中...就是不知 iOS 会不会正确处理嵌套的滚动关系。我去试试,感谢回复!
hustlzp
2015-12-03 12:44:40 +08:00
@blacknight SO 上找到了相关的一个问题:

http://stackoverflow.com/questions/17334478/uitableview-within-uiscrollview-using-autolayout

就是类似你提到的解决方法。
xi_lin
2015-12-03 12:49:54 +08:00
@blacknight 说的做法还是上方固定的来法吧
这样的话其实直接就是 https://github.com/wangmchn/WMPageController
blacknight
2015-12-03 12:53:32 +08:00
@hustlzp 方案是可行的,我试过
送佛送到西,帮人帮到底,刚去翻了一下 github ,给你一个现成的吧
https://github.com/AugustRush/ARSegmentPager
hustlzp
2015-12-03 12:55:22 +08:00
@xi_lin
@blacknight

感谢分享!
mornlight
2015-12-03 12:58:25 +08:00
@hustlzp 和 7 楼的想法类似,我觉得中间的自滚动 tab 独立出来会让耦合度低一些。
hustlzp
2015-12-03 13:02:07 +08:00
nellace
2015-12-03 14:02:17 +08:00
@xi_lin 做的挺精致的这个
racechao
2015-12-03 14:02:39 +08:00
@hustlzp
和上面的思路基本差不多,这样并不需要用 tableVIew :
1.只需要有一个主要的 ViewController ,这个 ViewController 有她的 Header View (普通的 View )还有一个 scrollView ;
2.假设这里每个 tab 对应一个 ViewControll 的 view ,将这些 view 放到 scrollView 中就可以了。这就将 tab 分到了多个 ViewController 当中, 当切换 tab 时改变 scrollView 的 content offset (将 scrollView 的 pagingEnabledtab 设为 true 会很方便);
我之前用 Swift 写了一个类似的控件 --> https://github.com/alfredcc/ZYScrollTabBar
使用方法和 tableView 差不多,拆分了 dataSource 和 delegate 有兴趣可以参考下
pheyer
2015-12-03 14:36:06 +08:00
可能有一个问题没考虑到,你的 Tab 要不要悬浮呢
借用上面 @blacknight 的描述: 这个界面可以分成三部分,最上面的 header , 中间的 tab ,最下面的一个混合视图。其实三个部分都可以用 view 来实现,最上面的是 uiview ,中间是 uiview ,下面可以用 scrollview ,暂称为 sub scrollview 。然后再用一个 scrollview 来容纳这三个 view 。

如果容纳这三个 view 的是 scrollview 的话,我们知道展示 scrollview 时是要提前知道它的 contentsize 的,你准备给它多少 height ?

如果 Tab 要有悬浮效果的话,容纳这三个 view 的用 TableView 可能更好一些,把 Tab 放在 Section 里面,悬浮就是自然而然的事情。设这个 TableView 名为 TableView0
上面说的 sub scrollview 可能具体起来就是 TableView 或者 CollectionView 了,就假设都为 sub TableView

如果想要比较好的滑动体验的话,然后 TableView 嵌套的滑动问题就来了,当 TableView0 还未滑动到底部,而手指落在 subTableView 的内容上面,如何确保手指向上滑动时是滑动 TableView0 ?或者你不管任由它滑动 subTableView ?
另一个问题,手指向下滑动使 subTableView 滑动到顶部,手指落在 subTableView 的内容上面,这时候怎么确保手指再往下滑动后滑动的是 TableView0 而非 subTableView ?
hustlzp
2015-12-03 15:37:04 +08:00
@pheyer 你这个思路挺新颖的,我目前没有悬浮的要求,不过以后应该会有的。

嵌套 scroll 目前还没有用过。
hustlzp
2015-12-03 15:39:30 +08:00
@racechao 好思路,这样写代码起来方便,不用手动去 show/hide child view 了,根据当前 index 设置 contentOffset 就行了。谢谢分享。
jackisnotspirate
2015-12-03 15:52:27 +08:00
scrollview 里面包着 tab, header , scrollview 滑动的时候, tab 跟着滑动,然后在达到某个时刻, scrollview 滑动, tab 设置成 相对 顶部 静止。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/240797

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX