Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // CustomPickerView.swift
- // ARIUIKit
- //
- // Created by ait belarbi mohamed amine on 17/01/2020.
- //
- import UIKit
- public struct PickerViewStyle {
- let name, type: String?
- let textStyleLabel, textStyleHelp, textStyleInput, textStyleFeedback: TextStyleByStates?
- let radius: [CGFloat]?
- let states: InputStyleByState?
- public init(name: String?,
- type: String?,
- textStyleLabel: TextStyleByStates?,
- textStyleHelp: TextStyleByStates?,
- textStyleInput: TextStyleByStates?,
- textStyleFeedback: TextStyleByStates?,
- radius: [CGFloat]?,
- states: InputStyleByState? ) {
- self.name = name
- self.type = type
- self.textStyleLabel = textStyleLabel
- self.textStyleHelp = textStyleHelp
- self.textStyleInput = textStyleInput
- self.textStyleFeedback = textStyleFeedback
- self.radius = radius
- self.states = states
- }
- }
- public struct CustomPickerViewModel {
- let id: String
- let required: Bool?
- let title, helpTitle, prefill: String?
- var items: [ComponentItemsViewModel]?
- let autovalidate: Bool?
- let style: PickerViewStyle?
- let pickerType: ComponentTypeViewModel?
- let onAutoValidate: (() -> ())?
- var state: InputState?
- public init(id: String,
- required: Bool?,
- title: String?,
- helpTitle: String?,
- prefill: String?,
- items: [ComponentItemsViewModel]?,
- pickerViewStyle: PickerViewStyle?,
- pickerType: ComponentTypeViewModel? = .text,
- autovalidate: Bool?,
- state: InputState = .empty,
- onAutoValidate: (() -> ())? = nil) {
- self.id = id
- self.required = required
- self.title = title
- self.helpTitle = helpTitle
- self.prefill = prefill
- self.items = items
- self.style = pickerViewStyle
- self.pickerType = pickerType
- self.autovalidate = autovalidate
- self.state = state
- self.onAutoValidate = onAutoValidate
- }
- }
- public final class CustomPickerView: UIView {
- static let identifier = String(describing: CustomPickerView.self)
- @IBOutlet private weak var helpLabel: UILabel!
- @IBOutlet private weak var titleLabel: UILabel!
- @IBOutlet private weak var arrowImageView: UIImageView! {
- didSet {
- arrowImageView.image = UIImage.tinyArrowDown
- }
- }
- @IBOutlet private weak var containerView: UIView!
- @IBOutlet private weak var currentValueLabel: UILabel!
- @IBOutlet private weak var helpLabelContainerView: UIView!
- @IBOutlet private weak var titleLabelContainerView: UIView!
- public var listContainer = UITextField(frame: .zero)
- public var currentValue: String {
- get {
- let prefillData = viewModel?.pickerType == .date ? currentValueLabel.text : viewModel.items?.filter { $0.selected == true }.first?.value
- return prefillData ?? ""
- }
- }
- public var viewModel: CustomPickerViewModel! {
- didSet {
- updateUI()
- }
- }
- required public init?(coder aDecoder: NSCoder) {
- super.init(coder: aDecoder)
- loadNib()
- }
- public init() {
- super.init(frame: .zero)
- loadNib()
- }
- private func loadNib() {
- let nib = UINib(nibName: CustomPickerView.identifier, bundle: ARIUIKit.bundle)
- guard let contentView = nib.instantiate(withOwner: self, options: nil).first as? UIView else {
- return
- }
- addSubview(contentView)
- contentView.translatesAutoresizingMaskIntoConstraints = false
- contentView.layoutAttachAll(to: self)
- }
- public override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
- super.touchesBegan(touches, with: event)
- setInputStyleBy(inputEvent: .highlight)
- }
- public override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
- super.touchesEnded(touches, with: event)
- toucheEnded(touches: touches)
- }
- public override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
- super.touchesCancelled(touches, with: event)
- toucheEnded(touches: touches)
- }
- private func toucheEnded(touches: Set<UITouch>) {
- setInputStyleBy(inputEvent: .default)
- listContainer.becomeFirstResponder()
- }
- public func showError() {
- viewModel.state = .error
- }
- private func updateUI() {
- helpLabelContainerView.isHidden = viewModel?.helpTitle?.isEmpty ?? true ? true : false
- helpLabel.text = viewModel?.helpTitle
- titleLabel.text = viewModel?.title
- currentValueLabel.text = viewModel.items?.filter { $0.selected == true }.first?.label ?? viewModel?.prefill
- setInputStyle()
- setCornerRadius()
- setInputStyleBy(inputEvent: .default)
- initPickerView(type: (viewModel?.pickerType ?? .text))
- listContainer.delegate = self
- }
- private func setCornerRadius() {
- var corners: UIRectCorner = []
- var radius: CGFloat = 0.0
- if let topLeftCorner = viewModel.style?.radius?[0], topLeftCorner > 0 {
- corners.insert(.topLeft)
- radius = topLeftCorner
- }
- if let topRightCorner = viewModel.style?.radius?[1], topRightCorner > 0 {
- corners.insert(.topRight)
- radius = topRightCorner
- }
- if let bottomLeftCorner = viewModel.style?.radius?[2], bottomLeftCorner > 0 {
- corners.insert(.bottomLeft)
- radius = bottomLeftCorner
- }
- if let bottomRighttCorner = viewModel.style?.radius?[3], bottomRighttCorner > 0 {
- corners.insert(.bottomRight)
- radius = bottomRighttCorner
- }
- containerView.roundCorners(corners, radius: radius)
- }
- private func initPickerView(type: ComponentTypeViewModel) {
- if type == .date {
- let datePicker: UIDatePicker = UIDatePicker()
- datePicker.datePickerMode = .date
- if let strDate = viewModel.title {
- let dateFormatter = ISO8601DateFormatter()
- dateFormatter.formatOptions = [.withFullDate]
- if let date = dateFormatter.date(from: strDate) {
- datePicker.date = date
- }
- }
- datePicker.addTarget(self, action: #selector(dateChanged(_:)), for: .valueChanged)
- listContainer.inputView = datePicker
- } else {
- let listPicker: UIPickerView = UIPickerView()
- listPicker.dataSource = self
- listPicker.delegate = self
- listContainer.inputView = listPicker
- }
- self.addSubview(listContainer)
- }
- @objc func dateChanged(_ sender: UIDatePicker) {
- let dateFormatter = ISO8601DateFormatter()
- dateFormatter.formatOptions = [.withFullDate]
- let strDate = dateFormatter.string(from: sender.date)
- currentValueLabel.text = strDate
- }
- private func setInputStyle() {
- var textStyleLabel: TextStyle?
- var textStyleInput: TextStyle?
- var textStyleHelp: TextStyle?
- var textStyleFeedback: TextStyle?
- switch viewModel.state {
- case .default:
- textStyleInput = viewModel.style?.textStyleInput?.default
- textStyleLabel = viewModel.style?.textStyleLabel?.default
- textStyleHelp = viewModel.style?.textStyleHelp?.default
- textStyleFeedback = viewModel.style?.textStyleFeedback?.default
- case .success:
- textStyleInput = viewModel.style?.textStyleInput?.success
- textStyleLabel = viewModel.style?.textStyleLabel?.success
- textStyleHelp = viewModel.style?.textStyleHelp?.success
- textStyleFeedback = viewModel.style?.textStyleFeedback?.success
- case .empty:
- textStyleInput = viewModel.style?.textStyleInput?.empty
- textStyleLabel = viewModel.style?.textStyleLabel?.empty
- textStyleHelp = viewModel.style?.textStyleHelp?.empty
- textStyleFeedback = viewModel.style?.textStyleFeedback?.empty
- case .error:
- textStyleInput = viewModel.style?.textStyleInput?.error
- textStyleLabel = viewModel.style?.textStyleLabel?.error
- textStyleHelp = viewModel.style?.textStyleHelp?.error
- textStyleFeedback = viewModel.style?.textStyleFeedback?.error
- case .none:
- break
- }
- if let textStyle = textStyleLabel {
- titleLabel.setStyle(textStyle)
- }
- if let textStyle = textStyleHelp {
- helpLabel.setStyle(textStyle)
- }
- if let textStyle = textStyleInput {
- currentValueLabel.setStyle(textStyle)
- }
- }
- private func setInputStyleBy(inputEvent: InputEvent) {
- switch viewModel.state {
- case .default:
- if let df = viewModel.style?.states?.default {
- setInputStyle(inputStyleByEvent: df, inputEvent: inputEvent)
- }
- case .success:
- if let success = viewModel.style?.states?.success {
- setInputStyle(inputStyleByEvent: success, inputEvent: inputEvent)
- }
- case .empty:
- if let empty = viewModel.style?.states?.empty {
- setInputStyle(inputStyleByEvent: empty, inputEvent: inputEvent)
- }
- case .error:
- if let error = viewModel.style?.states?.error {
- setInputStyle(inputStyleByEvent: error, inputEvent: inputEvent)
- }
- case .none:
- break
- }
- }
- private func setInputStyle(inputStyleByEvent: InputStyleByEvent, inputEvent: InputEvent) {
- switch inputEvent {
- case .default:
- if let background = inputStyleByEvent.default?.background {
- setInputBackground(style: background)
- }
- case .highlight:
- if let background = inputStyleByEvent.highlight?.background {
- setInputBackground(style: background)
- }
- case .selected:
- if let background = inputStyleByEvent.selected?.background {
- setInputBackground(style: background)
- }
- }
- }
- private func setInputBackground(style: BackgroundStyle) {
- switch style.fill?.type {
- case .solid:
- containerView.backgroundColor = style.fill?.colors?.first ?? .white
- case .gradient:
- if let firstColor = style.fill?.colors?[0],
- let secondColor = style.fill?.colors?[1] {
- containerView.removeGradientBackgroundIfNeeded()
- containerView.addGradientBackground(direction: .leftToRight, color1: firstColor, color2: secondColor)
- }
- case .none:
- break
- }
- }
- }
- extension CustomPickerView: UITextFieldDelegate {
- public func textFieldDidEndEditing(_ textField: UITextField) {
- if viewModel?.autovalidate == true, let onAutoValidate = viewModel?.onAutoValidate {
- onAutoValidate()
- }
- }
- }
- extension CustomPickerView: UIPickerViewDelegate, UIPickerViewDataSource {
- public func numberOfComponents(in pickerView: UIPickerView) -> Int {
- return 1
- }
- public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
- return viewModel?.items?.count ?? 0
- }
- public func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
- return viewModel?.items?[row].label
- }
- public func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
- currentValueLabel.text = viewModel?.items?[row].label
- var selectedIndex: Int = 0
- var i: Int = 0
- viewModel.items?.forEach {
- if $0.selected == true {
- selectedIndex = i
- return
- }
- i += 1
- }
- viewModel?.items?[selectedIndex].selected = false
- viewModel?.items?[row].selected = true
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement