LNStarScoreView.swift 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. //
  2. // LNStarScoreView.swift
  3. // Lanu
  4. //
  5. // Created by OneeChan on 2025/11/14.
  6. //
  7. import Foundation
  8. import UIKit
  9. import SnapKit
  10. enum LNStarType {
  11. case normal
  12. case whiteBorder
  13. var emptyIc: UIImage {
  14. switch self {
  15. case .normal: .icStar
  16. case .whiteBorder: .icStarWhiteBorder
  17. }
  18. }
  19. var fillIc: UIImage {
  20. switch self {
  21. case .normal: .icStarFill
  22. case .whiteBorder: .icStarWhiteBorderFill
  23. }
  24. }
  25. }
  26. class LNStarScoreView: UIView {
  27. private let grayIc = UIImageView()
  28. private let fillIc = UIImageView()
  29. private let fillView = UIView()
  30. var curType: LNStarType = .normal {
  31. didSet {
  32. grayIc.image = curType.emptyIc
  33. fillIc.image = curType.fillIc
  34. }
  35. }
  36. var score: Double = 0.0 {
  37. didSet {
  38. guard oldValue != score else { return }
  39. let fixed = score.bounded(min: 0.0, max: 1.0)
  40. fillView.snp.remakeConstraints { make in
  41. make.leading.top.bottom.equalToSuperview()
  42. make.width.equalToSuperview().multipliedBy(fixed)
  43. }
  44. }
  45. }
  46. var icSize: CGFloat? {
  47. didSet {
  48. if let icSize {
  49. grayIc.snp.updateConstraints { make in
  50. make.width.height.equalTo(icSize)
  51. }
  52. fillIc.snp.updateConstraints { make in
  53. make.width.height.equalTo(icSize)
  54. }
  55. } else {
  56. grayIc.snp.updateConstraints { make in
  57. make.width.equalTo(grayIc.image!.size.width)
  58. make.height.equalTo(grayIc.image!.size.height)
  59. }
  60. fillIc.snp.updateConstraints { make in
  61. make.width.equalTo(fillIc.image!.size.width)
  62. make.height.equalTo(fillIc.image!.size.height)
  63. }
  64. }
  65. }
  66. }
  67. override init(frame: CGRect) {
  68. super.init(frame: frame)
  69. setupViews()
  70. }
  71. required init?(coder: NSCoder) {
  72. fatalError("init(coder:) has not been implemented")
  73. }
  74. }
  75. extension LNStarScoreView {
  76. private func setupViews() {
  77. grayIc.image = curType.emptyIc
  78. addSubview(grayIc)
  79. grayIc.snp.makeConstraints { make in
  80. make.edges.equalToSuperview()
  81. make.width.equalTo(grayIc.image!.size.width)
  82. make.height.equalTo(grayIc.image!.size.height)
  83. }
  84. fillView.clipsToBounds = true
  85. addSubview(fillView)
  86. fillView.snp.makeConstraints { make in
  87. make.leading.top.bottom.equalToSuperview()
  88. make.width.equalToSuperview().multipliedBy(score)
  89. }
  90. fillIc.image = curType.fillIc
  91. fillView.addSubview(fillIc)
  92. fillIc.snp.makeConstraints { make in
  93. make.leading.centerY.equalToSuperview()
  94. make.width.equalTo(fillIc.image!.size.width)
  95. make.height.equalTo(fillIc.image!.size.height)
  96. }
  97. }
  98. }
  99. #if DEBUG
  100. import SwiftUI
  101. struct LNStarScoreViewPreview: UIViewRepresentable {
  102. func makeUIView(context: Context) -> some UIView {
  103. let container = UIView()
  104. container.backgroundColor = .lightGray
  105. let view = LNStarScoreView()
  106. view.icSize = 60
  107. view.curType = .whiteBorder
  108. container.addSubview(view)
  109. view.snp.makeConstraints { make in
  110. make.center.equalToSuperview()
  111. }
  112. view.score = 0.8
  113. return container
  114. }
  115. func updateUIView(_ uiView: UIViewType, context: Context) { }
  116. }
  117. #Preview(body: {
  118. LNStarScoreViewPreview()
  119. })
  120. #endif