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.

358 lines
12 KiB

//
// PickerView.swift
// HPlusFit
//
// Created by lemo. on 2019/8/1.
// Copyright © 2019 lemo. All rights reserved.
//
import UIKit
// MARK:-
fileprivate struct Metric {
static let backgroundColor = kHexColor(0xFFFFFF)
static let cancleColor = kHexColor(0xED3131)
static let confirmColor = kHexColor(0x2C7AFF)
static let titleColor = kHexColor(0x888888)
static let generalFont = SystemLightFont(18)
}
enum PikcerType: Int {
case step, height, weight, birthday, duration, step1
}
class PickerView: UIView {
//
var currenValues: ((Int) -> ())?
//
var type: PikcerType = .height
private lazy var backgroundView: UIView = {
let view = UIView().then {
$0.backgroundColor = .white
addSubview($0)
}
return view
}()
private lazy var cancleBtn: UIButton = {
let btn = UIButton().then {
$0.setTitle(MultiLanguageKey.cancel.localized, for: .normal)
$0.setTitleColor(Metric.cancleColor, for: .normal)
$0.titleLabel?.font = Metric.generalFont
backgroundView.addSubview($0)
}
return btn
}()
private lazy var comfirmBtn: UIButton = {
let btn = UIButton(type: .custom).then {
$0.setTitle(MultiLanguageKey.confirm.localized, for: .normal)
$0.setTitleColor(Metric.confirmColor, for: .normal)
$0.titleLabel?.font = Metric.generalFont
backgroundView.addSubview($0)
}
return btn
}()
private lazy var titleLabel: UILabel = {
let label = UILabel().then {
$0.font = Metric.generalFont
$0.textColor = Metric.titleColor
backgroundView.addSubview($0)
}
return label
}()
private lazy var pickerView: UIPickerView = {
let picker = UIPickerView().then {
$0.delegate = self
$0.dataSource = self
backgroundView.addSubview($0)
}
return picker
}()
private lazy var datePicker: UIDatePicker = {
let pick = UIDatePicker()
pick.datePickerMode = .date
pick.backgroundColor = .white
pick.locale = Locale(identifier: "zh")
pick.backgroundColor = ThemeManager.bgColor
let dayTimestamp: Int64 = 86400
let seconds: Int64 = Int64(dayTimestamp * 365 * 100)
pick.minimumDate = Date(timeInterval: -TimeInterval(seconds), since: Date())
if #available(iOS 13.4, *) {
pick.preferredDatePickerStyle = .wheels
} else {
// Fallback on earlier versions
}
//
pick.maximumDate = Date()
backgroundView.addSubview(pick)
return pick
}()
//
private var dataSource: [[String]] = []
private lazy var steps: Array = { () -> [[String]] in
var steps: [String] = []
for step in stride(from: 3000, to: 100500, by: 500) {
steps.append(String(step))
}
let array: [[String]] = [[], steps, [MultiLanguageKey.stepTip.localized]]
return array
}()
private lazy var steps1: Array = { () -> [[String]] in
var steps1: [String] = []
for step1 in stride(from: 5000, to: 51000, by: 1000) {
steps1.append(String(step1))
}
let array1: [[String]] = [[], steps1, [MultiLanguageKey.stepTip.localized]]
return array1
}()
private lazy var heights: Array = { () -> [[String]] in
var heights: [String] = []
for height in 90...240 {
heights.append(String(height))
}
let array: [[String]] = [[], heights, ["cm"]]
return array
}()
private lazy var weights: Array = { () -> [[String]] in
var weights: [String] = []
for weight in 10...178 {
weights.append(String(weight))
}
let array: [[String]] = [[], weights, ["kg"]]
return array
}()
private lazy var durations: Array = { () -> [[String]] in
var hours: [String] = []
for hour in 1...23 {
hours.append(String(hour))
}
// var mins: [String] = []
// for min in 0...59 {
// mins.append(String(min))
// }
// let array: [[String]] = [hours, [MultiLanguageKey.hour.localized],mins, [MultiLanguageKey.min.localized]]
let array: [[String]] = [hours, [MultiLanguageKey.hour.localized]]
return array
}()
override init(frame: CGRect) {
super.init(frame: frame)
setUpUI()
handleEvent()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension PickerView {
///
/// - Parameters:
/// - values:
/// - type:
/// - view:
func show(values: Int, type: PikcerType = .height, view: UIView) {
self.type = type
switch type {
case .step, .height, .weight:
pickerView.isHidden = false
datePicker.isHidden = true
switchDataSource(type: type)
let intervalIndex = dataSource[1].firstIndex(of: "\(values)") ?? 0
pickerView.selectRow(intervalIndex, inComponent: 1, animated: false)
case .birthday:
pickerView.isHidden = true
datePicker.isHidden = false
let date = Date(timeIntervalSince1970: TimeInterval(values))
datePicker.setDate(date, animated: false)
titleLabel.text = MultiLanguageKey.birthday.localized
case .duration:
pickerView.isHidden = false
datePicker.isHidden = true
switchDataSource(type: type)
let hourIndex = values
// let hourIndex = values / 60
// let minIndex = values % 60
pickerView.selectRow(hourIndex-1, inComponent: 0, animated: false)
// pickerView.selectRow(minIndex, inComponent: 2, animated: false)
case .step1:
pickerView.isHidden = false
datePicker.isHidden = true
switchDataSource(type: type)
let intervalIndex = dataSource[1].firstIndex(of: "\(values)") ?? 0
pickerView.selectRow(intervalIndex, inComponent: 1, animated: false)
}
animation(isShow: true, view: view)
}
func dimiss() {
animation(isShow: false)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
dimiss()
}
}
extension PickerView {
fileprivate func setUpUI() {
backgroundColor = .clear
frame = CGRect(x: 0, y: 0, width: kScreenW, height: kScreenH - kNavibarH)
backgroundView.snp.makeConstraints { (make) in
make.height.equalTo(kScaleHeight(252))
make.left.right.equalToSuperview()
make.bottom.equalToSuperview().offset(kScaleHeight(252))
}
cancleBtn.snp.makeConstraints { (make) in
make.left.equalTo(kNavBarItemMargin)
make.top.equalToSuperview()
make.height.equalTo(kScaleHeight(50))
make.width.equalTo(60)
}
comfirmBtn.snp.makeConstraints { (make) in
make.right.equalTo(-kNavBarItemMargin)
make.top.equalToSuperview()
make.height.equalTo(kScaleHeight(50))
make.width.equalTo(60)
}
titleLabel.snp.makeConstraints { (make) in
make.top.equalTo(kScaleHeight(13))
make.height.equalTo(kScaleHeight(25))
make.centerX.equalToSuperview()
}
pickerView.snp.makeConstraints { (make) in
make.top.equalTo(kScaleHeight(50))
make.left.right.bottom.equalToSuperview()
}
datePicker.snp.makeConstraints { (make) in
make.top.equalTo(kScaleHeight(50))
make.left.right.bottom.equalToSuperview()
}
}
fileprivate func handleEvent() {
cancleBtn.rx.tap
.subscribe(onNext: { [weak self] in
self?.dimiss()
})
.disposed(by: rx.disposeBag)
comfirmBtn.rx.tap
.subscribe(onNext: { [weak self] in
var value = 0
guard let `self` = self else { return }
switch self.type {
case .step, .height, .weight:
value = self.dataSource[1][self.pickerView.selectedRow(inComponent: 1)].integerValue
case .step1:
value = self.dataSource[1][self.pickerView.selectedRow(inComponent: 1)].integerValue
case .birthday:
value = Int(self.datePicker.date.timeIntervalSince1970)
case .duration:
let hour = self.dataSource[0][self.pickerView.selectedRow(inComponent: 0)].integerValue
// let min = self.dataSource[2][self.pickerView.selectedRow(inComponent: 2)].integerValue
// value = hour * 60 + min
value = hour
}
if let result = self.currenValues {
result(value)
}
self.dimiss()
})
.disposed(by: rx.disposeBag)
}
fileprivate func animation(isShow: Bool, view: UIView? = nil) {
self.layoutIfNeeded()
if isShow {
guard let view = view else { return }
view.addSubview(self)
UIView.animate(withDuration: 0.3) {
self.backgroundView.snp.updateConstraints { (make) in
make.bottom.equalToSuperview().offset(0)
}
self.layoutIfNeeded()
}
return
}else {
UIView.animate(withDuration: 0.3, animations: {
self.backgroundView.snp.updateConstraints { (make) in
make.bottom.equalToSuperview().offset(252)
}
self.layoutIfNeeded()
}) { _ in
self.removeFromSuperview()
}
}
}
fileprivate func switchDataSource(type: PikcerType) {
//
switch type {
case .height:
titleLabel.text = MultiLanguageKey.height.localized
case .weight:
titleLabel.text = MultiLanguageKey.weight.localized
default:
break
}
//
switch type {
case .step:
dataSource = steps
case .step1:
dataSource = steps1
case .height:
dataSource = heights
case .weight:
dataSource = weights
case .duration:
dataSource = durations
default: break
}
pickerView.reloadAllComponents()
}
}
extension PickerView: UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return dataSource.count
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return dataSource[component].count
}
func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
return kScaleHeight(50)
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
// 线
for i in 0..<pickerView.subviews.count {
let singleLine = pickerView.subviews[i]
if singleLine.height <= 1 {
singleLine.backgroundColor = kHexColor(0xEBEBEB)
}
}
//
let label = UILabel().then {
let width = component == 1 ? kScaleWidth(55 * 2 + 32) : kScaleWidth(80)
$0.frame = CGRect(x: 0, y: 0, width: width, height: kScaleWidth(50))
$0.font = SystemMediumFont(18)
$0.text = dataSource[component][row]
$0.textAlignment = component == 0 ? .right : component == 1 ? .center : .left
$0.textColor = ThemeManager.commonTextColor
}
return label
}
}