首页 > 解决方案 > 如何在 Apple Developer Tutorial 中创建 RatingControl 类的不同实例?

问题描述

我需要创建一个与RatingControl您在创建 FoodTracker 教程时创建的类非常相似的类。与我的唯一区别是我需要该类能够创建评级控制的不同实例,这些实例因图像类型而异。因此,我不仅需要拥有我的positivePointRatingButtons UIButton数组,还需要它能够实例化 thenegativePointRatingButtonssuperPointRatingButtonsas-well。我只是不想为此目的再上一堂课,而且我是新手,所以我想我会得到一些帮助。

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
        }
    }
}

我希望能够使用我定义@IBInspectablecircleType属性,以便我可以使用 1、2、3 整数作为每种情况的表示。

标签: iosswiftuistackview

解决方案


我想出了怎么做。我刚刚做了一个开关盒来根据 ratingType 变量加载不同的图像


推荐阅读