1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
| class RatingStarView: UIView, UICollectionViewDelegateFlowLayout { var ratingStarCallBack: ((Double) -> Void)? lazy var collectionView: UICollectionView = { let collectionV = UICollectionView(frame: self.bounds, collectionViewLayout: ratingFlowlayout) collectionV.translatesAutoresizingMaskIntoConstraints = false collectionV.delegate = self collectionV.dataSource = self collectionV.register(RatingStarCollectionCell.self) collectionV.isScrollEnabled = false collectionV.isUserInteractionEnabled = false collectionV.backgroundColor = .white return collectionV }() lazy var ratingFlowlayout: UICollectionViewFlowLayout = { let layout = UICollectionViewFlowLayout() layout.minimumLineSpacing = 0 layout.minimumInteritemSpacing = 0 return layout }() required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } public var selectCount: Double = 0 { didSet { collectionView.reloadData() } } init() { super.init(frame: .zero) addSubview(collectionView) NSLayoutConstraint.activate([ collectionView.leadingAnchor.constraint(equalTo: self.leadingAnchor), collectionView.trailingAnchor.constraint(equalTo: self.trailingAnchor), collectionView.topAnchor.constraint(equalTo: self.topAnchor), collectionView.bottomAnchor.constraint(equalTo: self.bottomAnchor) ]) } override func layoutSubviews() { super.layoutSubviews() collectionView.reloadData() } }
extension RatingStarView: UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let itemW: CGFloat = collectionView.frame.size.width / 5.0 let itemH: CGFloat = collectionView.frame.size.height return CGSize(width: itemW, height: itemH) } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 5 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(RatingStarCollectionCell.self, for: indexPath) let offset = round(selectCount * 2.0) / 2.0 if Double(indexPath.row) < floor(offset) { cell.selectImageView.image = R.image.rateStarFilled } else { cell.selectImageView.image = R.image.rateStarOutline } return cell } }
extension RatingStarView { override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { handleTouch(touches.first) } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { handleTouch(touches.first) } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { handleTouch(touches.first) } func handleTouch(_ touch: UITouch?) { let touchPoint = touch?.location(in: collectionView) let scale = touchPoint!.x / collectionView.frame.size.width var offset = scale * 5 offset = ceil(offset) offset = offset > 0 ? offset : 1 offset = offset <= 5 ? offset : 5
self.selectCount = Double(Int(offset)) ratingStarCallBack?(self.selectCount) } }
class RatingStarCollectionCell: UICollectionViewCell, YReusable { lazy var selectImageView: UIImageView = { let imgView = UIImageView() imgView.translatesAutoresizingMaskIntoConstraints = false imgView.contentMode = .scaleAspectFit return imgView }() required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override init(frame: CGRect) { super.init(frame: frame) contentView.addSubview(selectImageView) NSLayoutConstraint.activate([ selectImageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), selectImageView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), selectImageView.topAnchor.constraint(equalTo: contentView.topAnchor), selectImageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor) ]) } }
|