Skip to content

Commit 4e29b3c

Browse files
committed
fix/#170: StoreListCell 레이아웃 개선 및 컨벤션 적용
1 parent ca9bb66 commit 4e29b3c

File tree

3 files changed

+156
-131
lines changed

3 files changed

+156
-131
lines changed
Lines changed: 98 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import UIKit
22

33
import DesignSystem
4+
import Infrastructure
45

56
import ReactorKit
67
import RxSwift
@@ -9,63 +10,70 @@ import SnapKit
910
final class StoreListCell: UICollectionViewCell {
1011
static let identifier = "StoreListCell"
1112

13+
// MARK: - Properties
14+
var disposeBag = DisposeBag()
15+
16+
private enum Constant {
17+
static let imageHeight: CGFloat = 140
18+
static let bookmarkSize: CGFloat = 24
19+
static let bookmarkInset: CGFloat = 8
20+
static let categoryTopOffset: CGFloat = 12
21+
static let categoryHeight: CGFloat = 15
22+
static let titleTopOffset: CGFloat = 4
23+
static let addressHeight: CGFloat = 17
24+
static let dateHeight: CGFloat = 15
25+
static let cornerRadius: CGFloat = 12
26+
}
27+
1228
// MARK: - Components
13-
private let thumbnailImageView: UIImageView = {
14-
let iv = UIImageView()
15-
iv.contentMode = .scaleAspectFill
16-
iv.clipsToBounds = true
17-
iv.layer.cornerRadius = 12
18-
iv.backgroundColor = .g100
19-
return iv
20-
}()
21-
22-
let bookmarkButton: UIButton = {
23-
let button = UIButton()
24-
button.setImage(UIImage(named: "icon_bookmark"), for: .normal)
25-
button.backgroundColor = .clear
26-
button.layer.cornerRadius = 12
27-
return button
28-
}()
29-
30-
private let categoryTagLabel: PPLabel = {
31-
let label = PPLabel(style: .bold, fontSize: 11, text: "")
32-
label.textColor = .blu500
33-
label.text = "#카테고리"
34-
return label
35-
}()
36-
37-
private let titleLabel: PPLabel = {
38-
let label = PPLabel(style: .bold, fontSize: 14, text: "")
39-
label.textColor = .g900
40-
label.numberOfLines = 2
41-
return label
42-
}()
43-
44-
private let locationLabel: PPLabel = {
45-
let label = PPLabel(style: .medium, fontSize: 11, text: "")
46-
label.textColor = .g400
47-
label.numberOfLines = 2
48-
return label
49-
}()
50-
51-
private let dateLabel: PPLabel = {
52-
let label = PPLabel(style: .regular, fontSize: 12, text: "")
53-
label.textColor = .g400
54-
label.numberOfLines = 2
55-
return label
56-
}()
29+
private let thumbnailImageView = UIImageView().then {
30+
$0.contentMode = .scaleAspectFill
31+
$0.clipsToBounds = true
32+
$0.layer.cornerRadius = Constant.cornerRadius
33+
$0.backgroundColor = .g100
34+
}
5735

58-
var disposeBag = DisposeBag()
36+
let bookmarkButton = UIButton().then {
37+
$0.setImage(UIImage(named: "icon_bookmark"), for: .normal)
38+
$0.backgroundColor = .clear
39+
}
40+
41+
private let categoryTagLabel = PPLabel(style: .bold, fontSize: 11).then {
42+
$0.textColor = .blu500
43+
$0.setLineHeightText(text: "category", font: .korFont(style: .bold, size: 11))
44+
}
45+
46+
private let titleLabel = PPLabel(style: .bold, fontSize: 14).then {
47+
$0.numberOfLines = 2
48+
$0.lineBreakMode = .byTruncatingTail
49+
$0.textColor = .g900
50+
$0.setLineHeightText(text: "title", font: .korFont(style: .bold, size: 14))
51+
}
52+
53+
private let locationLabel = PPLabel(style: .medium, fontSize: 11).then {
54+
$0.numberOfLines = 1
55+
$0.lineBreakMode = .byTruncatingTail
56+
$0.textColor = .g400
57+
$0.setLineHeightText(text: "location", font: .korFont(style: .medium, size: 11))
58+
}
59+
60+
private let dateLabel = PPLabel(style: .medium, fontSize: 11).then {
61+
$0.lineBreakMode = .byTruncatingTail
62+
$0.textColor = .g400
63+
$0.setLineHeightText(text: "date", font: .korFont(style: .medium, size: 11))
64+
}
5965

6066
// MARK: - Init
6167
override init(frame: CGRect) {
6268
super.init(frame: frame)
63-
setUpConstraints()
64-
configureUI()
69+
70+
self.addViews()
71+
self.setupConstraints()
72+
self.configureUI()
6573
}
6674

6775
required init?(coder: NSCoder) {
68-
fatalError()
76+
fatalError("\(#file), \(#function) Error")
6977
}
7078

7179
override func prepareForReuse() {
@@ -76,52 +84,56 @@ final class StoreListCell: UICollectionViewCell {
7684

7785
// MARK: - SetUp
7886
private extension StoreListCell {
79-
func configureUI() {
80-
// backgroundColor = .white
87+
func addViews() {
88+
[thumbnailImageView, categoryTagLabel, titleLabel, locationLabel, dateLabel, bookmarkButton].forEach {
89+
self.contentView.addSubview($0)
90+
}
8191
}
8292

83-
func setUpConstraints() {
84-
contentView.addSubview(thumbnailImageView)
93+
func setupConstraints() {
8594
thumbnailImageView.snp.makeConstraints { make in
86-
make.top.leading.equalToSuperview()
87-
make.width.equalTo((UIScreen.main.bounds.width - 48) / 2)
88-
make.height.equalTo(thumbnailImageView.snp.width)
95+
make.width.equalTo(contentView.bounds.width)
96+
make.height.equalTo(Constant.imageHeight)
97+
make.top.equalToSuperview()
98+
make.centerX.equalToSuperview()
8999
}
90100

91-
contentView.addSubview(bookmarkButton)
92101
bookmarkButton.snp.makeConstraints { make in
93-
make.top.trailing.equalToSuperview().inset(8)
94-
make.size.equalTo(24)
102+
make.size.equalTo(Constant.bookmarkSize)
103+
make.top.trailing.equalToSuperview().inset(Constant.bookmarkInset)
104+
}
105+
106+
categoryTagLabel.snp.makeConstraints { make in
107+
make.leading.equalToSuperview()
108+
make.top.equalTo(thumbnailImageView.snp.bottom).offset(Constant.categoryTopOffset)
109+
make.height.equalTo(Constant.categoryHeight)
110+
}
111+
112+
titleLabel.snp.makeConstraints { make in
113+
make.top.equalTo(categoryTagLabel.snp.bottom).offset(Constant.titleTopOffset)
114+
make.leading.trailing.equalToSuperview()
115+
}
116+
117+
dateLabel.snp.makeConstraints { make in
118+
make.leading.equalToSuperview()
119+
make.height.equalTo(Constant.dateHeight).priority(.high)
120+
make.bottom.equalToSuperview()
95121
}
96122

97-
contentView.addSubview(categoryTagLabel)
98-
contentView.addSubview(titleLabel)
99-
contentView.addSubview(locationLabel)
100-
contentView.addSubview(dateLabel)
101-
102-
// 각 라벨의 위치 설정
103-
categoryTagLabel.snp.makeConstraints { make in
104-
make.top.equalTo(thumbnailImageView.snp.bottom).offset(10)
105-
make.leading.trailing.equalToSuperview()
106-
make.height.equalTo(16)
107-
}
108-
109-
titleLabel.snp.makeConstraints { make in
110-
make.top.equalTo(categoryTagLabel.snp.bottom).offset(6)
111-
make.leading.trailing.equalToSuperview()
112-
}
113-
114-
locationLabel.snp.makeConstraints { make in
115-
make.top.equalTo(titleLabel.snp.bottom).offset(12)
116-
make.leading.trailing.equalToSuperview()
117-
}
118-
119-
dateLabel.snp.makeConstraints { make in
120-
make.top.equalTo(locationLabel.snp.bottom).offset(6)
121-
make.leading.trailing.equalToSuperview()
122-
make.bottom.lessThanOrEqualToSuperview()
123-
}
124-
}
123+
locationLabel.snp.makeConstraints { make in
124+
make.leading.trailing.equalToSuperview()
125+
make.bottom.equalTo(dateLabel.snp.top)
126+
make.height.equalTo(Constant.addressHeight).priority(.high)
127+
}
128+
}
129+
130+
func configureUI() {
131+
self.contentView.layer.cornerRadius = 4
132+
self.contentView.clipsToBounds = true
133+
134+
thumbnailImageView.layer.cornerRadius = 4
135+
thumbnailImageView.clipsToBounds = true
136+
}
125137
}
126138

127139
// MARK: - Inputable
@@ -145,5 +157,4 @@ extension StoreListCell: Inputable {
145157
let bookmarkImage = input.isBookmarked ? "icon_bookmark_fill" : "icon_bookmark"
146158
bookmarkButton.setImage(UIImage(named: bookmarkImage), for: .normal)
147159
}
148-
149160
}

Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/StoreListView/StoreListView.swift

Lines changed: 58 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,26 @@ import SnapKit
22
import UIKit
33

44
final class StoreListView: UIView {
5+
6+
// MARK: - Properties
7+
private enum Constant {
8+
static let grabberWidth: CGFloat = 36
9+
static let grabberHeight: CGFloat = 5
10+
static let grabberTopOffset: CGFloat = 14
11+
static let grabberCornerRadius: CGFloat = 2.5
12+
static let collectionViewTopOffset: CGFloat = 8
13+
static let cornerRadius: CGFloat = 16
14+
static let itemHeight: CGFloat = 250
15+
static let minimumLineSpacing: CGFloat = 20
16+
static let minimumInteritemSpacing: CGFloat = 16
17+
static let sectionInsetTop: CGFloat = 16
18+
static let sectionInsetHorizontal: CGFloat = 16
19+
static let sectionInsetBottom: CGFloat = 16
20+
}
21+
522
// MARK: - Components
623
lazy var collectionView: UICollectionView = {
7-
let layout = createLayout()
24+
let layout = self.createLayout()
825
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
926
cv.backgroundColor = .white
1027
cv.register(StoreListCell.self, forCellWithReuseIdentifier: StoreListCell.identifier)
@@ -14,22 +31,18 @@ final class StoreListView: UIView {
1431
let grabberHandle: UIView = {
1532
let view = UIView()
1633
view.backgroundColor = .g200
17-
view.layer.cornerRadius = 2.5
34+
view.layer.cornerRadius = Constant.grabberCornerRadius
1835
view.isUserInteractionEnabled = true
1936
return view
2037
}()
2138

22-
private let paddingView: UIView = {
23-
let view = UIView()
24-
view.backgroundColor = .clear // 간격만 추가하므로 투명
25-
return view
26-
}()
27-
2839
// MARK: - Init
2940
override init(frame: CGRect) {
3041
super.init(frame: frame)
31-
configureLayer() // 최상단 레이어 설정
32-
setUpConstraints()
42+
43+
self.configureLayer()
44+
self.addViews()
45+
self.setupConstraints()
3346
}
3447

3548
required init?(coder: NSCoder) {
@@ -39,47 +52,51 @@ final class StoreListView: UIView {
3952

4053
// MARK: - Setup
4154
private extension StoreListView {
55+
func addViews() {
56+
[collectionView, grabberHandle].forEach {
57+
self.addSubview($0)
58+
}
59+
}
60+
61+
func setupConstraints() {
62+
grabberHandle.snp.makeConstraints { make in
63+
make.top.equalToSuperview().offset(Constant.grabberTopOffset).priority(.high)
64+
make.centerX.equalToSuperview()
65+
make.width.equalTo(Constant.grabberWidth)
66+
make.height.equalTo(Constant.grabberHeight)
67+
}
68+
69+
collectionView.snp.makeConstraints { make in
70+
make.top.equalTo(grabberHandle.snp.bottom).offset(Constant.collectionViewTopOffset).priority(.medium)
71+
make.leading.trailing.equalToSuperview()
72+
make.bottom.equalToSuperview()
73+
}
74+
}
75+
4276
func createLayout() -> UICollectionViewFlowLayout {
4377
let layout = UICollectionViewFlowLayout()
4478
layout.scrollDirection = .vertical
45-
layout.minimumLineSpacing = 20
46-
layout.minimumInteritemSpacing = 16
79+
layout.minimumLineSpacing = Constant.minimumLineSpacing
80+
layout.minimumInteritemSpacing = Constant.minimumInteritemSpacing
4781

48-
let totalWidth = UIScreen.main.bounds.width - 32
82+
let totalWidth = UIScreen.main.bounds.width - (Constant.sectionInsetHorizontal * 2)
4983
let itemWidth = (totalWidth - layout.minimumInteritemSpacing) / 2
5084

51-
layout.itemSize = CGSize(width: floor(itemWidth), height: itemWidth + 100)
52-
layout.sectionInset = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
85+
layout.itemSize = CGSize(width: floor(itemWidth), height: Constant.itemHeight)
86+
layout.sectionInset = UIEdgeInsets(
87+
top: Constant.sectionInsetTop,
88+
left: Constant.sectionInsetHorizontal,
89+
bottom: Constant.sectionInsetBottom,
90+
right: Constant.sectionInsetHorizontal
91+
)
5392

5493
return layout
5594
}
5695

57-
func setUpConstraints() {
58-
backgroundColor = .white
59-
addSubview(collectionView)
60-
addSubview(grabberHandle)
61-
grabberHandle.snp.makeConstraints { make in
62-
make.top.equalToSuperview().offset(14).priority(.high)
63-
make.centerX.equalToSuperview()
64-
make.width.equalTo(36)
65-
make.height.equalTo(5)
66-
}
67-
// paddingView.snp.makeConstraints { make in
68-
// make.top.equalTo(grabberHandle.snp.bottom)
69-
// make.leading.trailing.equalToSuperview()
70-
//
71-
// }
72-
73-
collectionView.snp.makeConstraints { make in
74-
make.top.equalTo(grabberHandle.snp.bottom).offset(8).priority(.medium)
75-
make.leading.trailing.equalToSuperview()
76-
make.bottom.equalToSuperview() // bottom 제약 다시 추가
77-
}
78-
}
79-
8096
func configureLayer() {
81-
layer.cornerRadius = 16
82-
layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] // 상단 좌우 코너만 적용
83-
layer.masksToBounds = true
97+
self.backgroundColor = .white
98+
self.layer.cornerRadius = Constant.cornerRadius
99+
self.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
100+
self.layer.masksToBounds = true
84101
}
85102
}

Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/StoreListView/StoreListViewController.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ final class StoreListViewController: UIViewController, View {
9393
.bind(to: mainView.collectionView.rx.items(dataSource: dataSource))
9494
.disposed(by: disposeBag)
9595

96-
// 찜한 팝업 토스트 처리 체인
9796
reactor.state
9897
.map { $0.shouldShowBookmarkToast }
9998
.distinctUntilChanged()
@@ -104,15 +103,13 @@ final class StoreListViewController: UIViewController, View {
104103
if isBookmarking {
105104
toastView.moveButton.rx.tap
106105
.subscribe(onNext: { [weak self] in
107-
// 이동 처리 (예: 찜한 팝업 리스트 페이지로 이동)
108106
})
109107
.disposed(by: self.disposeBag)
110108
}
111109
ToastMaker.createBookMarkToast(isBookMark: isBookmarking)
112110
}
113111
.disposed(by: disposeBag)
114112

115-
// 3) 아이템 선택
116113
mainView.collectionView.rx.itemSelected
117114
.withUnretained(self)
118115
.subscribe(onNext: { owner, indexPath in

0 commit comments

Comments
 (0)