ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

iOS造轮子 - UITableView字母索引条

2020-09-24 14:34:21  阅读:273  来源: 互联网

标签:iOS self alphaLabel touchPoint 索引 UITableView 轮子 indexBar view


 

最近重构项目的通信录页面,旧版本的索引条相当丑陋,找了下轮子又找不到,没办法,只能自己造了。发现微信的通讯录索引条样式还不错,照着写了一个,顺便添加了震动效果(Impact Feedback)。

首先看一下效果:

单击索引条时

单击索引条字母
单击索引条字母

滑动tableView时

滑动tableView时.gif
滑动tableView时.gif

在索引条上滑动时

在索引条上滑动时.gif
在索引条上滑动时.gif

实现原理

主要分为以下几步:

1、每一个索引,都是一个label,把所有label都竖直排列在一个父view中。这里没有使用重用池,主要考虑到一般的索引条,字母数量也不会太多。

_labelArr = [NSMutableArray new];
for (int i = 0; i < indexes.count; i++) {
    CGFloat y = (_sectionHeight * i);

    UILabel *alphaLabel = [[UILabel alloc] initWithFrame:CGRectMake(x, y, width, height)];
    alphaLabel.textAlignment = NSTextAlignmentCenter;
    alphaLabel.text = [[indexes objectAtIndex:i] uppercaseString];
    alphaLabel.font = [UIFont boldSystemFontOfSize:10.0];
    alphaLabel.backgroundColor = [UIColor clearColor];
    alphaLabel.textColor = self.textColor;
    alphaLabel.layer.cornerRadius = width * 0.5;
    alphaLabel.clipsToBounds = YES;
    [self addSubview:alphaLabel];
    [_labelArr addObject:alphaLabel];
}

2、当在父view中触摸时,通过touchMoved等方法处理触摸点和索引label之间的关系,如果触摸点落在label范围之内,则将label高亮选中。

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];

    CGPoint touchPoint = [[[event touchesForView:self] anyObject] locationInView:self];
    [self toSelectTitle:touchPoint];
}

// 通过touchPoint找到对应的索引label
- (void)toSelectTitle:(CGPoint)touchPoint
{
    if(touchPoint.x <= 0 ||
       touchPoint.y <= 0 ||
       touchPoint.x >= self.bounds.size.width ||
       touchPoint.y >= self.bounds.size.height) return;
    __block NSString *title;
    __block NSInteger index = 0;

    [_labelArr enumerateObjectsUsingBlock:^(__kindof UILabel * _Nonnull subview, NSUInteger idx, BOOL * _Nonnull stop) {
        if(touchPoint.y < CGRectGetMaxY(subview.frame)) {
            _preLabel.backgroundColor = [UIColor clearColor];
            _preLabel.textColor = _textColor;

            subview.backgroundColor = _selectedBackgroundColor;
            subview.textColor = _selectedTextColor;
            _preLabel = subview;

            index = idx;
            title = subview.text;
            *stop = YES;
        }
    }]; 

    ......
}

3、添加震动效果,并触发点击回调

//震动
if (@available(iOS 10.0, *)) {
    UIImpactFeedbackGenerator *gen = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight];
    [gen prepare];
    [gen impactOccurred];
}

//回调
if (_delegate && [_delegate conformsToProtocol:@protocol(TTIndexBarDelegate)]) {
    [_delegate indexDidChanged:self index:index title:title];
}

如何使用

默认样式:

self.indexBar = [[TTIndexBar alloc] initWithFrame:CGRectMake(self.view.frame.size.width - 30, 0, 30, self.view.frame.size.height)];
self.indexBar.delegate = self;
[self.view addSubview:self.indexBar];

[self.indexBar setIndexes:[NSMutableArray arrayWithObjects:@"A",@"B",@"C",@"D",@"E",@"F",@"G",@"H",@"I",@"J", nil]];

自定义样式:

self.indexBar = [[TTIndexBar alloc] initWithFrame:CGRectMake(self.view.frame.size.width - 30, 0, 30, self.view.frame.size.height)];
self.indexBar.delegate = self;
[self.view addSubview:self.indexBar];   

//Custom property
self.indexBar.textColor = [UIColor redColor];
self.indexBar.selectedTextColor = [UIColor greenColor];
self.indexBar.selectedBackgroundColor = [UIColor yellowColor];
self.indexBar.detailViewDrawColor = [UIColor cyanColor];
self.indexBar.detailViewTextColor = [UIColor orangeColor];

[self.indexBar setIndexes:[NSMutableArray arrayWithObjects:@"A",@"B",@"C",@"D",@"E",@"F",@"G",@"H",@"I",@"J", nil]];

Delegate:

- (void)indexDidChanged:(TTIndexBar *)indexBar index:(NSInteger)index title:(NSString *)title;

GitHub

TTIndexBar

资料推荐

如果你正在跳槽或者正准备跳槽不妨动动小手,添加一下咱们的交流群1012951431来获取一份详细的大厂面试资料为你的跳槽多添一份保障。

标签:iOS,self,alphaLabel,touchPoint,索引,UITableView,轮子,indexBar,view
来源: https://www.cnblogs.com/Julday/p/13723880.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有