UITableView字母索引视图(仿微信)
我们在使用UITableView时,会一个自带的字母索引视图。但是设计要求字母要在滑动列表的上层,类似下图:
于是,我自己写了一个,如下效果:
要实现的效果:
1、列表在滑动时,右侧的字母索引视图会根据当前列表的组来进行变化;
2、在字母索引视图上可以点击跳到对应的字母组,并且可以手指滑动选择,在点击或者滑动过程中,有一个指示器视图显示当前选中的组的字母。
我的实现方式:
1、字母索引视图采用UIControl类,命名为IndexView(IndexView实现UITableViewDelegate, UITableViewDataSource两个协议),因为UIControl有以下三个方法可以用来识别手势:
//当手指开始触摸屏幕时
- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(nullable UIEvent *)event;
//当手指在屏幕上移动时
- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(nullable UIEvent *)event;
//当手指离开屏幕时
- (void)endTrackingWithTouch:(nullable UITouch *)touch withEvent:(nullable UIEvent *)event;
2、将UITableView的delegate和dataSource设置为IndexView,并且IndexView提供两个代理方法:IndexViewDelegate和IndexViewDataSource。
这样做的目的主要是为了获取到UITableView的代理方法返回的数据(如果读者有更好的方式,欢迎在评论区给我留言🙂 )。
具体代理方法如下:
/** 代理方法 */
@protocol IndexViewDelegate <NSObject>
@optional
- (void)tableView:(UITableView *_Nonnull)tableView didSelectRowAtIndexPath:(NSIndexPath *_Nullable)indexPath;
- (CGFloat)tableView:(UITableView *_Nullable)tableView heightForHeaderInSection:(NSInteger)section;
- (nullable UIView *)tableView:(UITableView *_Nullable)tableView viewForHeaderInSection:(NSInteger)section;
@required
/** 当前选中下标 */
- (void)selectedSectionIndexTitle:(NSString *_Nullable)title atIndex:(NSInteger)index;
/** 添加指示器视图 */
- (void)addIndicatorView:(UIView *_Nullable)view;
@end
/** 数据源方法 */
@protocol IndexViewDataSource <NSObject>
@required
- (NSInteger)tableView:(UITableView *_Nullable)tableView numberOfRowsInSection:(NSInteger)section;
- (UITableViewCell *_Nullable)tableView:(UITableView *_Nonnull)tableView cellForRowAtIndexPath:(NSIndexPath *_Nullable)indexPath;
- (NSInteger)numberOfSectionsInTableView:(UITableView *_Nullable)tableView;
/** 组标题数组 */
- (NSArray<NSString *> *_Nullable)sectionIndexTitles;
@end
3、使用,UIViewController只需要实现如下3个代理方法即可:
#pragma mark - IndexView
- (NSArray<NSString *> *)sectionIndexTitles {
//去掉搜索符号
NSMutableArray *resultArray = [NSMutableArray array];//[NSMutableArray arrayWithObject:UITableViewIndexSearch];
for (NSDictionary *dict in self.brandArray) {
NSString *title = dict[@"firstLetter"];
[resultArray addObject:title];
}
return resultArray;
}
//当前选中组
- (void)selectedSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
[self.demoTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:index] atScrollPosition:UITableViewScrollPositionTop animated:NO];
}
//将指示器视图添加到当前视图上
- (void)addIndicatorView:(UIView *)view {
[self.view addSubview:view];
}
2017.06.20 更新
1、新增搜索
2、修正手指移动到视图外,指示器视图不消失的问题(感谢评论区指正😁)