前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS实践:打造一个可以快速索引的城市列表页1. 从plist中获取城市字典2. 对城市的首字母进行排序3. 设置边栏索引4. 关于约束的重要提示5. 完善:封装

iOS实践:打造一个可以快速索引的城市列表页1. 从plist中获取城市字典2. 对城市的首字母进行排序3. 设置边栏索引4. 关于约束的重要提示5. 完善:封装

作者头像
stanbai
发布2018-06-28 13:18:19
2.2K0
发布2018-06-28 13:18:19
举报
文章被收录于专栏:非典型技术宅非典型技术宅

相信绝大部分LBS的APP里面,大家都能看到一个带索引的城市列表页面,用来让用户选择所在城市。

我们就一步一步的来实现这个页面,最终效果如下:

Paste_Image.png

最终我们会按照首字母汉语拼音对所有城市进行排序,可以通过右侧的首字母索引来快速定位到城市。

1. 从plist中获取城市字典

1.1 准备素材,下载文件

城市列表(带拼音首字母的),下载地址:

链接: https://pan.baidu.com/s/1nV**YJJ 密码: cjpw

1.2 从plist中读取出所有的城市。

代码语言:javascript
复制
- (NSDictionary *)loadCityListData{
    
    return [NSDictionary dictionaryWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"cityList.plist" withExtension:nil]];
}

1.3 取出字典中所有的key

  • 字典中有一个属性allKeys,可以取出字典中所有的key。这是一个只读的属性。
  • 根据allKeys就能知道字典中有多少组,去对应的数据源设置返回数据。
代码语言:javascript
复制
@property (readonly, copy) NSArray<KeyType> *allKeys;

2. 对城市的首字母进行排序

  • 对所有字典key的数组中的内容进行排序
  • 对于排序,系统提供了两种办法可以进行排序。我们就不用再写什么冒泡儿、选择之类的算法了,直接来就可以用。

2.1 方法一:使用方法进行排序:升序

代码语言:javascript
复制
    _firstLetterOfCitys = [_firstLetterOfCitys sortedArrayUsingSelector:@selector(compare:)];

2.2 使用block进行排序:可以选择排序的方法

代码语言:javascript
复制
    _firstLetterOfCitys = [_firstLetterOfCitys sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
//        升序排序
        return [obj1 compare:obj2];
        
//        将序排序
        return [obj2 compare:obj1];
        
//        乱序
        return arc4random_uniform(10) % 3 - 1;
        
    }];

  • 之所以是能够排序,是每次obj1和obj2比较都进行了一次排序。排序结果记录在了NSComparisonReuslt中。
  • NSComparisonReuslt是一个枚举。通过操作两数比较的结果,进行排序。如果两数比较的结果一会儿是-1,一会儿是0,一会儿是1,那排序出来的结果也就是乱的。

官方对此说明:

代码语言:javascript
复制
typedef NS_ENUM(NSInteger, NSComparisonResult) {NSOrderedAscending = -1L, NSOrderedSame, NSOrderedDescending};

3. 设置边栏索引

  • 边栏的索引显示的文字和实际跳转没有直接关系。
  • 边栏索引无论写什么,都是按照实际的key值进行跳转的。
代码语言:javascript
复制
- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView{
    return _firstLetterOfCitys;
}

4. 关于约束的重要提示

  • 所有的类方法在执行初始化的时候都需要先去看看类里面初始化的方法首选项。

以UITableView为例

代码语言:javascript
复制
NS_CLASS_AVAILABLE_IOS(2_0) @interface UITableView : UIScrollView <NSCoding>

- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style NS_DESIGNATED_INITIALIZER; // must specify style at creation. -initWithFrame: calls this with UITableViewStylePlain
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;

官方说明的意思是说,当执行init的时候,系统要求执行了两个初始化方法。

问题来了:如果在初始化的时候,写成了[[UITableView alloc] init],在编译的时候实际上还是执行了两个初始化方法。第一个初始化方法中要求传入frame,此时因为没有传入参数,frame就会被默认为{0.0.0.0}。

为了解决这个问题,当view有了frame之后,就需要重新给tableView设置frame。是用以下方法进行设置:

代码语言:javascript
复制
- (void)layoutSubviews{
    [super layoutSubviews];
    _tableView.frame = self.bounds;
}

5. 完善:封装

因为城市列表今后我们很有可能会在其他项目里面使用,但我们又不确定以后再使用的时候是用StoryBoard调用还是代码调用。所以我们还要进一步处理一下。

代码语言:javascript
复制
//当从XIB或者UIStoryboard中创建UITableView的时候加载此方法
- (void)awakeFromNib{
    [super awakeFromNib];
    [self createCityListTableView];
}

//使用代码创建的时候加载此方法
- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        [self createCityListTableView];
    }
    
    return self;
}

这样就算是封装好了,以后不管是SB还是代码方式,都可以直接的把刚才写好的城市列表进行引用了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016.11.18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 从plist中获取城市字典
    • 1.1 准备素材,下载文件
      • 1.2 从plist中读取出所有的城市。
        • 1.3 取出字典中所有的key
        • 2. 对城市的首字母进行排序
          • 2.1 方法一:使用方法进行排序:升序
            • 2.2 使用block进行排序:可以选择排序的方法
            • 3. 设置边栏索引
            • 4. 关于约束的重要提示
            • 5. 完善:封装
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档