相信绝大部分LBS的APP里面,大家都能看到一个带索引的城市列表页面,用来让用户选择所在城市。
我们就一步一步的来实现这个页面,最终效果如下:
Paste_Image.png
最终我们会按照首字母汉语拼音对所有城市进行排序,可以通过右侧的首字母索引来快速定位到城市。
城市列表(带拼音首字母的),下载地址:
链接: https://pan.baidu.com/s/1nV**YJJ 密码: cjpw
- (NSDictionary *)loadCityListData{
return [NSDictionary dictionaryWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"cityList.plist" withExtension:nil]];
}
@property (readonly, copy) NSArray<KeyType> *allKeys;
_firstLetterOfCitys = [_firstLetterOfCitys sortedArrayUsingSelector:@selector(compare:)];
_firstLetterOfCitys = [_firstLetterOfCitys sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
// 升序排序
return [obj1 compare:obj2];
// 将序排序
return [obj2 compare:obj1];
// 乱序
return arc4random_uniform(10) % 3 - 1;
}];
官方对此说明:
typedef NS_ENUM(NSInteger, NSComparisonResult) {NSOrderedAscending = -1L, NSOrderedSame, NSOrderedDescending};
- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView{
return _firstLetterOfCitys;
}
以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;
}
因为城市列表今后我们很有可能会在其他项目里面使用,但我们又不确定以后再使用的时候是用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还是代码方式,都可以直接的把刚才写好的城市列表进行引用了。