Skip to content

Commit f36bb05

Browse files
authored
[NL-8] 홈 화면 UI 구현 (#24)
* NL-8: 홈 화면 헤더 영역 셀 구현 * NL-8: 홈 화면 번호 추천 영역 셀 구현 * NL-8: 디자인 세부값 업데이트 * NL-8: 홈 화면 오늘의 운세 영역 구현 * NL-8: 홈 화면 UI 구현 * NL-8: 코드 정리 * NL-8: 헤더 영역 chip 높이 설정 * NL-8: 이미지 + 텍스트 영역을 attributedString 을 활용하도록 수정
1 parent a98887c commit f36bb05

File tree

16 files changed

+947
-2
lines changed

16 files changed

+947
-2
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//
2+
// PaddingLabel.swift
3+
// Extension
4+
//
5+
// Created by ttozzi on 8/3/25.
6+
//
7+
8+
import UIKit
9+
10+
public final class PaddingLabel: UILabel {
11+
12+
public var contentInsets: UIEdgeInsets = .zero {
13+
didSet {
14+
invalidateIntrinsicContentSize()
15+
}
16+
}
17+
18+
public override func drawText(in rect: CGRect) {
19+
let insetRect = rect.inset(by: contentInsets)
20+
super.drawText(in: insetRect)
21+
}
22+
23+
public override var intrinsicContentSize: CGSize {
24+
let size = super.intrinsicContentSize
25+
return CGSize(
26+
width: size.width + contentInsets.left + contentInsets.right,
27+
height: size.height + contentInsets.top + contentInsets.bottom
28+
)
29+
}
30+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"images" : [
3+
{
4+
"filename" : "ball.svg",
5+
"idiom" : "universal"
6+
}
7+
],
8+
"info" : {
9+
"author" : "xcode",
10+
"version" : 1
11+
}
12+
}
Lines changed: 52 additions & 0 deletions
Loading
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"images" : [
3+
{
4+
"filename" : "clover.svg",
5+
"idiom" : "universal"
6+
}
7+
],
8+
"info" : {
9+
"author" : "xcode",
10+
"version" : 1
11+
}
12+
}
Lines changed: 14 additions & 0 deletions
Loading
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"images" : [
3+
{
4+
"filename" : "number_ball.png",
5+
"idiom" : "universal"
6+
}
7+
],
8+
"info" : {
9+
"author" : "xcode",
10+
"version" : 1
11+
}
12+
}
2.01 KB
Loading

DesignSystem/DesignSystem/Sources/Typography.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// Created by ttozzi on 7/19/25.
66
//
77

8-
import Foundation
8+
import UIKit
99
import SwiftRichString
1010

1111
public struct Typography {
@@ -128,4 +128,9 @@ extension Style {
128128
paragraph.lineHeightMultiple = value
129129
return self
130130
}
131+
132+
public func color(_ value: UIColor) -> Style {
133+
color = value
134+
return self
135+
}
131136
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
//
2+
// FortuneItemCollectionViewCell.swift
3+
// Home
4+
//
5+
// Created by ttozzi on 8/3/25.
6+
//
7+
8+
import UIKit
9+
import DesignSystem
10+
import Extension
11+
12+
struct FortuneItemCollectionViewCellModel {
13+
let title: String
14+
let imageURL: String?
15+
let message: String
16+
}
17+
18+
final class FortuneItemCollectionViewCell: UICollectionViewCell {
19+
20+
private lazy var contentStackView = UIStackView().then {
21+
$0.spacing = 12
22+
$0.axis = .vertical
23+
$0.alignment = .center
24+
}
25+
private lazy var titleLabel = PaddingLabel().then { // TODO: Chip
26+
$0.style = Typography.Body_14_SB
27+
$0.textColor = STColors.primary2.color
28+
$0.contentInsets = UIEdgeInsets(top: 3.5, left: 10, bottom: 3.5, right: 10)
29+
$0.layer.cornerRadius = 6
30+
$0.layer.borderWidth = 1
31+
$0.layer.borderColor = STColors.primary7.color.cgColor
32+
}
33+
private lazy var imageView = UIImageView().then {
34+
$0.backgroundColor = .gray // TODO: 확인 필요
35+
$0.layer.cornerRadius = 8
36+
$0.clipsToBounds = true
37+
}
38+
private lazy var messageLabel = UILabel().then {
39+
$0.style = Typography.Body_14_B.lineHeightMultiple(1.2)
40+
$0.textColor = STColors.gray1.color
41+
$0.numberOfLines = .zero
42+
}
43+
44+
override init(frame: CGRect) {
45+
super.init(frame: frame)
46+
setupUI()
47+
}
48+
49+
required init?(coder: NSCoder) {
50+
fatalError("init(coder:) has not been implemented")
51+
}
52+
53+
private func setupUI() {
54+
contentView.backgroundColor = .clear
55+
56+
contentView.addSubview(contentStackView)
57+
contentStackView.snp.makeConstraints { make in
58+
make.edges.equalToSuperview()
59+
}
60+
contentStackView.addArrangedSubview(titleLabel)
61+
titleLabel.snp.makeConstraints { make in
62+
make.height.equalTo(28)
63+
}
64+
contentStackView.addArrangedSubview(imageView)
65+
imageView.snp.makeConstraints { make in
66+
make.width.equalToSuperview()
67+
make.height.equalTo(106)
68+
}
69+
contentStackView.addArrangedSubview(messageLabel)
70+
messageLabel.snp.makeConstraints { make in
71+
make.height.greaterThanOrEqualTo(21)
72+
}
73+
}
74+
75+
func update(with model: FortuneItemCollectionViewCellModel) {
76+
titleLabel.styledText = model.title
77+
messageLabel.styledText = model.message
78+
}
79+
}
80+
81+
@available(iOS 17.0, *)
82+
#Preview {
83+
let cellModel = FortuneItemCollectionViewCellModel(
84+
title: "행운의 오브제",
85+
imageURL: "",
86+
message: "보이면 낚으시길"
87+
)
88+
let cell = FortuneItemCollectionViewCell()
89+
cell.update(with: cellModel)
90+
cell.snp.makeConstraints { make in
91+
make.width.equalTo(138)
92+
make.height.equalTo(179)
93+
}
94+
return cell
95+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
//
2+
// HomeHeaderCollectionViewCell.swift
3+
// Home
4+
//
5+
// Created by ttozzi on 7/31/25.
6+
//
7+
8+
import DesignSystem
9+
import Extension
10+
import UIKit
11+
12+
struct HomeHeaderCollectionViewCellModel: HomeCellModel {
13+
let roundText: String
14+
let message: String
15+
let imageURL: String?
16+
}
17+
18+
final class HomeHeaderCollectionViewCell: UICollectionViewCell {
19+
20+
private lazy var contentStackView = UIStackView().then {
21+
$0.spacing = .zero
22+
$0.axis = .vertical
23+
$0.alignment = .center
24+
}
25+
private lazy var roundTextChip = PaddingLabel().then { // TODO: Chip Component
26+
$0.backgroundColor = STColors.primary7.color
27+
$0.layer.cornerRadius = 14
28+
$0.clipsToBounds = true
29+
$0.style = Typography.Body_14_SB
30+
$0.textColor = STColors.primary2.color
31+
$0.textAlignment = .center
32+
$0.contentInsets = UIEdgeInsets(top: 3.5, left: 10, bottom: 3.5, right: 10)
33+
}
34+
private lazy var messageLabel = UILabel().then {
35+
$0.style = Typography.Heading_24_B
36+
$0.textColor = STColors.black.color
37+
}
38+
private lazy var imageView = UIImageView().then {
39+
$0.backgroundColor = .gray // TODO: 임시 영역
40+
}
41+
42+
override init(frame: CGRect) {
43+
super.init(frame: frame)
44+
setupUI()
45+
}
46+
47+
required init?(coder: NSCoder) {
48+
fatalError("init(coder:) has not been implemented")
49+
}
50+
51+
private func setupUI() {
52+
contentView.addSubview(contentStackView)
53+
contentStackView.snp.makeConstraints { make in
54+
make.top.leading.trailing.equalToSuperview()
55+
make.bottom.equalToSuperview().inset(16)
56+
}
57+
contentStackView.addArrangedSubview(roundTextChip)
58+
roundTextChip.snp.makeConstraints { make in
59+
make.height.equalTo(28)
60+
}
61+
contentStackView.setCustomSpacing(12, after: roundTextChip)
62+
contentStackView.addArrangedSubview(messageLabel)
63+
contentStackView.setCustomSpacing(28, after: messageLabel)
64+
contentStackView.addArrangedSubview(imageView)
65+
imageView.snp.makeConstraints { make in
66+
make.size.equalTo(120) // TODO: 확인 필요
67+
}
68+
}
69+
70+
func update(with model: HomeHeaderCollectionViewCellModel) {
71+
roundTextChip.styledText = model.roundText
72+
messageLabel.styledText = model.message
73+
// TODO: imageView 로드
74+
}
75+
}
76+
77+
@available(iOS 17.0, *)
78+
#Preview {
79+
let cellModel = HomeHeaderCollectionViewCellModel(
80+
roundText: "1181회",
81+
message: "잘 되면 꼭 기억해 주세요",
82+
imageURL: ""
83+
)
84+
let cell = HomeHeaderCollectionViewCell()
85+
cell.update(with: cellModel)
86+
cell.snp.makeConstraints { make in
87+
make.height.equalTo(228)
88+
}
89+
return cell
90+
}

0 commit comments

Comments
 (0)