//
|
// SwitchCityVC.swift
|
// OKProject
|
//
|
// Created by alvin_y on 2020/5/28.
|
// Copyright © 2020 yangwang. All rights reserved.
|
//
|
|
import UIKit
|
import MJRefresh
|
import RxCocoa
|
import RxSwift
|
import SwifterSwift
|
|
/// 切换城市
|
class SwitchCityVC: YYTableViewController {
|
|
/// 搜索容器
|
private let search_container: UIView = {
|
let view = UIView()
|
view.backgroundColor = UIColor.color(light: UIColor.color(hexString: "#FFFFFF"), dark: UIColor.color(hexString: "#FFFFFF"))
|
view.layer.borderColor = UIColor.color(light: UIColor.color(hexString: "#F3F4F5"), dark: UIColor.color(hexString: "#F3F4F5")).cgColor
|
view.layer.borderWidth = 1
|
return view
|
}()
|
|
/// 搜索框
|
private let textField_sreach: YYTextField = {
|
let textField = YYTextField()
|
textField.placeholder = "请输入城市名字"
|
textField.maximumOffset = 9
|
textField.font = UIFont.systemFont(ofSize: 13)
|
textField.backgroundColor = UIColor.color(light: UIColor.color(hexString: "#F6F6F7"), dark: UIColor.color(hexString: "#F6F6F7"))
|
textField.layer.cornerRadius = 4
|
textField.layer.masksToBounds = true
|
textField.tintColor = ThemeColor
|
textField.returnKeyType = .done
|
return textField
|
}()
|
|
/// 取消按钮
|
private let button_cancel: YYButton = {
|
let button = YYButton()
|
button.setTitle("取消", for: .normal)
|
button.titleLabel?.font = UIFont.systemFont(ofSize: 14)
|
button.setTitleColor(UIColor.color(light: UIColor.color(hexString: "#666666"), dark: UIColor.color(hexString: "#666666")), for: .normal)
|
return button
|
}()
|
|
|
/// 当前城市容器
|
private let view_currentCity: YYView = {
|
let view = YYView()
|
view.backgroundColor = UIColor.color(light: UIColor.color(hexString: "#F3F4F5"), dark: UIColor.color(hexString: "#F3F4F5"))
|
return view
|
}()
|
|
/// 当前城市
|
private let label_currentCity: YYLabel = {
|
let label = YYLabel()
|
label.textColor = UIColor.color(light: UIColor.color(hexString: "#333333"), dark: UIColor.color(hexString: "#333333"))
|
label.font = UIFont.systemFont(ofSize: 14)
|
label.text = "当前选择:\(YYLocationManager.shared.currentCity)"
|
return label
|
}()
|
|
/// 是否是全局
|
var global = true
|
|
/// 临时存贮数据
|
var tempData: [SwitchCityModel] = []
|
|
private let viewModel = SwitchCityViewModel()
|
|
/// 侧边标题
|
private var sectionTitles: [String] = []
|
|
/// 刷新回调
|
var refresh:((_ model: SwitchCityModel?,_ global: Bool) ->Void)?
|
|
override func viewDidLoad() {
|
super.viewDidLoad()
|
|
// Do any additional setup after loading the view.
|
}
|
|
override func viewWillAppear(_ animated: Bool) {
|
super.viewWillAppear(animated)
|
yy_isHiddenNavBarLine = true
|
}
|
|
//MARK: - UI
|
override func setupViews() {
|
super.setupViews()
|
navigationItem.title = "切换城市"
|
view.addSubview(search_container)
|
view.addSubview(view_currentCity)
|
view_currentCity.addSubview(label_currentCity)
|
search_container.addSubview(button_cancel)
|
search_container.addSubview(textField_sreach)
|
tableView.sectionIndexColor = ThemeColor
|
tableView.delegate = self
|
tableView.dataSource = self
|
tableView.separatorColor = UIColor.color(hexString: "#E5E5E5")
|
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "item")
|
tableView.register(headerFooterViewClassWith: YYTitleWithButtonHeaderView.self)
|
tableView.mj_header = MJRefreshNormalHeader(refreshingTarget: self, refreshingAction: #selector(onRefresh))
|
tableView.mj_header?.beginRefreshing()
|
}
|
|
/// 刷新
|
@objc func onRefresh(){
|
viewModel.queryOpenCity()
|
}
|
|
|
//MARK: - Layouts
|
override func defineLayouts() {
|
super.defineLayouts()
|
search_container.snp.makeConstraints { (make) in
|
if #available(iOS 11.0, *) {
|
make.top.equalTo(view.safeAreaLayoutGuide)
|
} else {
|
make.top.equalToSuperview()
|
}
|
make.left.right.equalToSuperview()
|
make.height.equalTo(45)
|
}
|
|
view_currentCity.snp.makeConstraints { (make) in
|
make.top.equalTo(search_container.snp.bottom)
|
make.left.right.equalToSuperview()
|
make.height.equalTo(39)
|
}
|
|
label_currentCity.snp.makeConstraints { (make) in
|
make.centerY.equalToSuperview()
|
make.left.equalToSuperview().offset(14)
|
make.right.equalToSuperview().offset(-14)
|
}
|
|
textField_sreach.snp.makeConstraints { (make) in
|
make.centerY.equalToSuperview()
|
make.left.equalToSuperview().offset(16)
|
make.right.equalToSuperview().offset(-60)
|
make.height.equalTo(29)
|
}
|
|
button_cancel.snp.makeConstraints { (make) in
|
make.centerY.equalToSuperview()
|
make.right.equalToSuperview().offset(-16)
|
}
|
|
tableView.snp.remakeConstraints { (make) in
|
make.top.equalTo(view_currentCity.snp.bottom)
|
make.left.right.bottom.equalToSuperview()
|
}
|
}
|
|
//MARK: - Rx
|
override func bindRx() {
|
super.bindRx()
|
button_cancel.rx.tap.subscribe(onNext: {[unowned self] (_) in
|
self.yy_pop()
|
}).disposed(by: disposeBag)
|
|
textField_sreach.rx.text.subscribe(onNext: { (text) in
|
if let string = text,string != ""{
|
let model = self.tempData.filter { (model) -> Bool in
|
return model.name.contains(string)
|
}
|
let citySections: [SwitchCitySection] = Dictionary(grouping: model, by: { self.getFirstLetter(from: self.getPinYin(from: $0.name)) }).reduce([], { (result, arg1) -> [SwitchCitySection] in
|
let (key, value) = arg1
|
return result + [SwitchCitySection(letter: key, items: value)]
|
}).sorted(by: \SwitchCitySection.letter)
|
self.viewModel.cities.accept(citySections)
|
self.sectionTitles = citySections.map{$0.letter}
|
self.tableView.reloadData()
|
}else{
|
let model = self.tempData
|
let citySections: [SwitchCitySection] = Dictionary(grouping: model, by: { self.getFirstLetter(from: self.getPinYin(from: $0.name)) }).reduce([], { (result, arg1) -> [SwitchCitySection] in
|
let (key, value) = arg1
|
return result + [SwitchCitySection(letter: key, items: value)]
|
}).sorted(by: \SwitchCitySection.letter)
|
self.viewModel.cities.accept(citySections)
|
self.sectionTitles = citySections.map{$0.letter}
|
self.tableView.reloadData()
|
}
|
}).disposed(by: disposeBag)
|
|
viewModel.requestSubject
|
.observeOn(MainScheduler.instance)
|
.subscribe(onNext: { [unowned self](status) in
|
self.tableView.mj_header?.endRefreshing()
|
switch status{
|
case .loading:
|
self.show()
|
break
|
case .success(let model):
|
self.hide()
|
guard let model = (model as? [SwitchCityModel])?.filter({ (model) -> Bool in
|
return model.name != ""
|
}) else {return}
|
self.tempData = model
|
let citySections: [SwitchCitySection] = Dictionary(grouping: model, by: { self.getFirstLetter(from: self.getPinYin(from: $0.name)) }).reduce([], { (result, arg1) -> [SwitchCitySection] in
|
let (key, value) = arg1
|
return result + [SwitchCitySection(letter: key, items: value)]
|
}).sorted(by: \SwitchCitySection.letter)
|
self.viewModel.cities.accept(citySections)
|
self.sectionTitles = citySections.map{$0.letter}
|
self.tableView.reloadData()
|
break
|
case .error(let error):
|
self.hide()
|
alert(text: error.localizedDescription)
|
break
|
}
|
}).disposed(by: disposeBag)
|
}
|
|
func getPinYin(from aString: String) -> String {
|
//转变成可变字符串
|
let mutableString = NSMutableString.init(string: aString)
|
|
//将中文转换成带声调的拼音
|
CFStringTransform(mutableString as CFMutableString, nil, kCFStringTransformToLatin, false)
|
|
//去掉声调
|
let pinyinString = mutableString.folding(options: String.CompareOptions.diacriticInsensitive, locale: NSLocale.current)
|
|
return pinyinString
|
}
|
|
func getFirstLetter(from aString: String) -> String {
|
//截取大写首字母
|
let firstString = aString.prefix(1).uppercased()
|
|
//判断首字母是否为大写
|
let regexA = "^[A-Z]$"
|
let predA = NSPredicate.init(format: "SELF MATCHES %@", regexA)
|
return predA.evaluate(with: firstString) ? firstString : "#"
|
}
|
}
|
|
|
// MARK: - UITableViewDelegate
|
extension SwitchCityVC:UITableViewDelegate{
|
|
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
|
return 44
|
}
|
|
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
|
return 30
|
}
|
|
func sectionIndexTitles(for tableView: UITableView) -> [String]? {
|
return sectionTitles
|
}
|
|
|
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
tableView.deselectRow(at: indexPath, animated: true)
|
let model = self.viewModel.cities.value[indexPath.section].items[indexPath.row]
|
if global{
|
YYLocationManager.shared.currentCity = model.name
|
YYLocationManager.shared.currentCityCode = model.content
|
YYLocationManager.shared.id = model.id
|
YYMapViewManager.share.setCenter(center: CLLocationCoordinate2D.init(latitude: CLLocationDegrees(CGFloat(model.lat)), longitude: CLLocationDegrees(CGFloat(model.lon))))
|
yy_pop()
|
NotificationCenter.default.post(Notification.init(name: Notification.Name(rawValue: SwitchCityNotification)))
|
}else{
|
yy_pop()
|
self.refresh?(model,global)
|
}
|
|
}
|
}
|
|
// MARK: - UITableViewDelegate
|
extension SwitchCityVC:UITableViewDataSource{
|
|
func numberOfSections(in tableView: UITableView) -> Int {
|
return self.viewModel.cities.value.count
|
}
|
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
return self.viewModel.cities.value[section].items.count
|
}
|
|
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
let cell = tableView.dequeueReusableCell(withIdentifier: "item", for: indexPath)
|
cell.textLabel?.text = viewModel.cities.value[indexPath.section].items[indexPath.row].name
|
cell.textLabel?.font = UIFont.systemFont(ofSize: 14)
|
cell.textLabel?.textColor = UIColor.color(light: UIColor.color(hexString: "#333333"), dark: UIColor.color(hexString: "#333333"))
|
cell.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
|
return cell
|
}
|
|
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
|
let view = tableView.dequeueReusableHeaderFooterView(withClass: YYTitleWithButtonHeaderView.self)
|
view.label_title.text = viewModel.cities.value[section].letter
|
return view
|
}
|
}
|