Мне нужно создать очень похожий класс класса RatingControl
, который вы создаете при создании учебника FoodTracker.Единственное отличие от моего заключается в том, что мне нужен этот класс, чтобы иметь возможность создавать различные экземпляры элемента управления рейтингом, которые различаются в зависимости от типов изображений.Поэтому вместо того, чтобы просто иметь мой массив positivePointRatingButtons
UIButton
, мне нужно, чтобы он мог также создавать экземпляры negativePointRatingButtons
или superPointRatingButtons
.Я просто не хочу делать еще один целый класс только для этой цели, и я новичок, поэтому я полагаю, что мне нужна помощь.
import UIKit
@IBDesignable class PointRatingControl: UIStackView {
//MARK: Properties
private var positivePointRatingButtons = [UIButton]()
private var negativePointRatingButtons = [UIButton]()
private var superPointRatingButtons = [UIButton]()
var rating = 0 {
didSet {
updatePointButtonSelectionStates()
}
}
@IBInspectable var circleType: Int = 1 {
didSet {
setupButtons()
}
}
@IBInspectable var circleSize: CGSize = CGSize(width: 30.0, height: 30.0) {
didSet {
setupButtons()
}
}
@IBInspectable var circleCount: Int = 10 {
didSet {
setupButtons()
}
}
//MARK: Initialization
override init(frame: CGRect) {
super.init(frame: frame)
setupButtons()
}
required init(coder: NSCoder) {
super.init(coder: coder)
setupButtons()
}
//MARK: Button Action
@objc func ratingButtonTapped(button: UIButton) {
guard let index = positivePointRatingButtons.index(of: button) else {
fatalError("The button, \(button), is not in the positiveRatingButtons array: \(positivePointRatingButtons)")
}
// Calculate the rating of the selected button
let selectedRating = index + 1
if selectedRating == rating {
// If the selected star represents the current rating, reset the rating to 0.
rating = 0
} else {
// Otherwise set the rating to the selected star
rating = selectedRating
}
}
//MARK: Private Methods
private func setupButtons() {
// Clear any existing buttons
for button in positivePointRatingButtons {
removeArrangedSubview(button)
button.removeFromSuperview()
}
positivePointRatingButtons.removeAll()
// Load button images, since its @IDDesignable in order to show in the interface builder you have to specifyexplicitly the catalog's bundle, as opposed to just using UIImage(named:) method
let bundle = Bundle(for: type(of: self))
let emptyCircle = UIImage(named: "greenCirclePhoto", in: bundle, compatibleWith: self.traitCollection)
let selectedCircle = UIImage(named: "greenFilledCirclePhoto", in: bundle, compatibleWith: self.traitCollection)
let highlightedCircle = UIImage(named: "greenSelectedCirclePhoto", in: bundle, compatibleWith: self.traitCollection)
for _ in 0..<circleCount {
let button = UIButton()
button.setImage(emptyCircle, for: .normal)
button.setImage(selectedCircle, for: .selected)
button.setImage(highlightedCircle, for: .highlighted)
button.setImage(highlightedCircle, for: [.highlighted, .selected])
button.translatesAutoresizingMaskIntoConstraints = false
button.heightAnchor.constraint(equalToConstant: circleSize.height).isActive = true
button.widthAnchor.constraint(equalToConstant: circleSize.width).isActive = true
button.addTarget(self, action: #selector(PointRatingControl.ratingButtonTapped(button:)), for: .touchUpInside)
addArrangedSubview(button)
positivePointRatingButtons.append(button)
}
updatePointButtonSelectionStates()
}
private func updatePointButtonSelectionStates() {
for (index, button) in positivePointRatingButtons.enumerated() {
// If the index of a button is less than the rating, that button should be selected.
button.isSelected = index < rating
}
}
}
Я хотел бы иметь возможность использовать @IBInspectable
также, используя свойство circleType
, которое я определил, чтобы я мог использовать как 1, 2, 3 целых числа как представления для каждого случая.