Skip to content

Commit c9d8cdb

Browse files
authored
[NL-54] : 운세 화면 구현 (#33)
* [NL-54] : Chip Component 생성 - Forturne 에서 사용 가능한 ChipComponent 생성 * [NL-55] : OnboardingViewController + viewModel Refactor - Routing시 delegate 설정 * [NL-54] : rebase to develop * [NL-54] : Fortune first cell 제작 * [NL-54] : 종합 운세 생성과 제작 - pagecontroller custom 필요 * [NL-54] : Merge 피드백 수정 - pagecontrol 삭제 - 그래프 크기 조절
1 parent d81ed3e commit c9d8cdb

File tree

8 files changed

+610
-92
lines changed

8 files changed

+610
-92
lines changed

Common/Lib/Sources/Router/OnbaordingRoute.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ import UIKit
1111
public enum OnboardingRoute {
1212
case splash
1313
case onboarding
14-
case agreement
15-
case timePicker
14+
case agreement
15+
case timePicker
1616
}

Feature/Fortune/Sources/Cells/FortuneCollectionViewCell.swift

Lines changed: 98 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,113 @@ import DesignSystem
99
import SnapKit
1010
import Then
1111
import UIKit
12+
import Extension
13+
import Base
1214

1315
struct FortuneCollectionViewCellModel {
14-
let dayInfo: String?
15-
let scoreInfo: String?
16-
let fortuneImage: UIImage?
16+
let dayInfo: String
17+
let scoreInfo: Int
1718
let fortuneText: String?
1819
}
1920

20-
final class FortuneCollectionViewCell: UICollectionViewCell {
21+
final class FortuneCollectionViewCell: BaseCollectionViewCell {
2122

2223
private lazy var contentStackView = UIStackView().then {
2324
$0.axis = .vertical
2425
$0.spacing = 6
26+
$0.alignment = .center
2527
}
28+
29+
private lazy var dayInfoLabel = PaddingLabel().then {
30+
$0.style = Typography.Body_14_SB
31+
$0.textColor = STColors.primary2.color
32+
$0.backgroundColor = STColors.primary7.color
33+
$0.layer.cornerRadius = 14
34+
$0.clipsToBounds = true
35+
$0.textAlignment = .center
36+
$0.contentInsets = UIEdgeInsets(top: 3.5, left: 10, bottom: 3.5, right: 10)
37+
}
38+
39+
private lazy var scoreInfoLabel = UILabel().then {
40+
$0.style = Typography.Display_28_B
41+
$0.textColor = STColors.gray1.color
42+
$0.textAlignment = .center
43+
}
44+
45+
private lazy var scoreArcStackView = UIStackView().then {
46+
$0.axis = .vertical
47+
$0.alignment = .center
48+
}
49+
50+
private lazy var scoreArcView = ScoreArcView().then {
51+
$0.contentInsets = UIEdgeInsets(top: 11, left: 20, bottom: 11, right: 20)
52+
}
53+
54+
private lazy var fortuneInfoLabel = UILabel().then {
55+
$0.style = Typography.Body_16_M
56+
$0.textColor = STColors.gray1.color
57+
$0.textAlignment = .center
58+
}
59+
60+
override init(frame : CGRect) {
61+
super.init(frame: frame)
62+
setupUI()
63+
}
64+
65+
required init?(coder: NSCoder) {
66+
fatalError("init(coder:) has not been implemented")
67+
}
68+
69+
private func setupUI() {
70+
backgroundColor = .clear
71+
contentView.addSubview(dayInfoLabel)
72+
contentView.addSubview(contentStackView)
73+
contentStackView.addArrangedSubview(scoreInfoLabel)
74+
contentStackView.addArrangedSubview(scoreArcView)
75+
contentStackView.addArrangedSubview(fortuneInfoLabel)
76+
77+
dayInfoLabel.snp.makeConstraints { make in
78+
make.top.equalToSuperview()
79+
make.centerX.equalToSuperview()
80+
}
81+
82+
contentStackView.snp.makeConstraints { make in
83+
make.top.equalTo(dayInfoLabel.snp.bottom).offset(12)
84+
make.leading.trailing.equalToSuperview()
85+
make.centerY.equalToSuperview()
86+
}
87+
88+
scoreArcView.snp.makeConstraints { make in
89+
make.height.equalTo(74)
90+
make.width.equalTo(148)
91+
}
92+
}
93+
94+
func update(with cellModel : FortuneCollectionViewCellModel) {
95+
dayInfoLabel.styledText = "\(cellModel.dayInfo) 행운 지수"
96+
scoreInfoLabel.styledText = "\(cellModel.scoreInfo)"
97+
scoreArcView.score = CGFloat(cellModel.scoreInfo)
98+
fortuneInfoLabel.styledText = cellModel.fortuneText
99+
100+
scoreArcView.update(background: STColors.primary6.color, fill: STColors.primary4.color, lineWidth: 20, lineCap: .butt)
101+
}
102+
103+
}
26104

27-
private lazy var scoreStack = UIStackView().then {
28-
$0.axis = .vertical
29-
$0.spacing = 12
30-
}
31-
105+
@available(iOS 17.0, *)
106+
#Preview {
107+
let stackView = UIStackView().then {
108+
$0.axis = .vertical
109+
$0.spacing = .zero
110+
}
111+
let cell = FortuneCollectionViewCell().then {
112+
$0.update(with: FortuneCollectionViewCellModel(dayInfo: "8월 8일", scoreInfo: 85, fortuneText: "좋은 기운이 문을 두들기고 있소"))
113+
}
114+
115+
cell.snp.makeConstraints { make in
116+
make.height.equalTo(218)
117+
}
118+
stackView.addArrangedSubview(cell)
119+
120+
return stackView
32121
}
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
//
2+
// OverallCollectionViewCell.swift
3+
// FeatureLayer
4+
//
5+
// Created by 최재혁 on 8/12/25.
6+
//
7+
8+
import UIKit
9+
import DesignSystem
10+
import Base
11+
12+
struct OverallCollectionViewCellModel {
13+
let title: String
14+
let modal : [OverallModalCollectionViewCellModel]
15+
}
16+
17+
final class OverallCollectionViewCell: UICollectionViewCell {
18+
19+
private var modalModels: [OverallModalCollectionViewCellModel] = []
20+
21+
private lazy var contentStackView = UIStackView().then {
22+
$0.axis = .vertical
23+
$0.spacing = 12
24+
$0.alignment = .center
25+
}
26+
27+
private lazy var titleStackView = UIStackView().then {
28+
$0.axis = .horizontal
29+
$0.spacing = 4
30+
$0.isLayoutMarginsRelativeArrangement = true
31+
$0.layoutMargins = UIEdgeInsets(top: 0, left: 24, bottom: 0, right: 0)
32+
}
33+
34+
private lazy var titleLabel = UILabel().then {
35+
$0.style = Typography.Body_18_B
36+
$0.textColor = STColors.gray2.color
37+
}
38+
39+
private lazy var modalCollectionView = UICollectionView(
40+
frame: .zero, collectionViewLayout: createLayout()
41+
).then {
42+
$0.backgroundColor = .clear
43+
$0.isPagingEnabled = false
44+
$0.showsHorizontalScrollIndicator = false
45+
$0.delegate = self
46+
$0.dataSource = self
47+
$0.register(
48+
OverallModalCollectionViewCell.self,
49+
forCellWithReuseIdentifier: OverallModalCollectionViewCell.typeName)
50+
}
51+
52+
override init(frame: CGRect) {
53+
super.init(frame: frame)
54+
setupUI()
55+
}
56+
57+
required init?(coder: NSCoder) {
58+
fatalError("init(coder:) has not been implemented")
59+
}
60+
61+
private func setupUI() {
62+
contentView.addSubview(contentStackView)
63+
contentStackView.addArrangedSubview(titleStackView)
64+
contentStackView.addArrangedSubview(modalCollectionView)
65+
titleStackView.addArrangedSubview(titleLabel)
66+
67+
contentStackView.snp.makeConstraints { make in
68+
make.edges.equalToSuperview()
69+
}
70+
71+
modalCollectionView.snp.makeConstraints { make in
72+
make.leading.trailing.equalToSuperview()
73+
make.height.equalTo(129)
74+
}
75+
76+
titleStackView.snp.makeConstraints { make in
77+
make.leading.equalToSuperview()
78+
}
79+
}
80+
81+
func update(with cellModel: OverallCollectionViewCellModel) {
82+
titleLabel.styledText = cellModel.title
83+
modalModels = cellModel.modal
84+
modalCollectionView.reloadData()
85+
}
86+
87+
private func createLayout() -> UICollectionViewCompositionalLayout {
88+
let layout = UICollectionViewCompositionalLayout { sectionIndex, environment -> NSCollectionLayoutSection? in
89+
90+
let itemSize = NSCollectionLayoutSize(
91+
widthDimension: .absolute(134),
92+
heightDimension: .estimated(200)
93+
)
94+
let item = NSCollectionLayoutItem(layoutSize: itemSize)
95+
96+
let groupSize = NSCollectionLayoutSize(
97+
widthDimension: .absolute(134),
98+
heightDimension: .estimated(200)
99+
)
100+
101+
let group = NSCollectionLayoutGroup.horizontal(
102+
layoutSize: groupSize,
103+
subitems: [item]
104+
)
105+
106+
let section = NSCollectionLayoutSection(group: group)
107+
section.orthogonalScrollingBehavior = .continuous
108+
109+
section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 20, bottom: 0, trailing: 0)
110+
111+
section.interGroupSpacing = 10
112+
113+
return section
114+
}
115+
116+
return layout
117+
}
118+
}
119+
120+
extension OverallCollectionViewCell : UICollectionViewDataSource, UICollectionViewDelegate {
121+
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
122+
return modalModels.count
123+
}
124+
125+
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
126+
guard let cell = collectionView.dequeueReusableCell(
127+
withReuseIdentifier: OverallModalCollectionViewCell.typeName,
128+
for: indexPath) as? OverallModalCollectionViewCell else {
129+
return UICollectionViewCell()
130+
}
131+
132+
let model = modalModels[indexPath.item]
133+
cell.update(with: model)
134+
return cell
135+
}
136+
}
137+
138+
@available(iOS 17.0, *)
139+
#Preview {
140+
let containerView = UIView().then {
141+
$0.backgroundColor = .systemBackground
142+
}
143+
144+
let cell = OverallCollectionViewCell(frame: .zero)
145+
146+
let modalModels: [OverallModalCollectionViewCellModel] = [
147+
OverallModalCollectionViewCellModel(
148+
title: "첫 번째 모달",
149+
description: "이것은 첫 번째 모달",
150+
image: UIImage(systemName: "star.fill") ?? UIImage()
151+
),
152+
OverallModalCollectionViewCellModel(
153+
title: "두 번째 모달",
154+
description: "이것은 두 번째 모달",
155+
image: UIImage(systemName: "heart.fill") ?? UIImage()
156+
),
157+
OverallModalCollectionViewCellModel(
158+
title: "세 번째 모달",
159+
description: "이것은 세 번째 모달입니다.",
160+
image: UIImage(systemName: "circle.fill") ?? UIImage()
161+
)
162+
]
163+
let cellModel = OverallCollectionViewCellModel(title: "종합 운세", modal: modalModels)
164+
165+
cell.update(with: cellModel)
166+
containerView.backgroundColor = STColors.primary7.color
167+
168+
containerView.addSubview(cell)
169+
cell.snp.makeConstraints { make in
170+
make.top.leading.trailing.bottom.equalToSuperview()
171+
make.height.equalTo(195)
172+
}
173+
174+
return containerView
175+
}

0 commit comments

Comments
 (0)