Skip to content

Commit

Permalink
[Feat] sopt-makers#360 - 파트 랭크 뷰
Browse files Browse the repository at this point in the history
  • Loading branch information
lsj8706 committed Apr 1, 2024
1 parent 852553e commit 5aec792
Show file tree
Hide file tree
Showing 4 changed files with 245 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
//
// STPartChartRectangleView.swift
// StampFeature
//
// Created by Aiden.lee on 2024/04/01.
// Copyright © 2024 SOPT-iOS. All rights reserved.
//

import UIKit

import Core
import DSKit

import SnapKit

public class STPartChartRectangleView: UIView {

// MARK: - Properties

public var rank: Int = 6
public var partName: String = "파트"

// MARK: - UI Components

private let starRankView: UIImageView = {
let iv = UIImageView()
iv.contentMode = .scaleAspectFit
iv.image = DSKitAsset.Assets.icStar.image.withRenderingMode(.alwaysTemplate)
iv.tintColor = DSKitAsset.Colors.soptampPurple100.color
return iv
}()

private let rankLabel: UILabel = {
let label = UILabel()
label.font = DSKitFontFamily.Montserrat.bold.font(size: 30)
return label
}()

private let rectangleView: UIView = {
let view = UIView()
view.layer.cornerRadius = 8
return view
}()

private let partNameLabel: UILabel = {
let label = UILabel()
label.setTypoStyle(.MDS.body3)
label.textColor = .black
label.lineBreakMode = .byTruncatingTail
label.setCharacterSpacing(0)
return label
}()

// MARK: View Life Cycle

public init(rank: Int) {
self.init()
self.rank = rank
setUI()
setLayout()
}

private override init(frame: CGRect) {
super.init(frame: frame)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

// MARK: - UI & Layouts

extension STPartChartRectangleView {

private func setUI() {
rankLabel.text = "\(rank)"
partNameLabel.text = partName
starRankView.isHidden = (rank > 3)

if rank == 1 {
rankLabel.textColor = DSKitAsset.Colors.soptampPurple300.color
rectangleView.backgroundColor = DSKitAsset.Colors.soptampPurple200.color
starRankView.image = DSKitAsset.Assets.icStar.image.withRenderingMode(.alwaysTemplate)
} else if rank == 2 {
rankLabel.textColor = DSKitAsset.Colors.soptampPink300.color
rectangleView.backgroundColor = DSKitAsset.Colors.soptampPink200.color
starRankView.image = nil
} else if rank == 3 {
rankLabel.textColor = DSKitAsset.Colors.soptampMint300.color
rectangleView.backgroundColor = DSKitAsset.Colors.soptampMint200.color
starRankView.image = nil
} else {
rankLabel.text = ""
rectangleView.backgroundColor = DSKitAsset.Colors.gray300.color
}
}

private func setLayout() {
self.addSubviews(starRankView, rectangleView, partNameLabel)
starRankView.addSubview(rankLabel)

starRankView.snp.makeConstraints { make in
make.bottom.equalTo(rectangleView.snp.top).offset(-13.adjusted)
make.centerX.equalToSuperview()
make.size.equalTo(50.adjusted)
}

rankLabel.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.centerY.equalToSuperview().inset(3)
}

rectangleView.snp.makeConstraints { make in
make.bottom.equalTo(partNameLabel.snp.top).offset(-10.adjustedH)
make.leading.trailing.equalToSuperview()
make.height.equalTo(self.calculateRectangleViewHeight())
}

partNameLabel.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.bottom.equalToSuperview()
make.width.lessThanOrEqualToSuperview()
}
}

private func calculateRectangleViewHeight() -> CGFloat {
return 27.f * (7 - rank).f
}
}

extension STPartChartRectangleView {
public func setData(rank: Int, partName: String) {
print(rank)
self.rank = rank
self.partName = partName
self.setUI()
}
}

extension STPartChartRectangleView {
static func == (left: STPartChartRectangleView, right: STPartChartRectangleView) -> Bool {
return left.rank == right.rank
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//
// PartRankingChartCVC.swift
// StampFeature
//
// Created by Aiden.lee on 2024/04/01.
// Copyright © 2024 SOPT-iOS. All rights reserved.
//

import UIKit
import Combine

import Core
import Domain
import DSKit

import SnapKit

final class PartRankingChartCVC: UICollectionViewCell, UICollectionViewRegisterable {
static var isFromNib: Bool = false

// MARK: - Properties

public var models: [RankingModel] = []

// MARK: - UI Components

private let chartStackView: UIStackView = {
let st = UIStackView()
st.axis = .horizontal
st.spacing = 7
st.distribution = .fillEqually
return st
}()

// MARK: - View Life Cycles

private override init(frame: CGRect) {
super.init(frame: frame)
self.setChartViews()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

// MARK: - UI & Layouts

extension PartRankingChartCVC {

private func setChartViews() {
self.addSubviews(chartStackView)

(1...6).forEach { rank in
let rectangleView = STPartChartRectangleView(rank: rank)
rectangleView.snp.makeConstraints { make in
make.width.greaterThanOrEqualTo(40)
}
chartStackView.addArrangedSubview(rectangleView)
}

chartStackView.snp.makeConstraints { make in
make.height.equalTo(250)
make.top.leading.trailing.bottom.equalToSuperview()
}
}
}

// MARK: - Methods

extension PartRankingChartCVC {

public func setData(model: RankingChartModel) {
let models = model.ranking
self.models = models

self.setChartData(chartRectangleModel: models)
}

private func setChartData(chartRectangleModel: [RankingModel]) {
for (index, rectangle) in chartStackView.arrangedSubviews.enumerated() {
guard let chartRectangle = rectangle as? STPartChartRectangleView else { return }
guard let model = chartRectangleModel[safe: index] else { return }
chartRectangle.setData(rank: model.score, partName: model.username)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@ extension PartRankingVC {
}

private func createChartSection() -> NSCollectionLayoutSection {
let size = NSCollectionLayoutSize(widthDimension: .absolute(RankingVC.standardWidth - 28.adjusted), heightDimension: .estimated(300))
let size = NSCollectionLayoutSize(widthDimension: .absolute(RankingVC.standardWidth), heightDimension: .estimated(250))
let item = NSCollectionLayoutItem(layoutSize: size)
let group = NSCollectionLayoutGroup.horizontal(layoutSize: size, subitem: item, count: 1)

let section = NSCollectionLayoutSection(group: group)
section.contentInsets = .init(top: 0, leading: 34.adjusted, bottom: 0, trailing: 34.adjusted)
section.contentInsets = .init(top: 0, leading: 20, bottom: 0, trailing: 20)
section.orthogonalScrollingBehavior = .none
return section
}

private func createListSection() -> NSCollectionLayoutSection {
let size = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(79.adjustedH))
let size = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(60))
let item = NSCollectionLayoutItem(layoutSize: size)
let group = NSCollectionLayoutGroup.horizontal(layoutSize: size, subitem: item, count: 1)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ public class PartRankingVC: UIViewController, PartRankingViewControllable {
self.bindViews()
self.bindViewModels()
self.setDataSource()

// TODO: 제거
applySnapshot(model: [.init(username: "a", score: 1, sentence: "test"),
.init(username: "b", score: 1, sentence: "test"),
.init(username: "c", score: 1, sentence: "test"),
.init(username: "d", score: 1, sentence: "test")]
)
}
}

Expand Down Expand Up @@ -137,22 +144,17 @@ extension PartRankingVC {
}

private func registerCells() {
RankingChartCVC.register(target: rankingCollectionView)
PartRankingChartCVC.register(target: rankingCollectionView)
RankingListCVC.register(target: rankingCollectionView)
}

private func setDataSource() {
dataSource = UICollectionViewDiffableDataSource(collectionView: rankingCollectionView, cellProvider: { collectionView, indexPath, itemIdentifier in
switch RankingSection.type(indexPath.section) {
case .chart:
guard let chartCell = collectionView.dequeueReusableCell(withReuseIdentifier: RankingChartCVC.className, for: indexPath) as? RankingChartCVC,
guard let chartCell = collectionView.dequeueReusableCell(withReuseIdentifier: PartRankingChartCVC.className, for: indexPath) as? PartRankingChartCVC,
let chartCellModel = itemIdentifier as? RankingChartModel else { return UICollectionViewCell() }
chartCell.setData(model: chartCellModel)
chartCell.balloonTapped = { [weak self] balloonModel in
guard let self = self else { return }
let item = balloonModel.toRankingListTapItem()
self.onCellTap?(item.username, item.sentence)
}
return chartCell

case .list:
Expand Down

0 comments on commit 5aec792

Please sign in to comment.