-
Notifications
You must be signed in to change notification settings - Fork 1
Style/#360 공통퀘스트 UI 구현 #368
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 11 commits
79f6f28
47cb1d7
2c91dbb
aec0bb7
5d157bf
b000618
bcaf3a5
8666e68
5de55a1
b6083bc
4d5fc28
7e9654a
1695f5a
29a1420
507b27f
45d9bf7
04cc8a0
075cbc8
a875874
0e635f8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| // | ||
| // CommonQuestAnswersEntity.swift | ||
| // ByeBoo-iOS | ||
| // | ||
| // Created by APPLE on 2/17/26. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| struct CommonQuestAnswersEntity { | ||
| let question: String | ||
| let answerCount: Int | ||
| let isAnswered: Bool | ||
| let answers: [CommonQuestAnswerEntity] | ||
| } | ||
|
|
||
| struct CommonQuestAnswerEntity { | ||
| let answerID: Int | ||
| let writer: String | ||
| let profileIcon: String | ||
| let writtenAt: Date | ||
| let content: String | ||
| } | ||
|
|
||
| extension CommonQuestAnswersEntity { | ||
| static func stub() -> Self { | ||
| .init( | ||
| question: "연애에서 반복된 문제 패턴 3가지를 생각해보아요", | ||
| answerCount: 0, | ||
| isAnswered: false, | ||
| answers: [] | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| extension CommonQuestAnswerEntity { | ||
| static func stub() -> Self { | ||
| .init( | ||
| answerID: 1, | ||
| writer: "장원영", | ||
| profileIcon: "SO_SO", | ||
| writtenAt: Date.now, | ||
| content: "헤어진 지 벌써 일주일이 지났습니다. 처음에는 실감이 안 나서 눈물조차 나오지 않았어요. 그저 멍하니 천장만 바라보며 시간을 보냈습니다. 그런데 오늘 아침, 습관적으로 휴대폰을 확인하다가 더 이상 '굿모닝' 인사를 보낼 사람이 없다는 사실을 깨닫고 그제야 무너져 내렸습니다. 밥알이 모래알 같아서 잘 넘어가지도 않네요. 친구들은 시간이 약이라고, 더 좋은 사람 만날 거라고 위로하지만 지금 당장은 그 어떤 말도 귀에 들어오지 않습니다." | ||
|
Comment on lines
+40
to
+43
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 원영씨 이별해서어뜩해.. |
||
| ) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| // | ||
| // FetchCommonQuestByDateUseCase.swift | ||
| // ByeBoo-iOS | ||
| // | ||
| // Created by APPLE on 2/17/26. | ||
| // | ||
|
|
||
| protocol FetchCommonQuestByDateUseCase { | ||
| func execute(date: String) async throws -> CommonQuestAnswersEntity | ||
| } | ||
|
|
||
| struct DefaultFetchCommonQuestByDateUseCase: FetchCommonQuestByDateUseCase { | ||
|
|
||
| private let repository: QuestsInterface | ||
|
|
||
| init(repository: QuestsInterface) { | ||
| self.repository = repository | ||
| } | ||
|
|
||
| func execute(date: String) async throws -> CommonQuestAnswersEntity { | ||
| try await repository.fetchCommoncQuest(date: date) | ||
| } | ||
| } | ||
|
|
||
| struct MockFetchCommonQuestByDateUseCase: FetchCommonQuestByDateUseCase { | ||
|
|
||
| func execute(date: String) async throws -> CommonQuestAnswersEntity { | ||
| .stub() | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| // | ||
| // UITableView+.swift | ||
| // ByeBoo-iOS | ||
| // | ||
| // Created by APPLE on 2/22/26. | ||
| // | ||
|
|
||
| import UIKit | ||
|
|
||
| extension UITableView { | ||
|
|
||
| func dequeueReusableCell<T: UITableViewCell>(for indexPath: IndexPath) -> T { | ||
| guard let cell = self.dequeueReusableCell( | ||
| withIdentifier: T.identifier, | ||
| for: indexPath | ||
| ) as? T else { | ||
| fatalError("identifier에 알맞은 셀을 찾을 수 없음: \(T.identifier)") | ||
dev-domo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| return cell | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| // | ||
| // UITableViewCell+.swift | ||
| // ByeBoo-iOS | ||
| // | ||
| // Created by APPLE on 2/17/26. | ||
| // | ||
|
|
||
| import UIKit | ||
|
|
||
| extension UITableViewCell { | ||
| static var identifier: String { | ||
| String(describing: self) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| // | ||
| // UITableViewHeaderFooterView+.swift | ||
| // ByeBoo-iOS | ||
| // | ||
| // Created by APPLE on 2/22/26. | ||
| // | ||
|
|
||
| import UIKit | ||
|
|
||
| extension UITableViewHeaderFooterView { | ||
| static var identifier: String { | ||
| String(describing: self) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| // | ||
| // CommonQuestAnswersCell.swift | ||
| // ByeBoo-iOS | ||
| // | ||
| // Created by APPLE on 2/17/26. | ||
| // | ||
|
|
||
| import UIKit | ||
|
|
||
| final class CommonQuestAnswersCell: UITableViewCell { | ||
|
|
||
| private let dateFormatter: DateFormatter = { | ||
dev-domo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| let formatter = DateFormatter() | ||
| formatter.dateFormat = "yyyy.MM.dd." | ||
| return formatter | ||
| }() | ||
|
|
||
| private let containerView = UIView() | ||
| private let userIconView = UIImageView() | ||
| private let userNicknameLabel = UILabel() | ||
| private let answerContentLabel = UILabel() | ||
| private let writtenDateLabel = UILabel() | ||
|
|
||
| override init( | ||
| style: UITableViewCell.CellStyle, | ||
| reuseIdentifier: String? | ||
| ) { | ||
| super.init(style: style, reuseIdentifier: reuseIdentifier) | ||
|
|
||
| setStyle() | ||
| setUI() | ||
| setLayout() | ||
| } | ||
|
|
||
| required init?(coder: NSCoder) { | ||
| fatalError("init(coder:) has not been implemented") | ||
| } | ||
|
|
||
| private func setStyle() { | ||
| self.do { | ||
| $0.backgroundColor = .clear | ||
| $0.selectionStyle = .none | ||
| } | ||
| containerView.do { | ||
| $0.layer.cornerRadius = 12 | ||
| $0.backgroundColor = UIColor.white.withAlphaComponent(0.05) | ||
dev-domo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| userNicknameLabel.do { | ||
| $0.textColor = .grayscale200 | ||
| $0.font = FontManager.body6R14.font | ||
| } | ||
| answerContentLabel.do { | ||
| $0.textColor = .grayscale100 | ||
| $0.font = FontManager.body3R16.font | ||
| $0.numberOfLines = 0 | ||
| } | ||
| writtenDateLabel.do { | ||
| $0.textColor = .grayscale400 | ||
| $0.font = FontManager.body6R14.font // TO-DO : 폰트 NotoSans로 수정하기 | ||
| } | ||
| } | ||
|
|
||
| private func setUI() { | ||
| addSubview(containerView) | ||
| containerView.addSubviews( | ||
| userIconView, | ||
| userNicknameLabel, | ||
| answerContentLabel, | ||
| writtenDateLabel | ||
| ) | ||
| } | ||
|
|
||
| private func setLayout() { | ||
| containerView.snp.makeConstraints { | ||
| $0.top.equalToSuperview().inset(24.adjustedH) | ||
| $0.horizontalEdges.equalToSuperview().inset(24.adjustedW) | ||
| $0.bottom.equalToSuperview() | ||
| } | ||
| userIconView.snp.makeConstraints { | ||
| $0.top.equalToSuperview().inset(16.adjustedH) | ||
| $0.leading.equalToSuperview().inset(24.adjustedW) | ||
| $0.size.equalTo(20.adjustedW) | ||
| } | ||
| userNicknameLabel.snp.makeConstraints { | ||
| $0.top.equalToSuperview().inset(16.adjustedH) | ||
| $0.leading.equalTo(userIconView.snp.trailing).offset(4.adjustedW) | ||
| $0.centerY.equalTo(userIconView.snp.centerY) | ||
| } | ||
| answerContentLabel.snp.makeConstraints { | ||
| $0.top.equalTo(userIconView.snp.bottom).offset(12.adjustedH) | ||
| $0.horizontalEdges.equalToSuperview().inset(24.adjustedW) | ||
| $0.height.equalTo(47.adjustedH) | ||
| } | ||
| writtenDateLabel.snp.makeConstraints { | ||
| $0.top.equalTo(answerContentLabel.snp.bottom).offset(20.adjustedH) | ||
| $0.leading.equalToSuperview().inset(24.adjustedW) | ||
| $0.bottom.equalToSuperview().inset(16.adjustedH) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| extension CommonQuestAnswersCell { | ||
|
|
||
| func bind( | ||
| profileIcon: UIImage?, | ||
| answer: CommonQuestAnswerEntity | ||
| ) { | ||
| if let profileIcon { | ||
| userIconView.image = profileIcon | ||
| } else { | ||
| userIconView.do { | ||
| $0.backgroundColor = .grayscale600 | ||
| $0.layer.cornerRadius = 10 | ||
| } | ||
| } | ||
|
Comment on lines
+103
to
+110
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 근데 프로필아이콘은 모든 사람들이 다 가지고 있지 않나여? 기본 배경값 설정을 해주신 이유가 궁금합니다!!
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 호옥시나 서버에서 프로필 이미지 타이틀을 잘못 넘겨줬을 때를 디버깅하기 위한 코드입니당 |
||
| userNicknameLabel.text = answer.writer | ||
| answerContentLabel.text = answer.content | ||
| writtenDateLabel.text = dateFormatter.string(from: answer.writtenAt) | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
뭐가 다른건지 한참 봣네요 ㅋㅋㅋㅋ