You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
271 lines
11 KiB
271 lines
11 KiB
// |
|
// SportViewControllers.swift |
|
// HPlusFit |
|
// |
|
// Created by lemo. on 2019/7/14. |
|
// Copyright © 2019 lemo. All rights reserved. |
|
// |
|
|
|
import UIKit |
|
import RxCocoa |
|
|
|
// MARK:- 复用 |
|
fileprivate enum Resuable { |
|
static let sportCell = ReusableCell<SportCell>(nibName: "SportCell") |
|
} |
|
|
|
class SportViewControllers: TableViewController { |
|
|
|
/// 标题按钮 |
|
lazy var titleView: UIButton = { |
|
let btn = UIButton().then { |
|
$0.setTitleColor(kHexColor(0x2A2A2A), for: .normal) |
|
$0.setTitle(MultiLanguageKey.allSportFB.localized, for: .normal) |
|
$0.setImage(R.image.sport_history_up(), for: .normal) |
|
$0.setImage(R.image.sport_history_down(), for: .selected) |
|
$0.titleLabel?.font = SystemMediumFont(20) |
|
$0.changgeImageAndTitleEdgeInsets(type: 1, spacing: 5.0) |
|
$0.sizeToFit() |
|
} |
|
return btn |
|
}() |
|
/// 运动分类选择 |
|
lazy var sportCategoryView: SportHistoryCategoryView = { |
|
let temp = SportHistoryCategoryView(frame: view.bounds) |
|
return temp |
|
}() |
|
/// 日期选择 |
|
private lazy var dateHeaderView: DateSwitchHeaderView = { |
|
let view = DateSwitchHeaderView(frame: CGRect(x: 0, y: 0, width: kScreenW, height: kScaleHeight(103))) |
|
view.segControlValueChangeClosure = { [weak self] (type) in |
|
guard let `self` = self else { return } |
|
guard let viewModel = self.viewModel as? SportViewModels else { return } |
|
let dateStr: String = DateClass.todayString() |
|
var queryType: DataQueryType = .day |
|
if type == .week { |
|
queryType = .week |
|
}else if type == .month { |
|
queryType = .month |
|
} |
|
viewModel.loadSportData(timeStr: dateStr, queryType: queryType) |
|
} |
|
view.dateSelectedClosure = { [weak self] (selectedDateStr) in |
|
guard let `self` = self else { return } |
|
guard let viewModel = self.viewModel as? SportViewModels else { return } |
|
viewModel.loadSportData(timeStr: selectedDateStr, queryType: nil) |
|
} |
|
return view |
|
}() |
|
// 头视图 |
|
lazy var sportHeaderView: SportHeaderView = { |
|
let nib = UINib.init(nibName: "SportHeaderView", bundle: nil) |
|
let v = nib.instantiate(withOwner: nil, options: nil)[0] as! SportHeaderView |
|
return v |
|
}() |
|
let rxDataSource = RxTableViewSectionedReloadDataSource |
|
<HealthSection>(configureCell: { |
|
(dataSource, tv, indexPath, element) in |
|
switch element { |
|
case .sportItem(let viewModel): |
|
let cell = tv.dequeue(Resuable.sportCell, for: indexPath) |
|
cell.bind(model: viewModel) |
|
return cell |
|
default: return UITableViewCell() |
|
} |
|
}, canEditRowAtIndexPath: { (_ , _) -> Bool in |
|
return true |
|
}) |
|
private lazy var nodataView: NoDataView = { |
|
let noDataView = NoDataView(frame: CGRect.zero, tip: MultiLanguageKey.noDataTipFB.localized, type: .sport) |
|
noDataView.isHidden = false |
|
noDataView.backgroundColor = kHexColor(0xffffff) |
|
return noDataView |
|
}() |
|
|
|
override func viewDidLoad() { |
|
super.viewDidLoad() |
|
//self.bindViewModel() |
|
// BluetoothService.shared.syncState |
|
// .flatMapLatest { (state) -> Observable<String> in |
|
// switch state { |
|
// case .normal: NSLog(MultiLanguageKey.syncDataFB.localized) |
|
// case .syncing(_): self.bindViewModel() //return Observable.just("\(Int(progrss * 100))%") |
|
// default: break |
|
// } |
|
// |
|
// } |
|
|
|
} |
|
override func viewWillAppear(_ animated: Bool) { |
|
super.viewWillAppear(true) |
|
// if BluetoothService.shared.checkBleCmdEnable(isShow: false) { |
|
// BluetoothService.shared.sendSyncDeviceData() |
|
// |
|
// } |
|
super.bindViewModel() |
|
} |
|
|
|
override func makeUI() { |
|
super.makeUI() |
|
view.backgroundColor = .white |
|
view.addSubview(dateHeaderView) |
|
view.addSubview(nodataView) |
|
// titleView |
|
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: titleView) |
|
// tableView |
|
tableViewStyle = .grouped |
|
tableView.rx.setDelegate(self).disposed(by: rx.disposeBag) |
|
tableView.tableHeaderView = sportHeaderView |
|
tableView.register(Resuable.sportCell) |
|
tableView.separatorStyle = .none |
|
tableView.rowHeight = kScaleHeight(80) |
|
tableView.backgroundColor = .white |
|
|
|
layoutUI() |
|
} |
|
|
|
func layoutUI() { |
|
tableView.snp.makeConstraints { (make) in |
|
make.top.equalTo(dateHeaderView.snp.bottom) |
|
make.left.right.bottom.equalToSuperview() |
|
} |
|
nodataView.snp.makeConstraints { (make) in |
|
make.edges.equalTo(tableView.snp.edges) |
|
} |
|
view.bringSubviewToFront(nodataView) |
|
} |
|
|
|
override func bindViewModel() { |
|
guard let viewModel = viewModel as? SportViewModels else { return } |
|
let dataSource = viewModel.relay.asObservable() |
|
.share(replay: 1) |
|
dataSource |
|
.bind(to: tableView.rx.items(dataSource: rxDataSource)) |
|
.disposed(by: rx.disposeBag) |
|
dataSource.subscribe(onNext: { [weak self] (sections) in |
|
// 无数据处理 |
|
let isHidden = sections.count != 0 |
|
self?.nodataView.isHidden = isHidden |
|
}) |
|
.disposed(by: rx.disposeBag) |
|
// 头部视图数据绑定 |
|
dataSource |
|
.subscribe(onNext: { [weak self] _ in |
|
self?.sportHeaderView.refreshUI(sports: viewModel.sportModelArr) |
|
}) |
|
.disposed(by: rx.disposeBag) |
|
// 运动分类数据绑定 |
|
viewModel.sportCategoryVariable.asObservable() |
|
.bind(to: sportCategoryView.tableView.rx.items(dataSource: sportCategoryView.rxDataSource)) |
|
.disposed(by: rx.disposeBag) |
|
// 运动分类高度数据绑定 |
|
viewModel.cateforyHieghtVariable.asObservable() |
|
.bind(to: sportCategoryView.rx.snpHeight()) |
|
.disposed(by: rx.disposeBag) |
|
} |
|
|
|
override func handleEvent() { |
|
super.handleEvent() |
|
titleView.rx.tap |
|
.subscribe({ [weak self] _ in |
|
guard let `self` = self else { return } |
|
// 点击展示运动分类选择 |
|
if self.titleView.isSelected { |
|
self.sportCategoryView.dimiss() |
|
}else { |
|
self.sportCategoryView.show(to: self.view) |
|
} |
|
self.titleView.isSelected = !self.titleView.isSelected |
|
// 禁用0.2秒,动画时间 |
|
self.titleView.isUserInteractionEnabled = false |
|
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2, execute: { |
|
self.titleView.isUserInteractionEnabled = true |
|
}) |
|
}) |
|
.disposed(by: rx.disposeBag) |
|
|
|
sportCategoryView.tableView.rx.modelSelected(SportType.self) |
|
.subscribe(onNext: { [weak self] result in |
|
guard let `self` = self else { return } |
|
guard let viewModel = self.viewModel as? SportViewModels else { return } |
|
// 标题视图更新 |
|
self.titleView.isSelected = !self.titleView.isSelected |
|
self.titleView.setTitle(result.sportTypeName.localized, for: .normal) |
|
self.titleView.changgeImageAndTitleEdgeInsets(type: 1, spacing: 5.0) |
|
// 切换运动类型 |
|
viewModel.switchSportTypeData(sportType: result) |
|
// 隐藏 |
|
self.sportCategoryView.dimiss() |
|
}) |
|
.disposed(by: rx.disposeBag) |
|
sportCategoryView.touchesBegan = { [weak self] in |
|
guard let `self` = self else { return } |
|
// 标题视图更新 |
|
self.titleView.isSelected = !self.titleView.isSelected |
|
} |
|
tableView.rx.modelSelected(HealthSectionItem.self) |
|
.subscribe(onNext: { [weak self] (item) in |
|
switch item { |
|
case .sportItem(let viewModel): |
|
let vm = SportDetailViewModels(sportModel: viewModel.sportModel) |
|
self?.navigator.show(segue: .sportDetail(viewModel: vm), sender: self) |
|
default: break |
|
} |
|
}) |
|
.disposed(by: rx.disposeBag) |
|
// tableView.rx.modelDeleted(SportModel.self) |
|
// .subscribe(onNext: { [weak self] (sportModel) in |
|
// guard let `self` = self else { return } |
|
// // 删除运动 |
|
// ShowMessage(self, "确定删除选中运动吗?", cancelText: "NO", confirmText: "YES", handle: { (result) in |
|
// if result { |
|
// self.viewModel.deleteSport(sportModel: sportModel) |
|
// } |
|
// }) |
|
// }) |
|
// .disposed(by: rx.disposeBag) |
|
} |
|
|
|
} |
|
|
|
|
|
// MARK:- UITableViewDelegate |
|
extension SportViewControllers: UITableViewDelegate { |
|
|
|
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { |
|
return kScaleHeight(40) |
|
} |
|
|
|
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { |
|
let view = UIView() |
|
view.backgroundColor = kHexColor(0xFFFFFF) |
|
// 时间 |
|
let _ = UILabel(frame: CGRect(x: kScaleWidth(15), y: 0, width: 200, height: kScaleHeight(40))).then { |
|
$0.text = rxDataSource[section].title |
|
$0.font = SystemRegularFont(16) |
|
$0.textColor = kHexColor(0x2A2A2A) |
|
view.addSubview($0) |
|
} |
|
// 总里程 / 次数 |
|
let items = rxDataSource.sectionModels[section].items |
|
var distance = 0 |
|
items.forEach { (item) in |
|
switch item { |
|
case .sportItem(let viewModel): |
|
distance += viewModel.sportModel.distance |
|
default: break |
|
} |
|
} |
|
let metric = UserDefaultsManager.getUserInfo()?.metricUnit ?? 0 |
|
let distanceStr = metric == 0 ? String(format: "%0.2lfkm",CGFloat(distance) / 1000.0) : String(format: "%0.2lfmiles", CGFloat(distance) / 1000.0 * 0.62137) |
|
let _ = UILabel(frame: CGRect(x: kScreenW - 200 - kScaleWidth(15), y: 0, width: 200, height: kScaleHeight(40))).then { |
|
$0.text = distanceStr + " " + "\(items.count)" + MultiLanguageKey.timeFB.localized |
|
$0.font = SystemLightFont(12) |
|
$0.textColor = kHexColor(0x2A2A2A) |
|
$0.textAlignment = .right |
|
view.addSubview($0) |
|
} |
|
return view |
|
} |
|
|
|
}
|
|
|