Last active
November 5, 2019 10:44
-
-
Save daryadariaa/12b45233470f0f629c6bd8834a63dc7e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import RxSwift | |
import RxCocoa | |
class AddDiscountTableViewCell: UITableViewCell { | |
@IBOutlet weak var discountTypeDropDown: SelectionDropDownView! | |
@IBOutlet weak var amountTextField: PrimaryTextField! | |
@IBOutlet weak var itemsDropDown: SelectionDropDownView! | |
static var identifier = "AddDiscountTableViewCell" | |
private var disposeBag = DisposeBag() | |
override func awakeFromNib() { | |
super.awakeFromNib() | |
configureView() | |
bind() | |
} | |
override func prepareForReuse() { | |
super.prepareForReuse() | |
disposeBag = DisposeBag() | |
} | |
private func configureView() { | |
discountTypeDropDown.placeholder = "discount".localized() | |
amountTextField.placeholder = "amount".localized() | |
} | |
private func bind() { | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import RxSwift | |
import RxCocoa | |
import MaterialComponents | |
protocol SelectionDropDownViewDelegate: class { | |
func didSelectItem(dropDown: SelectionDropDownView, item: DropdownItem) | |
func didDeselectItem(dropDown: SelectionDropDownView, item: DropdownItem) | |
} | |
enum SelectionDropDownType { | |
case `default` | |
case checkmark | |
} | |
class SelectionDropDownView: UIView { | |
private struct Constants { | |
static let smallPlaceholderFontSize: CGFloat = 12 | |
static let bigPlaceholderFontSize: CGFloat = 16 | |
static let leftRightMargin: CGFloat = 12 | |
static let topBottomMargin: CGFloat = 8 | |
} | |
private let disposeBag = DisposeBag() | |
private let smallPlaceholderLabel = UILabel() | |
private let bigPlaceholderLabel = UILabel() | |
private let valueLabel = UILabel() | |
private let bottomLineView = UIView() | |
private let dismissGesture = UITapGestureRecognizer() | |
private let optionsViewController = DropdownListTableViewController.storyboardViewController() | |
fileprivate let openSubject = PublishSubject<Void>() | |
var type: SelectionDropDownType = .default { | |
didSet { | |
optionsViewController.type = type | |
} | |
} | |
var placeholder: String? { | |
didSet { | |
smallPlaceholderLabel.text = placeholder | |
bigPlaceholderLabel.text = placeholder | |
} | |
} | |
var value: String? { | |
didSet { | |
valueLabel.text = value | |
valueLabel.isHidden = value == nil | |
smallPlaceholderLabel.isHidden = value == nil | |
bigPlaceholderLabel.isHidden = value != nil | |
} | |
} | |
var selectedItem: DropdownItem? { | |
get { | |
return selectedItems.first | |
} | |
set { | |
if let item = newValue, type == .default { | |
selectedItems.removeAll() | |
selectedItems.append(item) | |
} | |
} | |
} | |
var selectedItems = [DropdownItem]() { | |
didSet { | |
switch type { | |
case .default: | |
value = selectedItems.first?.title | |
case .checkmark: | |
if selectedItems.count > 1 { | |
value = String(format: "items-count".localized(), NSNumber(value: selectedItems.count)); | |
} else { | |
value = String(format: "item-count".localized(), NSNumber(value: selectedItems.count)); | |
} | |
} | |
} | |
} | |
weak var delegate: SelectionDropDownViewDelegate? | |
override init(frame: CGRect) { | |
super.init(frame: frame) | |
commonInit() | |
} | |
required init?(coder: NSCoder) { | |
super.init(coder: coder) | |
commonInit() | |
} | |
func present(in viewController: UIViewController, options: [DropdownItem]) { | |
guard !options.isEmpty else { | |
return | |
} | |
bottomLineView.backgroundColor = .primary | |
optionsViewController.items = options | |
optionsViewController.selection = selectedItems | |
viewController.present(optionsViewController, animated: true) | |
} | |
private func commonInit() { | |
dismissGesture.delegate = self | |
optionsViewController.transitioningDelegate = self | |
optionsViewController.modalPresentationStyle = .custom | |
optionsViewController.delegate = self | |
configure() | |
bind() | |
} | |
private func configure() { | |
backgroundColor = .surface | |
layer.masksToBounds = false | |
layer.cornerRadius = AppearenceConfig.cornerRadius | |
layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] | |
smallPlaceholderLabel.font = .systemFont(ofSize: Constants.smallPlaceholderFontSize) | |
smallPlaceholderLabel.textColor = .textPlaceholder | |
smallPlaceholderLabel.isHidden = true | |
bigPlaceholderLabel.font = .systemFont(ofSize: Constants.bigPlaceholderFontSize) | |
bigPlaceholderLabel.textColor = .textPlaceholder | |
valueLabel.font = .systemFont(ofSize: Constants.bigPlaceholderFontSize) | |
valueLabel.textColor = .text | |
valueLabel.isHidden = true | |
let stackView = UIStackView() | |
stackView.translatesAutoresizingMaskIntoConstraints = false | |
stackView.axis = .vertical | |
stackView.addArrangedSubview(smallPlaceholderLabel) | |
stackView.addArrangedSubview(bigPlaceholderLabel) | |
stackView.addArrangedSubview(valueLabel) | |
addSubview(stackView) | |
stackView.leftAnchor.constraint(equalTo: leftAnchor, constant: Constants.leftRightMargin).isActive = true | |
stackView.topAnchor.constraint(equalTo: topAnchor, constant: Constants.topBottomMargin).isActive = true | |
stackView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -Constants.topBottomMargin).isActive = true | |
let arrowImageView = UIImageView(image: UIImage(named: "arrowDown")) | |
arrowImageView.translatesAutoresizingMaskIntoConstraints = false | |
addSubview(arrowImageView) | |
arrowImageView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true | |
arrowImageView.rightAnchor.constraint(equalTo: rightAnchor, constant: -Constants.leftRightMargin).isActive = true | |
bottomLineView.translatesAutoresizingMaskIntoConstraints = false | |
bottomLineView.backgroundColor = .blueShadow | |
addSubview(bottomLineView) | |
bottomLineView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true | |
bottomLineView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true | |
bottomLineView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true | |
bottomLineView.heightAnchor.constraint(equalToConstant: 1).isActive = true | |
} | |
private func bind() { | |
dismissGesture.rx.event.subscribe(onNext: { [unowned self] _ in | |
self.bottomLineView.backgroundColor = .blueShadow | |
self.optionsViewController.dismiss(animated: true) | |
}).disposed(by: disposeBag) | |
let tap = UITapGestureRecognizer() | |
addGestureRecognizer(tap) | |
tap.rx.event.subscribe(onNext: { [unowned self] gesture in | |
self.openSubject.onNext(()) | |
}).disposed(by: disposeBag) | |
} | |
} | |
extension SelectionDropDownView: UIViewControllerTransitioningDelegate { | |
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { | |
guard presented is DropdownListTableViewController else { | |
return nil | |
} | |
return DropdownPresentAnimation(action: .show, sourceView: self, dismissGesture: dismissGesture) | |
} | |
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { | |
return DropdownPresentAnimation(action: .hide, sourceView: self, dismissGesture: dismissGesture) | |
} | |
} | |
extension SelectionDropDownView: UIGestureRecognizerDelegate { | |
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { | |
let location = touch.location(in: optionsViewController.view) | |
return !optionsViewController.view.bounds.contains(location) | |
} | |
} | |
extension SelectionDropDownView: DropdownListTableViewControllerDelegate { | |
func didSelect(item: DropdownItem) { | |
switch type { | |
case .default: | |
selectedItems.removeAll() | |
selectedItems.append(item) | |
delegate?.didSelectItem(dropDown: self, item: item) | |
optionsViewController.dismiss(animated: true) | |
case .checkmark: | |
if !selectedItems.contains(item) && item.checked { | |
selectedItems.append(item) | |
delegate?.didSelectItem(dropDown: self, item: item) | |
} else { | |
selectedItems.removeAll(where: { $0 == item }) | |
delegate?.didDeselectItem(dropDown: self, item: item) | |
} | |
} | |
bottomLineView.backgroundColor = .blueShadow | |
} | |
} | |
extension Reactive where Base: SelectionDropDownView { | |
var tap: ControlEvent<Void> { | |
return ControlEvent(events: base.openSubject) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment