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

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

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

Paste_Image.png

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

1. 从plist中获取城市字典

1.1 准备素材,下载文件

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

链接: https://pan.baidu.com/s/1nvPNYJJ 密码: cjpw

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

- (NSDictionary *)loadCityListData{
    
    return [NSDictionary dictionaryWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"cityList.plist" withExtension:nil]];
}

1.3 取出字典中所有的key

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

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

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

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

    _firstLetterOfCitys = [_firstLetterOfCitys sortedArrayUsingSelector:@selector(compare:)];

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

    _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,那排序出来的结果也就是乱的。

官方对此说明:

typedef NS_ENUM(NSInteger, NSComparisonResult) {NSOrderedAscending = -1L, NSOrderedSame, NSOrderedDescending};

3. 设置边栏索引

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

4. 关于约束的重要提示

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

以UITableView为例

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。是用以下方法进行设置:

- (void)layoutSubviews{
    [super layoutSubviews];
    _tableView.frame = self.bounds;
}

5. 完善:封装

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

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

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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏别先生

c3p0和QueryRunner的结合使用,让开发更加简便

1:DBUtils中的QueryRunner的使用:   1.1:QueryRunner中提供了对SQL语句操作的api;   1.2:主要有三个方法:    ...

66380
来自专栏数据结构与算法

BZOJ1269: [AHOI2006]文本编辑器editor

Descriptio 这些日子,可可不和卡卡一起玩了,原来可可正废寝忘食的想做一个简单而高效的文本编辑器。你能帮助他吗? 为了明确任务目标,可可对“文本编辑器...

29870
来自专栏FreeBuf

小白都能看懂的JSON反序列化远程命令执行

前言 Fastjson是一个由阿里巴巴维护的一个json库。它采用一种“假定有序快速匹配”的算法,是号称Java中最快的json库。Fastjson接口简单易...

53440
来自专栏个人随笔

房上的猫:吃货联盟项目

一.首先先定义部分成员变量: String[] name = new String[4];// 订餐人 String[] greens = new St...

397100
来自专栏Hongten

java中interface的完整表述

我用一个工具:java Decompiler反编译工具查看jar包源码的时候,出现了以下代码:

43210
来自专栏jeremy的技术点滴

JVM的Finalization Delay引起的OOM

43280
来自专栏進无尽的文章

编码篇 — 一个DataModel小例领略指针的魅力

做过的项目中曾经有这样的需求:货品录入(商品入库),弹框弹出所有的货品(很多),选择其中的一个,则下次弹框弹出所有货品时不再显示选择了的那件货品。当然,录入功能...

9930
来自专栏XAI

【人工智能】动物、植物、车型、菜品、LOGO识别示例代码

图像识别部分接口Java-API调用示例代码 https://gitee.com/xshuai/ai/不是完整的web项目大家没必要下载运行。复制|下载相关代码...

895110
来自专栏君赏技术博客

GB代码规范1.0

对于如果导入是UIKit类就使用UIKIT_EXTERN 如果是Founction使用关键词FOUNDATION_EXTERN

14320
来自专栏向治洪

微信支付

1,导入微信的libs包libammsdk.jar; 2,测试时使用weixinDemo中的debug_keystore; 3,需要注意应用要通过审核,并...

64650

扫码关注云+社区

领取腾讯云代金券