From 402ee797c372ea505177ddd93af590d88cceffaf Mon Sep 17 00:00:00 2001 From: JURI <80569323+juri123123@users.noreply.github.com> Date: Wed, 18 Feb 2026 23:27:48 +0900 Subject: [PATCH 1/5] =?UTF-8?q?style:=20#359=20=EB=A1=9C=EB=94=A9/?= =?UTF-8?q?=EC=8B=A4=ED=8C=A8=20UI=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/Enum/AIAnswerState.swift | 38 +++++++++ .../View/AIAnswer/AIAnswerView.swift | 80 +++++++++++++++++++ .../AIAnswerViewController.swift | 42 ++++++++++ 3 files changed, 160 insertions(+) create mode 100644 ByeBoo-iOS/ByeBoo-iOS/Presentation/Enum/AIAnswerState.swift create mode 100644 ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerView.swift create mode 100644 ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/ViewController/AIAnswerViewController.swift diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Enum/AIAnswerState.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Enum/AIAnswerState.swift new file mode 100644 index 00000000..d1172f4d --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Enum/AIAnswerState.swift @@ -0,0 +1,38 @@ +// +// AIAnswerState.swift +// ByeBoo-iOS +// +// Created by 최주리 on 2/18/26. +// + +import UIKit + +enum AIAnswerState { + case loading + case fail + case success +} + +extension AIAnswerState { + var text: String { + switch self { + case .loading: + "보리가 열심히 답변을 작성하고 있어요!" + case .fail: + "답변 생성을 실패했어요.\n잠시 뒤에 다시 시도해 주세요." + case .success: + "" + } + } + + var image: UIImage { + switch self { + case .loading: + .boriWriting + case .fail: + .boriRetry + case .success: + .boriLetter + } + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerView.swift new file mode 100644 index 00000000..f2b76d88 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerView.swift @@ -0,0 +1,80 @@ +// +// AIAnswerView.swift +// ByeBoo-iOS +// +// Created by 최주리 on 2/18/26. +// + +import UIKit + +final class AIAnswerView: BaseView { + + private let answerState: AIAnswerState + + private let stackView = UIStackView() + private let imageView = UIImageView() + private let textLabel = UILabel() + private let cardView = AIAnswerCardView() + + init(answerState: AIAnswerState) { + self.answerState = answerState + + super.init(frame: .zero) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func setStyle() { + backgroundColor = .grayscale900 + + stackView.do { + $0.axis = .vertical + $0.spacing = 8.adjustedH + $0.alignment = .center + } + + textLabel.do { + $0.applyByeBooFont( + style: .body3R16, + text: answerState.text, + color: .grayscale100, + textAlignment: .center + ) + $0.numberOfLines = 0 + } + + imageView.do { + $0.image = .boriWriting + } + + cardView.do { + $0.isHidden = true + } + } + + override func setUI() { + addSubviews(stackView, cardView) + stackView.addArrangedSubviews(imageView, textLabel) + } + + override func setLayout() { + stackView.snp.makeConstraints { + $0.horizontalEdges.equalToSuperview().inset(48.adjustedW) + $0.centerY.equalToSuperview() + } + imageView.snp.makeConstraints { + $0.size.equalTo(100) + } + cardView.snp.makeConstraints { + $0.horizontalEdges.equalToSuperview().inset(24.adjustedW) + $0.centerY.equalToSuperview() + } + } + + func updateState(state: AIAnswerState) { + textLabel.text = state.text + imageView.image = state.image + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/ViewController/AIAnswerViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/ViewController/AIAnswerViewController.swift new file mode 100644 index 00000000..cb081989 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/ViewController/AIAnswerViewController.swift @@ -0,0 +1,42 @@ +// +// AIAnswerViewController.swift +// ByeBoo-iOS +// +// Created by 최주리 on 2/18/26. +// + +import Combine +import UIKit + +final class AIAnswerViewController: BaseViewController { + + private let rootView = AIAnswerView(answerState: .fail) + + override func loadView() { + view = rootView + } + + override func viewDidLoad() { + super.viewDidLoad() + + self.navigationItem.hidesBackButton = true + + ByeBooNavigationBar.makeNavigationBar( + navigationItem: self.navigationItem, + navigationController: self.navigationController, + type: .close(header: .black), + action: #selector(close) + ) + } +} + +extension AIAnswerViewController: Dismissible { + func close() { + tabBarController?.tabBar.isHidden = false + self.navigationController?.popToRootViewController(animated: false) + } +} + +extension AIAnswerViewController { + func configure( ) { } +} From b5dc98ee36383992451e216965e2587ba437feab Mon Sep 17 00:00:00 2001 From: JURI <80569323+juri123123@users.noreply.github.com> Date: Thu, 19 Feb 2026 01:40:52 +0900 Subject: [PATCH 2/5] =?UTF-8?q?style:=20#359=20=EB=B3=B4=EB=A6=AC=20?= =?UTF-8?q?=EB=8B=B5=EC=9E=A5=20UI=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/AIAnswer/AIAnswerCardView.swift | 64 +++++++++++++++++++ .../View/AIAnswer/AIAnswerView.swift | 20 ++++-- .../AIAnswerViewController.swift | 2 +- 3 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerCardView.swift diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerCardView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerCardView.swift new file mode 100644 index 00000000..f20e2043 --- /dev/null +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerCardView.swift @@ -0,0 +1,64 @@ +// +// AIAnswerCardView.swift +// ByeBoo-iOS +// +// Created by 최주리 on 2/18/26. +// + +import UIKit + +final class AIAnswerCardView: BaseView { + + private let cardImageView = UIImageView() + private let contentLabel = UILabel() + private let boriLabel = UILabel() + + override func setStyle() { + backgroundColor = .grayscale900 + + cardImageView.do { + $0.image = .boriLetter + } + contentLabel.do { + // font 어떻게 되는거지? + $0.applyByeBooFont( + style: .body3R16, + text: "", + color: .primary50 + ) + $0.numberOfLines = 0 + } + boriLabel.do { + $0.applyByeBooFont( + style: .body3R16, + text: "보리의 답장", + color: .primary50 + ) + } + } + + override func setUI() { + addSubviews(cardImageView) + cardImageView.addSubviews(contentLabel, boriLabel) + } + + override func setLayout() { + cardImageView.snp.makeConstraints { + $0.edges.equalToSuperview() + } + contentLabel.snp.makeConstraints { + $0.horizontalEdges.equalToSuperview().inset(24.adjustedW) + $0.top.equalToSuperview().offset(217.adjustedH) + } + boriLabel.snp.makeConstraints { + $0.top.equalTo(contentLabel.snp.bottom).offset(44.adjustedH) + $0.trailing.equalToSuperview().inset(24.adjustedW) + } + } +} + +extension AIAnswerCardView { + func updateText(answer: String) { + contentLabel.text = answer + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerView.swift index f2b76d88..e8aabeea 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerView.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerView.swift @@ -20,6 +20,7 @@ final class AIAnswerView: BaseView { self.answerState = answerState super.init(frame: .zero) + updateState(state: answerState) } required init?(coder: NSCoder) { @@ -34,7 +35,6 @@ final class AIAnswerView: BaseView { $0.spacing = 8.adjustedH $0.alignment = .center } - textLabel.do { $0.applyByeBooFont( style: .body3R16, @@ -44,11 +44,9 @@ final class AIAnswerView: BaseView { ) $0.numberOfLines = 0 } - imageView.do { $0.image = .boriWriting } - cardView.do { $0.isHidden = true } @@ -72,9 +70,23 @@ final class AIAnswerView: BaseView { $0.centerY.equalToSuperview() } } - +} + +extension AIAnswerView { func updateState(state: AIAnswerState) { textLabel.text = state.text imageView.image = state.image + + switch state { + case .loading: + stackView.isHidden = false + cardView.isHidden = true + case .fail: + stackView.isHidden = false + cardView.isHidden = true + case .success: + stackView.isHidden = true + cardView.isHidden = false + } } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/ViewController/AIAnswerViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/ViewController/AIAnswerViewController.swift index cb081989..82f61222 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/ViewController/AIAnswerViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/ViewController/AIAnswerViewController.swift @@ -10,7 +10,7 @@ import UIKit final class AIAnswerViewController: BaseViewController { - private let rootView = AIAnswerView(answerState: .fail) + private let rootView = AIAnswerView(answerState: .success) override func loadView() { view = rootView From 7a007b9947c27614c11a79b18bda927501ec6d33 Mon Sep 17 00:00:00 2001 From: JURI <80569323+juri123123@users.noreply.github.com> Date: Sun, 22 Feb 2026 19:50:47 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20#359=20=EB=8B=B5=EC=9E=A5=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Quest/View/Archive/ArchiveQuestView.swift | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Archive/ArchiveQuestView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Archive/ArchiveQuestView.swift index 08f89af5..e5a2a298 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Archive/ArchiveQuestView.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Archive/ArchiveQuestView.swift @@ -24,6 +24,11 @@ final class ArchiveQuestView: BaseView { private let thinkView: ThinkView? private let actionView: ActionView? private let feelView = FeelView(emotionType: "", descriptionText: "") + private let AIAnswerButton = ByeBooButton( + titleText: "보리의 답장 보러가기", + type: .enabled + ) + private(set) var type: QuestType @@ -62,7 +67,8 @@ final class ArchiveQuestView: BaseView { scrollView.addSubview(contentView) contentView.addSubviews( headerView, - feelView + feelView, + AIAnswerButton ) switch type { @@ -77,17 +83,17 @@ final class ArchiveQuestView: BaseView { override func setLayout() { scrollView.snp.makeConstraints { - $0.edges.equalToSuperview() + $0.edges.equalTo(safeAreaLayoutGuide) } contentView.snp.makeConstraints { $0.edges.equalToSuperview() $0.width.equalToSuperview() - $0.bottom.equalTo(feelView.snp.bottom).offset(24.adjustedH) + $0.height.greaterThanOrEqualTo(scrollView.frameLayoutGuide) } headerView.snp.makeConstraints { - $0.top.equalTo(16.adjustedH) + $0.top.equalToSuperview().offset(16.adjustedH) $0.horizontalEdges.equalToSuperview() } @@ -112,6 +118,12 @@ final class ArchiveQuestView: BaseView { $0.horizontalEdges.equalToSuperview() } } + + AIAnswerButton.snp.makeConstraints { + $0.top.greaterThanOrEqualTo(feelView.snp.bottom).offset(44.adjustedH) + $0.horizontalEdges.equalToSuperview().inset(24.adjustedW) + $0.bottom.equalTo(contentView.snp.bottom).inset(36.adjustedH) + } } } From 0c82fc123fdd83583e92deea64be752e8f4bff72 Mon Sep 17 00:00:00 2001 From: JURI <80569323+juri123123@users.noreply.github.com> Date: Sun, 22 Feb 2026 20:08:29 +0900 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20#359=20=EB=B3=B4=EB=A6=AC=20?= =?UTF-8?q?=EB=8B=B5=EC=9E=A5=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/AIAnswer/AIAnswerCardView.swift | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerCardView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerCardView.swift index f20e2043..82d0344d 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerCardView.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerCardView.swift @@ -10,6 +10,8 @@ import UIKit final class AIAnswerCardView: BaseView { private let cardImageView = UIImageView() + private let scrollView = UIScrollView() + private let contentView = UIView() private let contentLabel = UILabel() private let boriLabel = UILabel() @@ -18,9 +20,12 @@ final class AIAnswerCardView: BaseView { cardImageView.do { $0.image = .boriLetter + $0.isUserInteractionEnabled = true + } + scrollView.do { + $0.showsVerticalScrollIndicator = false } contentLabel.do { - // font 어떻게 되는거지? $0.applyByeBooFont( style: .body3R16, text: "", @@ -30,7 +35,7 @@ final class AIAnswerCardView: BaseView { } boriLabel.do { $0.applyByeBooFont( - style: .body3R16, + style: .boriVoiceR18, text: "보리의 답장", color: .primary50 ) @@ -39,19 +44,31 @@ final class AIAnswerCardView: BaseView { override func setUI() { addSubviews(cardImageView) - cardImageView.addSubviews(contentLabel, boriLabel) + cardImageView.addSubviews(scrollView, boriLabel) + scrollView.addSubview(contentView) + contentView.addSubview(contentLabel) } override func setLayout() { cardImageView.snp.makeConstraints { $0.edges.equalToSuperview() } - contentLabel.snp.makeConstraints { + scrollView.snp.makeConstraints { + $0.top.equalToSuperview().inset(217.adjustedH) $0.horizontalEdges.equalToSuperview().inset(24.adjustedW) - $0.top.equalToSuperview().offset(217.adjustedH) + $0.bottom.equalToSuperview().inset(98.adjustedH) + } + contentView.snp.makeConstraints { + $0.edges.equalToSuperview() + $0.width.equalToSuperview() + $0.height.greaterThanOrEqualTo(scrollView.frameLayoutGuide) + } + contentLabel.snp.makeConstraints { + $0.horizontalEdges.equalToSuperview() + $0.verticalEdges.equalToSuperview() } boriLabel.snp.makeConstraints { - $0.top.equalTo(contentLabel.snp.bottom).offset(44.adjustedH) + $0.top.equalTo(scrollView.snp.bottom).offset(44.adjustedH) $0.trailing.equalToSuperview().inset(24.adjustedW) } } From 2da130ed86decc28871d8bd2a63e90bf4b88f433 Mon Sep 17 00:00:00 2001 From: JURI <80569323+juri123123@users.noreply.github.com> Date: Mon, 23 Feb 2026 16:18:08 +0900 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20#359=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WriteQuest/View/AIAnswer/AIAnswerCardView.swift | 6 +++++- .../Feature/WriteQuest/View/AIAnswer/AIAnswerView.swift | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerCardView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerCardView.swift index 82d0344d..8234fcfa 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerCardView.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerCardView.swift @@ -76,6 +76,10 @@ final class AIAnswerCardView: BaseView { extension AIAnswerCardView { func updateText(answer: String) { - contentLabel.text = answer + contentLabel.applyByeBooFont( + style: .boriVoiceR18, + text: answer, + color: .primary50 + ) } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerView.swift index e8aabeea..b9c8999c 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerView.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/WriteQuest/View/AIAnswer/AIAnswerView.swift @@ -74,7 +74,12 @@ final class AIAnswerView: BaseView { extension AIAnswerView { func updateState(state: AIAnswerState) { - textLabel.text = state.text + textLabel.applyByeBooFont( + style: .body3R16, + text: state.text, + color: .grayscale100, + textAlignment: .center + ) imageView.image = state.image switch state {