| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- //
- // IBNumberEditText.swift
- // MTP2_iOS
- //
- // Created by Handy_Cao on 2018/11/10.
- // Copyright © 2018 Muchinfo. All rights reserved.
- //
- import UIKit
- /// 输入框按钮类型
- ///
- /// - Add: 加
- /// - Subtract: 减
- enum NumberInputViewButtonType {
- case Add
- case Subtract
- }
- @IBDesignable
- class IBNumberEditText: UIView {
-
- // MARK: - 属性列表
- /// 减号
- @IBOutlet weak var minusBtn: IBButton!
- /// 加号
- @IBOutlet weak var addBtn: IBButton!
- /// 输入框
- @IBOutlet weak var numberField: IBTextField!
- /// 定义container为DemoView的子view, 以便更方便的封装xib
- @IBOutlet weak var containerView: UIView!
- /// 小数位,如果需要则设置
- var decimalPlace: Int?
- /// 增量(默认值为1)
- var incrementIntNum = 1
- /// 增量值
- var incrementDoubleNum: Double = 1.0
- /// 最大值
- var maxIntNum = Int.max
- /// 最大值
- var maxDoubleNum = Double(Int.max)
- /// 最小值
- var minIntNum = 0
- var minDoubleNum = 0.0
- /// 是否循环
- var isWarp = false
- /// 不允许交互
- override var isUserInteractionEnabled: Bool {
- didSet {
- addBtn.setBackgroundImage(UIImage(named: isUserInteractionEnabled ? "add_enable" : "add_unenable"), for: .normal)
- minusBtn.setBackgroundImage(UIImage(named: isUserInteractionEnabled ? "sub_enable" : "sub_unenable"), for: .normal)
- numberField.textColor = UIColorFromHex(rgbValue: isUserInteractionEnabled ? 0x3384F3 : 0x999999)
- }
- }
- /// 代理
- weak var delegate: IBNumberEditTextDelegate?
- /// 需要的值类型 1: Int 2: Double
- var valueType = 1 {
- didSet {
- switch valueType {
- case 1:
- numberField.keyboardType = .numberPad
- default:
- numberField.keyboardType = .decimalPad
- }
- }
- }
-
- /// 当前Int值
- var currentIntNumbers: Int {
- get {
- return Int(numberField.text!) ?? 0
- }
- set {
- if newValue > maxIntNum {
- numberField.text = String(maxIntNum)
- } else {
- numberField.text = String(newValue)
- }
- delegate?.IBNumberEditText(textField: numberField)
- }
- }
-
- /// 当前Double值
- var currentDoubleNumbers: Double {
- get {
- if let decimalPlace = decimalPlace {
- /// FIXME: - 暂时用于解决浮点数计算失真问题
- return Double(String(format: "%.\(decimalPlace)f", Double(numberField.text!) ?? 0)) ?? 0
- } else {
- return Double(numberField.text!) ?? 0
- }
- }
- set {
- if let decimalPlace = decimalPlace {
- if Double(Int(newValue)) == newValue {
- numberField.text = newValue.toString(reserve: decimalPlace)
- } else {
- numberField.text = String(format: "%.\(decimalPlace)f", newValue)
- }
- } else {
- if Double(Int(newValue)) == newValue {
- numberField.text = newValue.toString(reserve: decimalPlace ?? 0)
- } else {
- numberField.text = newValue.toString(reserve: decimalPlace ?? 0)
- }
- }
- delegate?.IBNumberEditText(textField: numberField)
- }
- }
-
- // MARK: - 生命周期
- override init(frame: CGRect) {
- super.init(frame: frame)
- initViewFromNib()
- }
-
- required init?(coder aDecoder: NSCoder) {
- super.init(coder: aDecoder)
- initViewFromNib()
- }
-
- private func initViewFromNib() {
- /// 需要这句代码,不能直接写UINib(nibName: "MyView", bundle: nil),不然不能在storyboard中显示
- let bundle = Bundle.init(for: self.classForCoder)
- let nib = UINib(nibName: "NumberEditText", bundle: bundle)
- containerView = nib.instantiate(withOwner: self, options: nil)[0] as? UIView
- containerView.frame = bounds
- addSubview(containerView)
- }
-
- override func awakeFromNib() {
- NotificationCenter.default.addObserver(self, selector: #selector(valueChanged), name: UITextField.textDidChangeNotification, object: numberField)
- }
-
- @objc fileprivate func valueChanged() {
- delegate?.IBNumberEditText(textField: numberField)
- }
-
- deinit {
- NotificationCenter.default.removeObserver(self)
- }
-
- // MARK: - 交互相关
- @IBAction func onButtonPressed(_ sender: IBButton) {
- switch sender {
- case addBtn:
- if valueType == 1 {
- if currentIntNumbers < maxIntNum {
- currentIntNumbers += incrementIntNum
- } else if isWarp {
- currentIntNumbers = minIntNum
- }
- } else {
- if currentDoubleNumbers < maxDoubleNum {
- currentDoubleNumbers += incrementDoubleNum
- } else if isWarp {
- currentDoubleNumbers = minDoubleNum
- }
- }
-
- /// 出发代理
- guard let delegate = self.delegate else { return }
- delegate.numberInputView(self, .Add)
-
- case minusBtn:
- if valueType == 1 {
- if currentIntNumbers > minIntNum {
- currentIntNumbers -= incrementIntNum
- } else if isWarp {
- currentIntNumbers = maxIntNum
- }
- } else {
- if currentDoubleNumbers > minDoubleNum {
- currentDoubleNumbers -= incrementDoubleNum
- } else if isWarp {
- currentDoubleNumbers = maxDoubleNum
- }
- }
-
- /// 出发代理
- guard let delegate = self.delegate else { return }
- delegate.numberInputView(self, .Subtract)
- default:
- break
- }
-
- /// 通知值变化
- delegate?.IBNumberEditText(textField: numberField)
- }
- }
- extension IBNumberEditText: UITextFieldDelegate {
- func textFieldDidBeginEditing(_ textField: UITextField) {
- if Double(textField.text!) == 0 {
- textField.text = ""
- }
- }
-
- func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
-
- /// 解决删除按钮失效问题
- if (range.length == 1 && string.count == 0) {
-
- return true
- }
-
- if let decimalPlace = decimalPlace,
- let num = textField.text?.split(separator: ".").compactMap(String.init),
- num.count == 2, num[1].count == decimalPlace {
-
- return false
- }
-
- return true
- }
-
- func textFieldDidEndEditing(_ textField: UITextField) {
- /// 类型为整数型
- if valueType == 1 {
- self.currentIntNumbers = Int(self.currentIntNumbers/self.incrementIntNum)*Int(self.incrementIntNum)
- }
-
- /// numberInputViewDidEndEditing
- delegate?.numberInputViewDidEndEditing(self)
- }
- }
- protocol IBNumberEditTextDelegate: class {
- /// valueChanged 触发
- ///
- /// - Parameter textField: 值变化的输入框
- func IBNumberEditText(textField: UITextField)
-
- /// 按钮点击出发
- ///
- /// - Parameters:
- /// - buttonType: 按钮类型
- func numberInputView(_ numberInputView: IBNumberEditText, _ buttonType: NumberInputViewButtonType)
-
- /// numberInputViewDidEndEditing
- /// - Parameter numberInputView: numberInputView
- func numberInputViewDidEndEditing(_ numberInputView: IBNumberEditText)
- }
|