iOS:类似于美团/支付宝 城市选择器带拼音搜索实现
2017-03-31 本文已影响895人
SoolyChristina
1. 分析原型
效果图 实现demo要做的页面是一个
UITableView
加UISearchController
2. UITabelView
-
UITableView
就分为四种cell
使用.plain
类型就好 -
普通城市就可以用自带的
cell
-
热门城市 当前城市和最近城市就必须
自定义cell
了 -
在数据源方法里利用
indexPath
创建不同种类cell即可 -
数据通过加载plist文件即可
/// 懒加载 城市数据
lazy var cityDic: [String: [String]] = { () -> [String : [String]] in
let path = Bundle.main.path(forResource: "cities.plist", ofType: nil)
let dic = NSDictionary(contentsOfFile: path ?? "") as? [String: [String]]
return dic ?? [:]
}()
/// 懒加载 热门城市
lazy var hotCities: [String] = {
let path = Bundle.main.path(forResource: "hotCities.plist", ofType: nil)
let array = NSArray(contentsOfFile: path ?? "") as? [String]
return array ?? []
}()
3. UISearchController
- 创建搜索控制器
/// 搜索控制器
lazy var searchVC: UISearchController = {
let searchVc = UISearchController(searchResultsController: self.searchResultVC)
searchVc.delegate = self
searchVc.searchResultsUpdater = self
// 不隐藏导航条
searchVc.hidesNavigationBarDuringPresentation = false
searchVc.definesPresentationContext = true
// 是否关闭蒙版
searchVc.dimsBackgroundDuringPresentation = false
searchVc.searchBar.frame = CGRect(x: 0, y: 0, width: ScreenWidth - 114, height: 44)
searchVc.searchBar.placeholder = "输入城市名或拼音查询"
searchVc.searchBar.delegate = self
return searchVc
}()
/// 搜索结果控制器
lazy var searchResultVC: ResultTableViewController = ResultTableViewController()
-
UISearchBar
加到导航条里若需修改搜索条的width
就必须先用一个view去接收再添加到导航条上
let titleView = UIView(frame: searchVC.searchBar.frame)
titleView.addSubview(searchVC.searchBar)
self.navigationItem.titleView = titleView
-
搜索逻辑 (支持拼音搜索)
-
先判断
searchBar.text
是否含有中文字符,如果有- 将其转为拼音 根据首字母在
cityDic["首字母"]
里遍历查找 - 把数据传给
searchResultsController
显示数据即可
- 将其转为拼音 根据首字母在
-
若没有中文字符则进行拼音搜索
- 根据
searchBar.text
的首字母 将cityDic["首字母"]
里转换为无空格的拼音遍历查找即可 - 需要实现
bj => 北京 wh=> 武汉
此类搜索则分别获取两字的首字母即可 - 搜索不区分大小写则调用
String
里的uppercased()
和lowercased()
对应将字符串转为大写和小写
- 根据
-
中文转拼音
func chineseToPinyin() -> String {
let stringRef = NSMutableString(string: self) as CFMutableString
// 转换为带音标的拼音
CFStringTransform(stringRef,nil, kCFStringTransformToLatin, false)
// 去掉音标
CFStringTransform(stringRef, nil, kCFStringTransformStripCombiningMarks, false)
let pinyin = stringRef as String
return pinyin
}