Membuat Rating Komponen

Muhammad Alfiansyah
3 min readJul 3, 2020

--

Karena saya programmer malas, apa lagi kalau harus mengulang membuat suatu komponen yang mungkin atau dapat diimplementasi ke aplikasi lain, jadi disini saya mau share kode saya dalam membuat komponen rating.

Silahkan buat temen temen kalo mau copy atau improve kode yang akan saya share. Tapi dari pada hanya copy paste, disini saya akan jelaskan mengenai implementasi kode saya.

Oke kita masuk kedalam proses koding. Untuk membuat komponen pada iOS kita menggunakan UIButton dan UIStackView sebagai bahan sebagai dasar pembuatan dan UIControl sebagai base class pada user interaction view.

UIControl The base class for controls, which are visual elements that convey a specific action or intention in response to user interactions.

@IBDesignable
class RatingComponent: UIControl {
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
}
}
}
  1. var ratings: [UIButton] Array button yang akan kita gunakan untuk menampung UIButton
  2. var verticalStack: UIStackView sebagai container untuk menampung UIButton sehingga kita dapat mengatur ukuran dan posisi array button secara otomatis
  3. Next kita perlu menambahkan runtime attribute sehingga kita dapat melihat perubahan tampilan secara runtime
@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)
}
}
}
  1. var count: Int setiap kali kita merubah count agar jumlah bintang berubah secara runtime pada xib kita perlu menambahkan didSet function untuk menghandle pengurangan dan penambahan UIButton pada UIStackView
  2. var selectedImage: UIImage? digunakan untuk mengatur selected UIButton image
  3. var unSelectedImage: UIImage? sama halnya pengan selectedImage, hanya saja ini digunakan untuk mengatur unselected UIButton image
  4. var value: Int digunakan untuk mendapatkan atau mensetup nilai saat ini dengan cara mengatur state UIButton isSelected
  5. Terakhir kita perlu menambahkan .touchUpInside action sehingga setiap kali kita klik atau tap rating button value dan tampilan Rating Component berubah
@objc
private func onTapRating(_ sender: UIButton) {
if isEnabled {
value = sender.tag + 1
sendActions(for: .valueChanged)
}
}

Dengan inherits class UIControl komponen kita jadi memiliki kemampuan seperti UIControl lainya seperti UIButton, UISwitch dkk.

Untuk observe value ketika terjadi perubahan kita hanya perlu implement addTarget dengan UIControl.Event adalah .valueChanged.

Source Code :

--

--

No responses yet