有没有觉得UITableView自带的右侧索引很难用,我一直觉得WindowsPhone中的列表索引非常好用。
所以呢,我们来实现类似Windows Phone中的列表索引(这就是信仰)。
最终实现效果图:
1.完整的首字母索引 2.Header名称索引
想法:这个控件是该继承UITableView还是UIView,抑或其他的呢?
想要写的这个控件,只是在UITableView的基础上增加-点击HeaderView事件-来弹出索引。
弹出索引的大小为控件的大小,并直接添加到父视图中。
所以觉得直接继承UITableView会更加方便,而继承UIView虽然说在写法上更简单些,但是总觉得不太好。
碰巧看到一个实现UITableView动画的例子,于是参照着实现了HeaderView的点击事件。
https://github.com/applidium/ADLivelyTableView
原理是通过增加一个中间代理,只在控件中实现了willDisplayCell协议来控制滑动时的动画,
如果在VC中使用控件时也实现了该协议,则让控件中的代理发送该消息给VC。这样的话相当
于UITableView的实现部分都不变,动画都交给控件来实现。
-------------------------------------我是分割线----------------------------------------------
1.继承UITableView - 增加中间代理
普通流程:UIViewController<UITableViewDelegate> ---> UITableView
tableView.delegate = self;
控件流程:继承UITableView : YFMetroListBox : UITableView
增加私有属性: id<UITableViewDelegate> _selfDelegate;
UIViewController<UITableViewDelegate> ---> YFMetroListBox<UITableViewDelegate> ---> UITableView
tableView.delegate = self; 重写YFMetroListBox代理见下面代码
重写YFMetroListBox设置代理的方法:(这个是继承自UITableView的属性)
-(void)setDelegate:(id<UITableViewDelegate>)delegate{//这里的形参即VC对象
_selfDelegate = delegate; //让本类(YFMetroListBox)对VC进行监听
[super setDelegate:self]; //让父类(UITableView)对子类的监听
}
//重写方法: YFMetroListBox或者父类是否实现了协议
- (BOOL)respondsToSelector:(SEL)aSelector { return [super respondsToSelector:aSelector] || [_selfDelegate respondsToSelector:aSelector]; } //转发消息
- (void)forwardInvocation:(NSInvocation *)anInvocation { if ([_selfDelegate respondsToSelector:[anInvocation selector]]) { [anInvocation invokeWithTarget:_selfDelegate]; } else { [super forwardInvocation:anInvocation]; } }
2.YFMetroListBox实现willDisplayHeaderView协议,增加添加HeaderView的点击手势
弯路1 :刚开始想使用viewForHeaderInSection添加自定义View,之后添加手势,
但是这样的话就得在此HeaderView内容,因此直接在初始化的时候传入了NSArray(感觉不好,但没其他方案)。
除了上述协议,还有titleForHeaderInSection也是能够直接设置默认的标题内容的,那么如何获取headerView?
再者,上面两个协议都是UITableViewDataSource中的,要在控件中这样做会更加的混乱了
解决 :不管VC中如何设置标题,在HeaderView将要显示的时候,添加手势就行了
#pragma mark -m UITableViewDelegate
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section{
//如果VC也实现了该协议,则发送此消息
if([_selfDelegate respondsToSelector:@selector(tableView:willDisplayHeaderView:forSection:)]){
[_selfDelegate tableView:tableView willDisplayHeaderView:view forSection:section];
}
//增加手势
UITapGestureRecognizer *tapRegesture = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@s