美文网首页iOS工作系列iOS移动开发开发
iOS:实现一个横向的tableView 理解scrollVie

iOS:实现一个横向的tableView 理解scrollVie

作者: redihd | 来源:发表于2015-08-22 20:38 被阅读3734次

HorizontalTableView相关的(下面还有对于scrollView的讨论)

上次写了一篇实现横向pageView的文章,地址在这里,本来是想把上次的pageView补全的,后来想想不如直接写一个横向的tableView好了。于是就有了这篇文章。
先上代码,github地址在这,再看demo 效果

ZqwHorizontalTableViewDemo.gif

其实横向的tableView的实现基本和上次的pageView差不多,主要需要的也就是一个复用cell池可视cell池并及时更新他们。
与pageView相比只是多了一个cellIdentifiy来取对应的cell,另一个就是如何获取现在可视区域的cell及对应的位置(因为现在每一个cell的宽度不一定了)。

所以比起上次的pageView,我们只要获取现在要显示的cells开始index和一共有几个cell需要展示,在这里我们用一个range来表示他们,然后根据range来判断要显示cell的和不显示的cell并对 visibleListViewsItems 和 dequeueViewPool 做更新,然后计算要显示的cell的位置,这样子一个有复用功能的横向的tableView就搞定了。

而另外一个多出来的需求cellIdentifiy 就需要我们新建一个属于自己的baseCell来配合,我们该cell带一个identifiy属性,在从复用池(dequeueViewPool)获取cell的时候对identifiy做一次判断,如果有对应cell的identifiy则取出,没有则新建即可。

这次我并没有使用block,主要是上次复用view的返回用block之后发现返回需要的cell那一部分太大段了,还不如分开来写。而且这样也更好地模仿了系统的tableView,所以我也设了一个dataSource 和一个actionDelegate(我想用delegate来着),但是。。。delegate已经被scrollView用了。

这里上一下我们的HorizontalTableView的数据源,代理和几个简单地方法

//@property (nonatomic, weak) id<ZqwTableViewDelegate> actionDelegate;   最基本的处理点击事件
- (void) zqwTableView:(ZqwHorizontalTableView*)tableView didTapAtColumn:(NSInteger)column;

//@property (nonatomic, weak) id<ZqwTableViewDataSource> dataSource;  1、 多少个cell 2、 对应的宽度 3、 获取cell
- (NSInteger)numberOfColumnsInZqwTableView:(ZqwHorizontalTableView *)tableView;

- (ZqwTableViewCell *)zqwTableView:(ZqwHorizontalTableView *)tableView cellAtColumn:(NSInteger)column;

- (CGFloat)zqwTableView:(ZqwHorizontalTableView *)tableView cellWidthAtColumn:(NSInteger)column;

@interface ZqwHorizontalTableView : UIScrollView
- (ZqwTableViewCell *)dequeueZqwTalbeViewCellForIdentifiy:(NSString *)identifiy;

- (void)reloadData;

具体如何使用可以看git上的demo

另外再上一个scrollView相关的

顺便附上一个自己实现一部分功能的scrollView
git地址在这里
这个demo主要就是为了演示scrollView的工作原来,为什么scroll能拖动,所谓的contentOffset,和contentSize代表着什么。

  1. scrollView 为什么能滚动.我们知道每个视图都有一个 bounds和 frame。当我们要去布局一个界面时,我们需要处理视图的 frame。这个属性允许我们设置视图的位置和大小。视图的 frame 和 bounds 的大小总是一样的,但是他们的 origin 有可能不同。弄懂这两个属性的工作原理是理解 UIScrollView 的关键。

    先放出两个公式
    viewPosition.x = View.frame.origin.x - Superview.bounds.origin.x;
    viewPosition.y = View.frame.origin.y - Superview.bounds.origin.y;

    现在有一个父视图和若干个子视图,一般情况,父视图的bounds.origin都是(0,0),子视图的位置则是frame相对于bounds.origin(0,0)的位置,一般子视图的动画或者移动,都是对子视图frame的改变。
    现在我们来观察scrollView,移动scrollView的时候所有的子视图的位置好像都改变了。如果我们想要改变子视图的frame来做出这种效果,我们需要同时调整所有子视图的frame。这样操作量太大,这时候来看我们之前的公式,想要改变位置,不一定要改变子视图的frame,而通过改变父视图的bounds来实现。

    所以,改变scrollView的bounds就是我们滑动scrollView的本质。

  2. contentOffset 是scrollView特有的一个属性,但其实我们通过上面的分析可以很快的了解到,这个属性的实质就是bounds.origin。这里贴一下contentOffset的setter 和 getter方法。

    - (void)setContentOffset:(CGPoint)offset{
        CGRect bounds = [self bounds];
        bounds.origin = offset;
        [self setBounds:bounds];
    }
    
    - (CGPoint)contentOffset{
        return self.bounds.origin;
    }
    
  3. contentSize 这个属性是规定了scrollView可滚动区域的属性。当contentSize小于bounds.size时则不能滑动,当contentSize大于bounds.size时则可滑动,对应的contentOffset的最大值等于contentSize减去对应的bounds.size。

我写的scrollView的demo只是简单实现了scrollView滑动的功能,其他的属性比如减速,bounces这些增强使用体验的效果我们可以用facebook的pop来实现,这里就不细聊了。

欢迎讨论~

相关文章

网友评论

  • ce5574adfa83:您好,请问怎么设置初始化的时候直接滑到最后一页,设置currentPageIndex没有生效呢
  • 不必luo嗦:再补充一下,文/redihd(简书作者)
    原文链接:http://www.jianshu.com/p/0e90c20c4a39
    著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

    - (ZqwTableViewCell *)dequeueZqwTalbeViewCellForIdentifiy:(NSString *)identifiy;
    这个方法我只能加载继承ZqwTableViewCell的cell,现在我要加载继承uitableviewcell的cell,该怎么用了?
    真爱要有你才完美:你好 我想问下 你说用collectionview也可以做成这种横向的 我尝试了 可是 我做下拉刷新的时候 发现 当下拉的时候整个界面因为可以左右滑动 导致我下拉刷新的时候 还可以左右 整个界面都崩了 我想知道这个怎么解决 谢谢了
    不必luo嗦:@redihd 好的 谢谢 我去试试
    redihd:@不必luo嗦 其实就是想用xib上面的东西吧,你可以用uiview ZqwTableViewCell是继承自uiview的
  • 不必luo嗦:你好!我现在准备用你的demo,但是现在我要加载xib上面的cell,想用tableview register的那个方法,不能用了,该怎么处理
    redihd:@不必luo嗦 因为我没有实现register方法
  • OCDak:很给力,菜鸟表示受用很大。我在使用HorizontalTableView,我需要在下方设置两个按钮控制横向的偏移量,往左翻的按钮我调用的是滚动视图的- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate 方法,加上简单的动画可以实现类似滑动的效果,但是同样的方法往右实现偏移就会出现屏幕原视图消失的现象,求大神解释下,并如何解决这个问题?不胜感激啊!
    redihd:@OCDak 这个有私信吗。。。私聊吧
    OCDak:@redihd 你好,我说的是滑动的时候出现的一些问题,当滑到最后一个试图,再往右滑,自动弹回后在右侧会出现一个条形白边,并没有完全弹回,这是什么问题?不知道是否方便留下QQ请求你下~不胜感激~
    redihd:@OCDak 你是要做翻页功能?要么直接把_tableView.pagingEnabled 改成yes 要么调用- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated; // animate at constant velocity to new offset
    这个方法

本文标题:iOS:实现一个横向的tableView 理解scrollVie

本文链接:https://www.haomeiwen.com/subject/tfxgqttx.html