Skip to content

Instantly share code, notes, and snippets.

@alfian0
Created July 3, 2020 12:11
Show Gist options
  • Select an option

  • Save alfian0/f729bee1d17614ac117135e74919216c to your computer and use it in GitHub Desktop.

Select an option

Save alfian0/f729bee1d17614ac117135e74919216c to your computer and use it in GitHub Desktop.

Revisions

  1. alfian0 created this gist Jul 3, 2020.
    90 changes: 90 additions & 0 deletions RatingComponent.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,90 @@
    @IBDesignable
    class RatingComponent: UIControl {
    @IBInspectable
    var count: Int = 5 {
    didSet {
    ratings = []
    for i in 0..<count {
    let button = UIButton(type: .custom)
    button.setImage(selectedImage, for: .selected)
    button.setImage(unSelectedImage, for: .normal)
    button.imageView?.contentMode = .scaleAspectFit
    button.isSelected = i <= (value-1)
    button.tag = i
    button.addTarget(self, action: #selector(onTapRating(_:)), for: .touchUpInside)
    ratings.append(button)
    verticalStack.addArrangedSubview(button)
    }
    }
    }

    @IBInspectable
    var selectedImage: UIImage? = nil {
    didSet {
    for rating in ratings {
    rating.setImage(selectedImage, for: .selected)
    }
    }
    }

    @IBInspectable
    var unSelectedImage: UIImage? = nil {
    didSet {
    for rating in ratings {
    rating.setImage(unSelectedImage, for: .normal)
    }
    }
    }

    @IBInspectable
    var value: Int = 0 {
    didSet {
    for rating in ratings {
    rating.isSelected = rating.tag <= (value-1)
    }
    }
    }

    private var ratings: [UIButton] = []

    private var verticalStack: UIStackView = {
    let stack = UIStackView()
    stack.axis = .horizontal
    stack.distribution = .fillEqually
    stack.spacing = 8
    stack.translatesAutoresizingMaskIntoConstraints = false
    return stack
    }()

    override init(frame: CGRect) {
    super.init(frame: frame)
    setup()
    }

    required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setup()
    }

    override func prepareForInterfaceBuilder() {
    setup()
    }

    private func setup() {
    if !subviews.contains(verticalStack) {
    addSubview(verticalStack)
    verticalStack.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
    verticalStack.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
    verticalStack.topAnchor.constraint(equalTo: topAnchor).isActive = true
    verticalStack.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
    }
    }

    @objc
    private func onTapRating(_ sender: UIButton) {
    if isEnabled {
    value = sender.tag + 1
    sendActions(for: .valueChanged)
    }
    }
    }