관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] UI 컴포넌트 - Rating View (별점, 평점, tag 사용) 본문

UI 컴포넌트 (swift)

[iOS - swift] UI 컴포넌트 - Rating View (별점, 평점, tag 사용)

jake-kim 2021. 7. 23. 01:05

Rate view

아이디어

  • stackView가 있고, stackView 안에 Button들이 존재
  • 해당 Button들은 for문으로 정해준 개수만큼 생성되며, 배열로 참조되고 있는 형태
  • 버튼들의 tag를 설정하여, 어떤 버튼이 눌렀는지 tag로 체크 후 tag이하를 갖는 인덱스들을 선택된 처리

BaseView 정의

class BaseView: UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)

        configure()
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func configure() {}
    func bind() {}
}

RateView 구현

  • class 생성
class RateView: BaseView {

}
  • 기본 property
    • startNumber: 초기화할 별의 개수 (= button의 개수)
    • currentStar: 현재 선택된 별의 개수 저장
    • buttons: 버튼들이 저장될 배열 (일괄 선택처리용도)
    var starNumber: Int = 5 {
        didSet { bind() }
    }
    var currentStar: Int = 0

    private var buttons: [UIButton] = []
  • 버튼들이 담길 stackView 정의
    lazy var stackView: UIStackView = {
        let view = UIStackView()
        view.axis = .horizontal
        view.spacing = 12
        view.backgroundColor = .white

        return view
    }()
  • UIImage 객체 저장 (버튼 선택처리, 미선택처리를 위한 이미지 객체)
    lazy var starFillImage: UIImage? = {
        return UIImage(systemName: "star.fill")
    }()

    lazy var starEmptyImage: UIImage? = {
        return UIImage(systemName: "star")
    }()
  • 기본 세팅
    override func configure() {
        super.configure()

        starNumber = 5
        addSubviews()
        setupLayout()
    }

    private func addSubviews() {
        addSubview(stackView)
    }

    private func setupLayout() {
        stackView.translatesAutoresizingMaskIntoConstraints = false

        stackView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
        stackView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
        stackView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
        stackView.topAnchor.constraint(equalTo: topAnchor).isActive = true
    }
  • 별점 버튼 초기화:  tag생성이 핵심
    override func bind() {
        super.bind()

        for i in 0..<5 {
            let button = UIButton()
            button.setImage(starEmptyImage, for: .normal)
            button.tag = i
            buttons += [button]
            stackView.addArrangedSubview(button)
            button.addTarget(self, action: #selector(didTapButton(sender:)), for: .touchUpInside)
        }
    }
  • tag를 이용하여 선택처리
    @objc
    private func didTapButton(sender: UIButton) {
        let end = sender.tag

        for i in 0...end {
            buttons[i].setImage(starFillImage, for: .normal)
        }
        for i in end + 1..<starNumber {
            buttons[i].setImage(starEmptyImage, for: .normal)
        }

        currentStar = end + 1
    }

* source code: https://github.com/JK0369/RateView

Comments