From ad951cac320f44c2ee89f20e25e12f891d00154b Mon Sep 17 00:00:00 2001 From: yeonee Date: Fri, 13 Mar 2026 17:31:30 +0900 Subject: [PATCH 01/17] =?UTF-8?q?style:=20#408=20=EC=95=84=EC=B9=B4?= =?UTF-8?q?=EC=9D=B4=EB=B8=8C=20=ED=85=8D=EC=8A=A4=ED=8A=B8=EB=B7=B0=20?= =?UTF-8?q?=ED=8F=B0=ED=8A=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/Common/TextView/TextBoxView.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/TextView/TextBoxView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/TextView/TextBoxView.swift index bdf77807..2c45636d 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/TextView/TextBoxView.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/TextView/TextBoxView.swift @@ -40,8 +40,8 @@ final class TextBoxView: BaseView { backgroundColor = .white5 titleLabel.applyByeBooFont( - style: .body6R14, - color: .grayscale300, + style: .body3R16, + color: .grayscale100, numberOfLines: 0 ) titleLabel.lineBreakMode = .byCharWrapping @@ -75,9 +75,9 @@ final class TextBoxView: BaseView { extension TextBoxView { func updateText(_ text: String) { titleLabel.applyByeBooFont( - style: .body6R14, + style: .body3R16, text: text, - color: .grayscale300, + color: .grayscale100, numberOfLines: 0 ) } @@ -86,7 +86,7 @@ extension TextBoxView { titleLabel.applyByeBooFont( style: .body6R14, text: text, - color: .grayscale300, + color: .grayscale100, numberOfLines: 0 ) self.emotionChip?.updateEmotion(ByeBooEmotion.toEmotion(text: emotionState)) From a1e6a969632733cc1922ccfa05350f9537c67596 Mon Sep 17 00:00:00 2001 From: yeonee Date: Fri, 13 Mar 2026 17:31:51 +0900 Subject: [PATCH 02/17] =?UTF-8?q?style:=20#408=20=EB=84=A4=EB=B9=84?= =?UTF-8?q?=EA=B2=8C=EC=9D=B4=EC=85=98=20=EB=B0=94=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/Navigation/ByeBooNavigationBar.swift | 16 ++++++++++++++++ .../ArchiveQuestViewController.swift | 10 +++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/Navigation/ByeBooNavigationBar.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/Navigation/ByeBooNavigationBar.swift index a42d1334..461056c3 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/Navigation/ByeBooNavigationBar.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/Navigation/ByeBooNavigationBar.swift @@ -17,6 +17,7 @@ enum NavigationHeaderType { enum NavigationBarType: Equatable { case back(header: NavigationHeaderType = .clear) case backAndMenu(header: NavigationHeaderType = .clear) + case backAndEdit(header: NavigationHeaderType = .clear) case title(String, header: NavigationHeaderType = .clear) case close(header: NavigationHeaderType = .clear) case titleAndClose(String, header: NavigationHeaderType = .clear) @@ -74,6 +75,7 @@ struct ByeBooNavigationBar { switch barType { case .back(let header), .backAndMenu(let header), + .backAndEdit(let header), .close(let header), .none(let header), .title(_, let header), @@ -143,6 +145,20 @@ struct ByeBooNavigationBar { navigationItem: navigationItem, action: secondAction ) + case .backAndEdit: + let backButtonItem = makeBarButtonItem( + image: .left.withTintColor(.white), + target: topViewController, + action: action + ) + navigationItem.leftBarButtonItem = backButtonItem + + let editButtonItem = makeBarButtonItem( + image: .edit, + target: topViewController, + action: secondAction + ) + navigationItem.rightBarButtonItem = editButtonItem case .title(let string, _): navigationItem.title = string diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/ArchiveQuestViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/ArchiveQuestViewController.swift index 00f7a3e0..f753e456 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/ArchiveQuestViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/ArchiveQuestViewController.swift @@ -57,7 +57,15 @@ final class ArchiveQuestViewController: BaseViewController { type: .close(header: .black), action: #selector(close) ) - case .mypage, .questMain, .edit: + case .questMain: + ByeBooNavigationBar.makeNavigationBar( + navigationItem: self.navigationItem, + navigationController: self.navigationController, + type: .backAndEdit(header: .clear), + action: #selector(close), + secondAction: #selector(editButtonDidTap) + ) + case .mypage, .edit: ByeBooNavigationBar.makeNavigationBar( navigationItem: self.navigationItem, navigationController: self.navigationController, From 35095d7828922bd8baabf948a551ebf03b831e39 Mon Sep 17 00:00:00 2001 From: yeonee Date: Fri, 13 Mar 2026 17:37:04 +0900 Subject: [PATCH 03/17] =?UTF-8?q?fix:=20#408=20=EA=B3=B5=ED=86=B5=ED=80=98?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=82=B4=20=EB=8B=B5=EB=B3=80=20=EB=93=A4=EC=96=B4=EA=B0=88=20?= =?UTF-8?q?=EC=8B=9C=EC=97=90=EB=8F=84=20=EC=88=98=EC=A0=95,=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EB=B0=94=ED=85=80=EC=8B=9C=ED=8A=B8=20=EB=9C=A8?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ByeBoo-iOS/ByeBoo-iOS/Data/DataDependencyAssembler.swift | 3 ++- .../Data/Model/CommonQuestAnswersResponseDTO.swift | 7 ++++--- .../Data/Repository/CommonQuestRepository.swift | 8 ++++++-- .../Domain/Entity/CommonQuestAnswersEntity.swift | 3 +++ .../ViewController/CommonQuestHistoryViewController.swift | 7 +++++-- .../Quest/ViewController/CommonQuestViewController.swift | 3 ++- 6 files changed, 22 insertions(+), 9 deletions(-) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Data/DataDependencyAssembler.swift b/ByeBoo-iOS/ByeBoo-iOS/Data/DataDependencyAssembler.swift index 5ff2648a..4304c2bb 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Data/DataDependencyAssembler.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Data/DataDependencyAssembler.swift @@ -55,7 +55,8 @@ struct DataDependencyAssembler: DependencyAssembler { DIContainer.shared.register(type: CommonQuestInterface.self) { _ in return DefaultCommonQuestRepository( network: networkService, - keychainService: keychainService + keychainService: keychainService, + userDefaultService: userDefaultService ) } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Data/Model/CommonQuestAnswersResponseDTO.swift b/ByeBoo-iOS/ByeBoo-iOS/Data/Model/CommonQuestAnswersResponseDTO.swift index d0474117..8c3e1aae 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Data/Model/CommonQuestAnswersResponseDTO.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Data/Model/CommonQuestAnswersResponseDTO.swift @@ -25,7 +25,7 @@ struct CommonQuestAnswerResponseDTO: Decodable { } extension CommonQuestAnswersResponseDTO { - func toEntity() -> CommonQuestAnswersEntity { + func toEntity(userName: String) -> CommonQuestAnswersEntity { .init( question: question, questID: questId, @@ -33,14 +33,15 @@ extension CommonQuestAnswersResponseDTO { isAnswered: isAnswered, hasNext: hasNext, nextCursor: nil, - answers: answers.map { $0.toEntity() } + answers: answers.map { $0.toEntity(userName: userName) } ) } } extension CommonQuestAnswerResponseDTO { - func toEntity() -> CommonQuestAnswerEntity { + func toEntity(userName: String) -> CommonQuestAnswerEntity { .init( + isMyAnswer: userName == writer ? true : false, answerID: answerId, writer: writer, profileIcon: profileIcon, diff --git a/ByeBoo-iOS/ByeBoo-iOS/Data/Repository/CommonQuestRepository.swift b/ByeBoo-iOS/ByeBoo-iOS/Data/Repository/CommonQuestRepository.swift index a4769162..c74198ca 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Data/Repository/CommonQuestRepository.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Data/Repository/CommonQuestRepository.swift @@ -11,13 +11,16 @@ struct DefaultCommonQuestRepository: CommonQuestInterface { private let network: NetworkService private let keychainService: KeychainService + private let userDefaultsService: UserDefaultService init( network: NetworkService, - keychainService: KeychainService + keychainService: KeychainService, + userDefaultService: UserDefaultService ) { self.network = network self.keychainService = keychainService + self.userDefaultsService = userDefaultService } func saveCommonQuest(questID: Int, answer: String) async throws { @@ -35,6 +38,7 @@ struct DefaultCommonQuestRepository: CommonQuestInterface { date: String, cursor: Int? ) async throws -> CommonQuestAnswersEntity { + let userName: String = userDefaultsService.load(key: .userName) ?? "" let commonQuest = try await network.request( CommonQuestAPI.fetchCommonQuest( date: date, @@ -42,7 +46,7 @@ struct DefaultCommonQuestRepository: CommonQuestInterface { ), decodingType: CommonQuestAnswersResponseDTO.self ) - return commonQuest.toEntity() + return commonQuest.toEntity(userName: userName) } func updateCommonQuest(answerID: Int, answer: String) async throws { diff --git a/ByeBoo-iOS/ByeBoo-iOS/Domain/Entity/CommonQuestAnswersEntity.swift b/ByeBoo-iOS/ByeBoo-iOS/Domain/Entity/CommonQuestAnswersEntity.swift index 1d86ebdb..8edb6a71 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Domain/Entity/CommonQuestAnswersEntity.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Domain/Entity/CommonQuestAnswersEntity.swift @@ -18,6 +18,7 @@ struct CommonQuestAnswersEntity { } struct CommonQuestAnswerEntity { + let isMyAnswer: Bool let answerID: Int let writer: String let profileIcon: String @@ -32,6 +33,7 @@ extension CommonQuestAnswersEntity { static let allAnswers: [CommonQuestAnswerEntity] = (1...30).map { CommonQuestAnswerEntity( + isMyAnswer: false, answerID: $0, writer: "유저\($0)", profileIcon: profileIcons[$0 % 4], @@ -57,6 +59,7 @@ extension CommonQuestAnswersEntity { extension CommonQuestAnswerEntity { static func stub() -> Self { .init( + isMyAnswer: false, answerID: 1, writer: "장원영", profileIcon: "SO_SO", diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestHistoryViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestHistoryViewController.swift index 6269ee1f..04e602f5 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestHistoryViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestHistoryViewController.swift @@ -104,14 +104,17 @@ extension CommonQuestHistoryViewController { nickname: String? = nil, content: String, answerID: Int? = nil, - writerID: Int? = nil + writerID: Int? = nil, + isMyAnswer: Bool? = nil ) { self.answerID = answerID self.answer = content self.question = question self.writtenAt = writtenAt - commonQuestArchiveType = nickname == nil ? .mine : .other + if let isMyAnswer { + commonQuestArchiveType = isMyAnswer ? .mine : .other + } if let writerID { self.writerID = writerID diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift index 190b1a97..685c7ffb 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift @@ -142,7 +142,8 @@ extension CommonQuestViewController: UITableViewDelegate { profileIcon: viewModel.getProfileIcon(at: answerIndex), nickname: answer.writer, content: answer.content, - writerID: answer.writerID + writerID: answer.writerID, + isMyAnswer: answer.isMyAnswer ) historyViewController.navigationItem.hidesBackButton = true From ead225b08a8fb39fa31c70c8eff0aed985baddbd Mon Sep 17 00:00:00 2001 From: yeonee Date: Fri, 13 Mar 2026 17:42:55 +0900 Subject: [PATCH 04/17] =?UTF-8?q?style:=20#408=20count=20=ED=85=8D?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EC=97=90=EC=84=9C=20()=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Feature/Quest/View/Write/QuestTextField.swift | 4 ++-- .../Write/View/ActivationType/WriteActiveTypeQuestView.swift | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/QuestTextField.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/QuestTextField.swift index 4a99ac06..012c253e 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/QuestTextField.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/QuestTextField.swift @@ -74,7 +74,7 @@ final class QuestTextField: BaseView { textCountLabel.applyByeBooFont ( style: .cap2R12, - text: "(\(count)/\(limitCount))", + text: "\(count)/\(limitCount)", color: .grayscale400 ) @@ -150,7 +150,7 @@ extension QuestTextField: UITextViewDelegate { textView.deleteBackward() } count = textView.text.count - textCountLabel.text = "(\(count)/\(limitCount))" + textCountLabel.text = "\(count)/\(limitCount)" updateTextViewHeight() delegate?.updateButtonWhenWriting(text: textView.text) } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/ActivationType/WriteActiveTypeQuestView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/ActivationType/WriteActiveTypeQuestView.swift index 2b87da9f..42c3b21d 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/ActivationType/WriteActiveTypeQuestView.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/ActivationType/WriteActiveTypeQuestView.swift @@ -168,7 +168,7 @@ final class WriteActiveTypeQuestView: BaseView { } func updateImageCountLabel(count: Int) { - imgCountLabel.text = "(\(count)/1)" + imgCountLabel.text = "\(count)/1" } } From 516b859b4a53019c686fd7b40b2ee47e661883cf Mon Sep 17 00:00:00 2001 From: yeonee Date: Fri, 13 Mar 2026 17:43:06 +0900 Subject: [PATCH 05/17] =?UTF-8?q?style::=20#408=20=EC=95=84=EC=9D=B4?= =?UTF-8?q?=EC=BD=98=20=EC=BB=AC=EB=9F=AC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Feature/Quest/View/Write/ImagePickerContainer.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/ImagePickerContainer.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/ImagePickerContainer.swift index 3bc33ff2..5251863c 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/ImagePickerContainer.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/ImagePickerContainer.swift @@ -50,7 +50,7 @@ final class ImagePickerContainer: BaseView { plusIcon.do { $0.image = .plus.withRenderingMode(.alwaysTemplate) $0.contentMode = .scaleAspectFit - $0.tintColor = .primary300 + $0.tintColor = .grayscale500 } } From f14e39f05226fde4c7ad88565d6a9df5d2d2a6a1 Mon Sep 17 00:00:00 2001 From: yeonee Date: Sun, 15 Mar 2026 15:35:57 +0900 Subject: [PATCH 06/17] =?UTF-8?q?style:=20#408=20head2=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Feature/Quest/View/Write/WriteQuestTitleView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/WriteQuestTitleView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/WriteQuestTitleView.swift index c89429ef..f63d638c 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/WriteQuestTitleView.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/WriteQuestTitleView.swift @@ -53,7 +53,7 @@ final class WriteQuestTitleView: BaseView { titleLabel.do { $0.applyByeBooFont( - style: .head1M24, + style: .head2M22, color: .white, textAlignment: .center, numberOfLines: 0 From 7fad6bf051f7079dfbb0f3e1a69ca1516ca9ddae Mon Sep 17 00:00:00 2001 From: yeonee Date: Sun, 15 Mar 2026 15:36:12 +0900 Subject: [PATCH 07/17] =?UTF-8?q?feat:=20#408=20=EA=B3=B5=ED=86=B5?= =?UTF-8?q?=ED=80=98=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C=20=EC=8B=9C=20=EB=AA=A8=EB=8B=AC=20=EB=85=B8=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/Modal/ConfirmModalView.swift | 5 ++ .../ViewController/MyPageViewController.swift | 2 +- .../ParentQuestViewController.swift | 13 +++++ ...WriteQuestionTypeQuestViewController.swift | 49 +++++++++++++------ 4 files changed, 52 insertions(+), 17 deletions(-) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/Modal/ConfirmModalView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/Modal/ConfirmModalView.swift index 7d4e81fb..4dc97516 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/Modal/ConfirmModalView.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Common/Modal/ConfirmModalView.swift @@ -12,6 +12,7 @@ enum ConfirmModalType { case withdraw case block case delete + case saveQuest var title: String { switch self { @@ -23,6 +24,8 @@ enum ConfirmModalType { "차단을 해제하시겠어요?" case .delete: "정말 삭제하시겠어요?" + case .saveQuest: + "작성을 완료하시겠어요?" } } @@ -34,6 +37,8 @@ enum ConfirmModalType { "탈퇴 시 모든 데이터가 삭제됩니다." case .delete: "삭제한 답변은 다시 복구할 수 없습니다." + case .saveQuest: + "완료하면 다른 사용자에게 공개돼요." } } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/MyPage/ViewController/MyPageViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/MyPage/ViewController/MyPageViewController.swift index 33730a2e..c0a4eb61 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/MyPage/ViewController/MyPageViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/MyPage/ViewController/MyPageViewController.swift @@ -364,7 +364,7 @@ extension MyPageViewController { self.viewModel.action(.withdrawActionButtonDidTap) Mixpanel.mainInstance().track(event: MyPageEvents.Name.withdrawConfirmClick) - case .block, .delete: + case .block, .delete, .saveQuest: break } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/ParentQuestViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/ParentQuestViewController.swift index 553c8325..bc43c80d 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/ParentQuestViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/ParentQuestViewController.swift @@ -56,6 +56,19 @@ final class ParentQuestViewController: BaseViewController, ToastPres tabBar.select(index: index) } + func presentCompleteModal() { + let modal = ModalBuilder( + modalView: QuestCompleteModal(), + action: nil, + rootViewController: self + ) + modal.present() + + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + modal.dismiss() + } + } + @objc private func handleToast(_ notification: Notification) { guard let type = notification.userInfo?["type"] as? CommonQuestArchiveType.Action else { return } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift index 14aa6ad7..365d6627 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift @@ -78,10 +78,7 @@ final class WriteQuestionTypeQuestViewController: WriteQuestBaseViewController + else { return } + + targetViewController.presentCompleteModal() } } } + + private func createModalView() -> ConfirmModalView { + let dismissButton: ByeBooButton? = ByeBooButton(titleText: "아니오", type: .outline) + let actionButton = ByeBooButton(titleText: "예", type: .enabled) + return ConfirmModalView( + modalType: .saveQuest, + dismissButton: dismissButton, + actionButton: actionButton + ) + } + + private func presentConfirmModal() { + let isEdit = questMode == .edit ? true : false + let modalView = createModalView() + let action: () -> Void = { self.saveQuest(isEdit: isEdit, isCommonQuest: true) } + + ModalBuilder( + modalView: modalView, + action: action, + rootViewController: self + ).present() + } } extension WriteQuestionTypeQuestViewController: EditQuestProtocol { From 2feaa6683ae14bdba5216c28e45119409a1ac617 Mon Sep 17 00:00:00 2001 From: yeonee Date: Sun, 15 Mar 2026 15:47:51 +0900 Subject: [PATCH 08/17] =?UTF-8?q?feat:=20#408=20=EC=B0=A8=EB=8B=A8=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=20empty=20=EB=B6=84=EA=B8=B0=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MyPage/View/BlockedUserListView.swift | 21 ++++++++++++++++++- .../BlockedkUserListViewController.swift | 3 +++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/MyPage/View/BlockedUserListView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/MyPage/View/BlockedUserListView.swift index 05ddc53b..b10ae136 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/MyPage/View/BlockedUserListView.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/MyPage/View/BlockedUserListView.swift @@ -10,6 +10,7 @@ import UIKit final class BlockedUserListView: BaseView { private(set) var userTableView = UITableView() + private let emptyLabel = UILabel() override func setStyle() { self.do { @@ -19,10 +20,18 @@ final class BlockedUserListView: BaseView { $0.backgroundColor = .grayscale900 $0.separatorStyle = .none } + emptyLabel.do { + $0.applyByeBooFont( + style: .body6R14, + text: "차단하신 사용자가 없어요", + color: .grayscale400 + ) + $0.isHidden = true + } } override func setUI() { - addSubview(userTableView) + addSubviews(userTableView, emptyLabel) } override func setLayout() { @@ -31,5 +40,15 @@ final class BlockedUserListView: BaseView { $0.horizontalEdges.equalToSuperview() $0.bottom.equalToSuperview().inset(24.adjustedH) } + emptyLabel.snp.makeConstraints { + $0.top.equalToSuperview().inset(334.5.adjustedH) + $0.centerX.equalToSuperview() + } + } +} + +extension BlockedUserListView { + func updateEmptyLabel() { + self.emptyLabel.isHidden = false } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/MyPage/ViewController/BlockedkUserListViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/MyPage/ViewController/BlockedkUserListViewController.swift index a50e82b7..e0eb8b2e 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/MyPage/ViewController/BlockedkUserListViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/MyPage/ViewController/BlockedkUserListViewController.swift @@ -62,6 +62,9 @@ extension BlockedkUserListViewController { switch result { case .success(let blockedList): ByeBooLogger.debug("차단 사용자 조회 성공 \(blockedList)") + if blockedList.isEmpty { + self.rootView.updateEmptyLabel() + } self.rootView.userTableView.reloadData() case .failure(let error): ByeBooLogger.error(error) From 8ca9960184275cf1582a55fd1d388203b5d42cd1 Mon Sep 17 00:00:00 2001 From: yeonee Date: Sun, 15 Mar 2026 15:55:15 +0900 Subject: [PATCH 09/17] =?UTF-8?q?fix:=20#408=20=EC=8B=A0=EA=B3=A0=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=8B=9C=20answerID=EA=B0=80=20nil?= =?UTF-8?q?=EB=A1=9C=20=EB=93=A4=EC=96=B4=EA=B0=80=EB=8A=94=20=EA=B2=83=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Feature/Quest/ViewController/CommonQuestViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift index 685c7ffb..5530799a 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift @@ -142,6 +142,7 @@ extension CommonQuestViewController: UITableViewDelegate { profileIcon: viewModel.getProfileIcon(at: answerIndex), nickname: answer.writer, content: answer.content, + answerID: answer.answerID, writerID: answer.writerID, isMyAnswer: answer.isMyAnswer ) From 31c58087657a25ad509fc611c80c466fb78e3ffc Mon Sep 17 00:00:00 2001 From: yeonee Date: Sun, 15 Mar 2026 16:03:44 +0900 Subject: [PATCH 10/17] =?UTF-8?q?feat:=20#408=20=ED=80=98=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=9E=91=EC=84=B1=20=EC=99=84=EB=A3=8C=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=ED=83=AD=20=EC=8B=9C=20=ED=82=A4=EB=B3=B4=EB=93=9C?= =?UTF-8?q?=20=EB=82=B4=EB=A0=A4=EA=B0=80=EA=B2=8C=20=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 공통퀘스트에서 토스트메시지 안보이는 것 해결 --- .../ViewController/WriteActiveTypeQuestViewController.swift | 1 + .../ViewController/WriteQuestionTypeQuestViewController.swift | 1 + 2 files changed, 2 insertions(+) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift index be162017..a446d690 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift @@ -76,6 +76,7 @@ final class WriteActiveTypeQuestViewController: WriteQuestBaseViewController Date: Mon, 16 Mar 2026 02:25:37 +0900 Subject: [PATCH 11/17] =?UTF-8?q?refactor:=20#408=20questTextfield?= =?UTF-8?q?=EC=97=90=EC=84=9C=20descriptionlabel,=20count=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Quest/View/Write/QuestTextField.swift | 87 +++++-------------- 1 file changed, 21 insertions(+), 66 deletions(-) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/QuestTextField.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/QuestTextField.swift index 012c253e..059cd316 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/QuestTextField.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/QuestTextField.swift @@ -12,33 +12,23 @@ import Then final class QuestTextField: BaseView { private(set) var textView = UITextView() - private var descriptionStackView: UIStackView? - private let errorIcon = UIImageView() - private let descriptionLabel = UILabel() - private(set) var textCountLabel = UILabel() - private var questType: QuestType + var isPlaceholderActive: Bool = true var count: Int = 0 private(set) var placeholder: String private(set) var limitCount: Int private var containerHeightConsraint: Constraint? private var textViewHeightConstraint: Constraint? + private var lastTextViewHeight = 196.adjustedH - weak var delegate: QuestCompleteProtocol? + weak var questCompleteDelegate: QuestCompleteProtocol? + weak var questTextViewDelegate: WriteQuestTextViewProtocol? init(type: QuestType) { self.questType = type placeholder = type.plaeholder limitCount = type.textLimit - - switch type { - case .question: - descriptionStackView = UIStackView() - case .activation: - descriptionStackView = nil - } - super.init(frame: .zero) textView.delegate = self } @@ -48,12 +38,7 @@ final class QuestTextField: BaseView { } override func setUI() { - addSubviews(textView, textCountLabel) - - if let descriptionStackView { - addSubviews(descriptionStackView) - descriptionStackView.addArrangedSubviews(errorIcon, descriptionLabel) - } + addSubviews(textView) } override func setStyle() { @@ -71,31 +56,6 @@ final class QuestTextField: BaseView { color: .grayscale300 ) } - - textCountLabel.applyByeBooFont ( - style: .cap2R12, - text: "\(count)/\(limitCount)", - color: .grayscale400 - ) - - if let descriptionStackView { - descriptionStackView.do { - $0.axis = .horizontal - $0.spacing = 3.adjustedW - } - } - - errorIcon.do { - $0.image = .error - $0.contentMode = .scaleAspectFit - } - - descriptionLabel.applyByeBooFont( - style: .cap2R12, - text: "10글자 이상 작성해 주세요.", - color: .grayscale400, - textAlignment: .center - ) } override func setLayout() { @@ -110,18 +70,6 @@ final class QuestTextField: BaseView { $0.bottom.equalToSuperview().inset(72.adjustedH) textViewHeightConstraint = $0.height.equalTo(196.adjustedH).constraint } - - if let descriptionStackView { - descriptionStackView.snp.makeConstraints { - $0.leading.equalToSuperview() - $0.bottom.equalToSuperview().inset(24.adjustedW) - } - } - - textCountLabel.snp.makeConstraints { - $0.trailing.equalToSuperview() - $0.bottom.equalToSuperview().inset(24.adjustedW) - } } } @@ -132,6 +80,7 @@ extension QuestTextField: UITextViewDelegate { applyTextViewStyle(text: "", color: .grayscale100) } textView.textColor = .grayscale100 + questTextViewDelegate?.textViewDidEndEditing() } func textViewDidEndEditing(_ textView: UITextView) { @@ -141,18 +90,15 @@ extension QuestTextField: UITextViewDelegate { } else { applyTextViewStyle(text: textView.text, color: .grayscale100) } - textCountLabel.textColor = .grayscale300 - updateTextViewHeight() + questTextViewDelegate?.textViewDidEndEditing() } func textViewDidChange(_ textView: UITextView) { if textView.text.count > limitCount { textView.deleteBackward() } - count = textView.text.count - textCountLabel.text = "\(count)/\(limitCount)" - updateTextViewHeight() - delegate?.updateButtonWhenWriting(text: textView.text) + questCompleteDelegate?.updateButtonWhenWriting(text: textView.text) + questTextViewDelegate?.textViewDidChange(count: textView.text.count) } } @@ -165,16 +111,25 @@ extension QuestTextField { ) } - func updateTextViewHeight() { + func updateTextViewHeight() -> CGFloat { let width = self.frame.width let fittingSize = CGSize(width: width, height: .greatestFiniteMagnitude) let estimatedHeight = ceil(textView.sizeThatFits(fittingSize).height) let containerMinHeight = 268.adjustedH let textViewMinHeight = 196.adjustedH + let newHeight = max(textViewMinHeight, estimatedHeight) + let diff = newHeight - lastTextViewHeight + containerHeightConsraint?.update(offset: max(containerMinHeight, estimatedHeight + 72.adjustedH)) textViewHeightConstraint?.update(offset: max(textViewMinHeight, estimatedHeight)) - superview?.layoutIfNeeded() - layoutIfNeeded() + UIView.performWithoutAnimation { + self.superview?.layoutIfNeeded() + self.layoutIfNeeded() + } + + lastTextViewHeight = newHeight + + return diff } } From 35e4be61a94ae9d5c51442c0c70e6b93a4e8461e Mon Sep 17 00:00:00 2001 From: yeonee Date: Mon, 16 Mar 2026 02:26:04 +0900 Subject: [PATCH 12/17] =?UTF-8?q?fix:=20#408=20=EC=A7=88=EB=AC=B8=ED=98=95?= =?UTF-8?q?=20=ED=85=8D=EC=8A=A4=ED=8A=B8=EB=B7=B0=20=ED=82=A4=EB=B3=B4?= =?UTF-8?q?=EB=93=9C=20=EA=B4=80=EB=A0=A8=20QA=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WriteQuestionTypeQuestView.swift | 109 ++++++++++++++++-- .../WriteActiveTypeQuestViewController.swift | 22 +++- .../WriteQuestBaseViewController.swift | 104 +++++++++++++---- ...WriteQuestionTypeQuestViewController.swift | 24 +++- 4 files changed, 220 insertions(+), 39 deletions(-) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/QuestionType/WriteQuestionTypeQuestView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/QuestionType/WriteQuestionTypeQuestView.swift index c3dff053..56e8d382 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/QuestionType/WriteQuestionTypeQuestView.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/QuestionType/WriteQuestionTypeQuestView.swift @@ -12,11 +12,23 @@ import Then final class WriteQuestionTypeQuestView: BaseView { private let questScope: QuestScope + private(set) var limitCount: Int = QuestType.question.textLimit + var count: Int = 0 + private(set) var scrollView = UIScrollView() private let contentView = UIView() + private(set) var headerView = WriteQuestTitleView(questNum: 0, title: "") private let divider = UIView() private(set) var questTextField = QuestTextField(type: .question) + private var descriptionStackView = UIStackView() + private let descriptionLabel = UILabel() + private(set) var textCountLabel = UILabel() + private let errorIcon = UIImageView() + private let bottomContainerView = UIView() + + private var bottomConstraint: Constraint? + private var contentViewBottomConstraint: Constraint? init(questScope: QuestScope) { self.questScope = questScope @@ -28,13 +40,16 @@ final class WriteQuestionTypeQuestView: BaseView { } override func setUI() { - addSubview(scrollView) + addSubviews(scrollView) scrollView.addSubview(contentView) contentView.addSubviews( headerView, divider, - questTextField + questTextField, + bottomContainerView ) + bottomContainerView.addSubviews(descriptionStackView, textCountLabel) + descriptionStackView.addArrangedSubviews(errorIcon, descriptionLabel) } override func setStyle() { @@ -42,7 +57,6 @@ final class WriteQuestionTypeQuestView: BaseView { scrollView.do { $0.isScrollEnabled = true - $0.keyboardDismissMode = .onDrag $0.backgroundColor = .clear $0.isUserInteractionEnabled = true } @@ -55,6 +69,31 @@ final class WriteQuestionTypeQuestView: BaseView { divider.do { $0.backgroundColor = .grayscale800 } + + descriptionStackView.do { + $0.axis = .horizontal + $0.spacing = 3.adjustedW + } + + textCountLabel.applyByeBooFont ( + style: .cap2R12, + text: "\(count)/\(limitCount)", + color: .grayscale400 + ) + + errorIcon.do { + $0.image = .error + $0.contentMode = .scaleAspectFit + } + + descriptionLabel.applyByeBooFont( + style: .cap2R12, + text: "10글자 이상 작성해 주세요.", + color: .grayscale400, + textAlignment: .center + ) + + bottomContainerView.backgroundColor = .grayscale900 } override func touchesBegan(_ touches: Set, with event: UIEvent?) { @@ -69,8 +108,9 @@ final class WriteQuestionTypeQuestView: BaseView { contentView.snp.makeConstraints { $0.edges.equalTo(scrollView.contentLayoutGuide) $0.width.equalTo(scrollView.frameLayoutGuide) - $0.bottom.equalTo(questTextField.snp.bottom).offset(12.adjustedH) $0.height.greaterThanOrEqualTo(scrollView.frameLayoutGuide).priority(250) + contentViewBottomConstraint = + $0.bottom.equalTo(bottomContainerView.snp.bottom).offset(32.adjustedH).constraint } headerView.snp.makeConstraints { @@ -89,19 +129,38 @@ final class WriteQuestionTypeQuestView: BaseView { $0.leading.trailing.equalToSuperview().inset(24.adjustedW) $0.height.greaterThanOrEqualTo(268.adjustedH) } + + bottomContainerView.snp.makeConstraints { + $0.top.equalTo(questTextField.snp.bottom).offset(32.adjustedH) + $0.leading.trailing.equalToSuperview() + } + + descriptionStackView.snp.makeConstraints { + $0.top.equalToSuperview().inset(12.adjustedH) + $0.leading.equalToSuperview().inset(24.adjustedW) + $0.bottom.equalToSuperview().inset(12.adjustedW) + } + + textCountLabel.snp.makeConstraints { + $0.centerY.equalTo(descriptionStackView) + $0.trailing.equalToSuperview().inset(24.adjustedW) + } } } extension WriteQuestionTypeQuestView: WriteQuestBaseProtocol { - var questTextView: UITextView { - questTextField.textView + var questTextView: QuestTextField { + questTextField } - var questCountLabelView: UIView { - questTextField.textCountLabel + var questCountLabelView: UILabel { + textCountLabel } var tipTagView: UIView { headerView.tipTag ?? UIView() } + var bottomView: UIView { + bottomContainerView + } } extension WriteQuestionTypeQuestView { @@ -117,3 +176,37 @@ extension WriteQuestionTypeQuestView { ) } } + +extension WriteQuestionTypeQuestView: UpdateUIWhenKeyboardProtocol { + func updateUIWhenKeyboardUp() { + bottomContainerView.removeFromSuperview() + addSubview(bottomContainerView) + bottomContainerView.snp.remakeConstraints { $0.leading.trailing.equalToSuperview() + bottomConstraint = $0.bottom.equalToSuperview().constraint + } + contentView.snp.makeConstraints { + contentViewBottomConstraint = + $0.bottom.equalTo(questTextField.snp.bottom).offset(12.adjustedH).constraint + } + } + + func updateUIWhenKeyboardDown() { + bottomContainerView.removeFromSuperview() + contentView.addSubview(bottomContainerView) + bottomContainerView.snp.remakeConstraints { + $0.top.equalTo(questTextField.snp.bottom).offset(32.adjustedH) + $0.leading.trailing.equalToSuperview() + $0.bottom.equalToSuperview().inset(17.adjustedH) + } + + contentViewBottomConstraint?.deactivate() + contentView.snp.makeConstraints { + contentViewBottomConstraint = + $0.bottom.equalTo(bottomContainerView.snp.bottom).offset(17.adjustedH).constraint + } + } + + func updateBottomConstraint(_ offset: CGFloat) { + bottomConstraint?.update(offset: offset) + } +} diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift index a446d690..cea7c667 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift @@ -62,7 +62,7 @@ final class WriteActiveTypeQuestViewController: WriteQuestBaseViewController: @@ -23,7 +38,6 @@ class WriteQuestBaseViewController: private var currentKeyboardOffset: CGFloat = 0 private var previousTextViewHeight: CGFloat = 0 - init(rootView: RootView) { self.rootView = rootView super.init(nibName: nil, bundle: nil) @@ -97,21 +111,37 @@ class WriteQuestBaseViewController: @objc func confirmButtonDidTap() { } @objc - private func textViewMoveUp(_ notification: NSNotification) { - guard let keyboardFrame: NSValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { - return + private func keyboardWillUp(_ notification: NSNotification) { + guard let frame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect, + let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double, + let curveRaw = notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt + else { return } + + keyboardFrameInWindow = frame + scrollCountLabelIfNeeded() + applyKeyboardInset() + + let curve = UIView.AnimationOptions(rawValue: curveRaw << 16) + let keyboardHeight = max(0, view.bounds.height - frame.origin.y) + + if let rootView = rootView as? UpdateUIWhenKeyboardProtocol { + if keyboardHeight > 0 { + rootView.updateUIWhenKeyboardUp() + rootView.updateBottomConstraint(-keyboardHeight) + } + else { + rootView.updateUIWhenKeyboardDown() + } + } - keyboardFrameInWindow = keyboardFrame.cgRectValue - isKeyboardUsed = true - - DispatchQueue.main.async { [weak self] in - self?.applyKeyboardInset() - self?.scrollCountLabelIfNeeded() + UIView.animate(withDuration: duration, delay: 0, options: curve) { + self.view.layoutIfNeeded() } } + @objc - private func textViewMoveDown(_ notification: NSNotification) { + private func keyboardWillDown(_ notification: NSNotification) { keyboardFrameInWindow = .zero currentKeyboardOffset = 0 UIView.animate(withDuration: 0.3) { @@ -127,14 +157,46 @@ class WriteQuestBaseViewController: } extension WriteQuestBaseViewController { - func scrollCountLabelIfNeeded() { - let targetFrameInWindow = rootView.questCountLabelView.convert(rootView.questCountLabelView.bounds, to: nil) - guard keyboardOverlap(for: targetFrameInWindow) > 0 else { return } + func applyTextViewGrowth() { + let diff = rootView.questTextView.updateTextViewHeight() - let targetRect = rootView.questCountLabelView.convert(rootView.questCountLabelView.bounds, to: rootView.scrollView) - .insetBy(dx: 0, dy: -24.adjustedH) + guard diff > 0.5 else { return } - rootView.scrollView.scrollRectToVisible(targetRect, animated: true) + var offset = rootView.scrollView.contentOffset + offset.y += diff + let bottomContainerHeight = rootView.bottomView.frame.height + let maxOffsetY = rootView.scrollView.contentSize.height + - rootView.scrollView.bounds.height + + rootView.scrollView.contentInset.bottom + + bottomContainerHeight + + offset.y = min(offset.y, max(0, maxOffsetY)) + rootView.scrollView.setContentOffset(offset, animated: false) + } + + private func scrollCountLabelIfNeeded() { + let targetFrameInWindow = rootView.questCountLabelView.convert(rootView.questCountLabelView.bounds, to: nil) + let overlap = keyboardOverlap(for: targetFrameInWindow) + guard overlap > 0 else { return } + + let targetFrameInScroll = rootView.questCountLabelView.convert( + rootView.questCountLabelView.bounds, + to: rootView.scrollView + ) + + let bottomContainerHeight = rootView.bottomView.frame.height + let labelBottom = targetFrameInScroll.maxY + let visibleHeight = rootView.scrollView.frame.height + let padding: CGFloat = 200.adjustedH + + let targetOffsetY = labelBottom - visibleHeight + bottomContainerHeight + padding + + guard targetOffsetY > rootView.scrollView.contentOffset.y else { return } + + rootView.scrollView.setContentOffset( + CGPoint(x: 0, y: targetOffsetY), + animated: true + ) } private func keyboardOverlap(for rectInWindow: CGRect) -> CGFloat { @@ -161,12 +223,12 @@ extension WriteQuestBaseViewController { private func registerKeyboardNotificationCenter() { NotificationCenter.default.addObserver( self, - selector: #selector(textViewMoveUp), + selector: #selector(keyboardWillUp), name: UIResponder.keyboardWillShowNotification, object: nil ) NotificationCenter.default.addObserver( self, - selector: #selector(textViewMoveDown), + selector: #selector(keyboardWillDown), name: UIResponder.keyboardWillHideNotification, object: nil ) } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift index da89764e..b852b370 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift @@ -60,7 +60,8 @@ final class WriteQuestionTypeQuestViewController: WriteQuestBaseViewController Date: Mon, 16 Mar 2026 03:39:54 +0900 Subject: [PATCH 13/17] =?UTF-8?q?fix:=20#408=20=EC=95=A1=ED=8B=B0=EB=B8=8C?= =?UTF-8?q?=20=ED=82=A4=EB=B3=B4=EB=93=9C=20=EA=B4=80=EB=A0=A8=20QA=20?= =?UTF-8?q?=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Quest/View/Write/QuestTextField.swift | 4 +- .../WriteActiveTypeQuestView.swift | 92 ++++++++++++++++--- .../WriteQuestionTypeQuestView.swift | 7 +- .../WriteActiveTypeQuestViewController.swift | 2 + ...WriteQuestionTypeQuestViewController.swift | 3 + 5 files changed, 92 insertions(+), 16 deletions(-) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/QuestTextField.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/QuestTextField.swift index 059cd316..1e52b824 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/QuestTextField.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/QuestTextField.swift @@ -61,7 +61,7 @@ final class QuestTextField: BaseView { override func setLayout() { self.snp.makeConstraints { $0.width.equalTo(327.adjustedW) - containerHeightConsraint = $0.height.equalTo(268.adjustedH).constraint + containerHeightConsraint = $0.height.greaterThanOrEqualTo(268.adjustedH).constraint } textView.snp.makeConstraints { @@ -80,7 +80,7 @@ extension QuestTextField: UITextViewDelegate { applyTextViewStyle(text: "", color: .grayscale100) } textView.textColor = .grayscale100 - questTextViewDelegate?.textViewDidEndEditing() + questTextViewDelegate?.textViewDidBeginEditing() } func textViewDidEndEditing(_ textView: UITextView) { diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/ActivationType/WriteActiveTypeQuestView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/ActivationType/WriteActiveTypeQuestView.swift index 42c3b21d..0de2ad87 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/ActivationType/WriteActiveTypeQuestView.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/ActivationType/WriteActiveTypeQuestView.swift @@ -11,9 +11,12 @@ import SnapKit import Then final class WriteActiveTypeQuestView: BaseView { + private(set) var limitCount: Int = QuestType.activation.textLimit + var count: Int = 0 + private(set) var scrollView = UIScrollView() private let contentView = UIView() - + private(set) var headerView = WriteQuestTitleView(questNum: 0, title: "") private let divider = UIView() @@ -28,7 +31,10 @@ final class WriteActiveTypeQuestView: BaseView { private let grayTag = ByeBooFilledTag(tagType: .smallGray, text: "선택") private let thinkTitleLabel = UILabel() private(set) var questTextField = QuestTextField(type: .activation) - + + private(set) var textCountLabel = UILabel() + private var bottomConstraint: Constraint? + private var contentViewBottomConstraint: Constraint? override func setUI() { addSubviews(scrollView) @@ -40,7 +46,8 @@ final class WriteActiveTypeQuestView: BaseView { imgTitleContainerView, textStackView, imageContainer, - questTextField + questTextField, + textCountLabel ) imgTitleContainerView.addSubviews( @@ -57,7 +64,6 @@ final class WriteActiveTypeQuestView: BaseView { scrollView.do { $0.isScrollEnabled = true - $0.keyboardDismissMode = .onDrag $0.backgroundColor = .clear $0.isUserInteractionEnabled = true } @@ -93,7 +99,13 @@ final class WriteActiveTypeQuestView: BaseView { style: .body2M16, text: "생각 적기", color: .grayscale50 - ) + ) + + textCountLabel.applyByeBooFont ( + style: .cap2R12, + text: "\(count)/\(limitCount)", + color: .grayscale400 + ) } override func setLayout() { @@ -104,8 +116,7 @@ final class WriteActiveTypeQuestView: BaseView { contentView.snp.makeConstraints { $0.edges.equalTo(scrollView.contentLayoutGuide) $0.width.equalTo(scrollView.frameLayoutGuide) - $0.bottom.equalTo(questTextField.snp.bottom).offset(12.adjustedH) - $0.height.greaterThanOrEqualTo(scrollView.frameLayoutGuide) + $0.height.greaterThanOrEqualTo(scrollView.frameLayoutGuide).priority(250) } headerView.snp.makeConstraints { @@ -161,6 +172,12 @@ final class WriteActiveTypeQuestView: BaseView { $0.leading.trailing.equalToSuperview().inset(24.adjustedW) $0.height.greaterThanOrEqualTo(280.adjustedH) } + + textCountLabel.snp.makeConstraints { + $0.top.equalTo(questTextField.snp.bottom).offset(32.adjustedH) + $0.trailing.equalToSuperview().inset(24.adjustedW) + $0.bottom.equalToSuperview().inset(24.adjustedH) + } } override func touchesBegan(_ touches: Set, with event: UIEvent?) { @@ -173,15 +190,18 @@ final class WriteActiveTypeQuestView: BaseView { } extension WriteActiveTypeQuestView: WriteQuestBaseProtocol { - var questTextView: UITextView { - questTextField.textView + var questTextView: QuestTextField { + questTextField } - var questCountLabelView: UIView { - questTextField.textCountLabel + var questCountLabelView: UILabel { + textCountLabel } var tipTagView: UIView { headerView.tipTag ?? UIView() } + var bottomView: UIView { + textCountLabel + } } extension WriteActiveTypeQuestView { @@ -197,3 +217,53 @@ extension WriteActiveTypeQuestView { ) } } + +extension WriteActiveTypeQuestView: UpdateUIWhenKeyboardProtocol { + func updateUIWhenKeyboardUp() { + textCountLabel.removeFromSuperview() + addSubview(textCountLabel) + textCountLabel.snp.remakeConstraints { + $0.trailing.equalToSuperview().inset(24.adjustedW) + bottomConstraint = $0.bottom.equalToSuperview().inset(13.adjustedH).constraint + } + + contentView.snp.remakeConstraints { + $0.edges.equalTo(scrollView.contentLayoutGuide) + $0.width.equalTo(scrollView.frameLayoutGuide) + $0.height.greaterThanOrEqualTo(scrollView.frameLayoutGuide).priority(250) + } + questTextField.snp.remakeConstraints { + $0.top.equalTo(textStackView.snp.bottom).offset(8.adjustedH) + $0.leading.trailing.equalToSuperview().inset(24.adjustedW) + $0.height.greaterThanOrEqualTo(280.adjustedH) + $0.bottom.equalToSuperview().inset(17.adjustedH) + } + } + + func updateUIWhenKeyboardDown() { + textCountLabel.removeFromSuperview() + contentView.addSubview(textCountLabel) + questTextField.snp.remakeConstraints { + $0.top.equalTo(textStackView.snp.bottom).offset(8.adjustedH) + $0.leading.trailing.equalToSuperview().inset(24.adjustedW) + $0.height.greaterThanOrEqualTo(280.adjustedH) + } + + textCountLabel.snp.remakeConstraints { + $0.top.equalTo(questTextField.snp.bottom).offset(32.adjustedH) + $0.trailing.equalToSuperview().inset(24.adjustedW) + $0.bottom.equalToSuperview().inset(24.adjustedH) + } + + contentView.snp.remakeConstraints { + $0.edges.equalTo(scrollView.contentLayoutGuide) + $0.width.equalTo(scrollView.frameLayoutGuide) + $0.height.greaterThanOrEqualTo(scrollView.frameLayoutGuide).priority(250) + } + } + + func updateBottomConstraint(_ offset: CGFloat) { + bottomConstraint?.update(offset: offset - 13.adjustedH) + } +} + diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/QuestionType/WriteQuestionTypeQuestView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/QuestionType/WriteQuestionTypeQuestView.swift index 56e8d382..ab6cd253 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/QuestionType/WriteQuestionTypeQuestView.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/QuestionType/WriteQuestionTypeQuestView.swift @@ -181,7 +181,8 @@ extension WriteQuestionTypeQuestView: UpdateUIWhenKeyboardProtocol { func updateUIWhenKeyboardUp() { bottomContainerView.removeFromSuperview() addSubview(bottomContainerView) - bottomContainerView.snp.remakeConstraints { $0.leading.trailing.equalToSuperview() + bottomContainerView.snp.remakeConstraints { + $0.leading.trailing.equalToSuperview() bottomConstraint = $0.bottom.equalToSuperview().constraint } contentView.snp.makeConstraints { @@ -200,13 +201,13 @@ extension WriteQuestionTypeQuestView: UpdateUIWhenKeyboardProtocol { } contentViewBottomConstraint?.deactivate() - contentView.snp.makeConstraints { + contentView.snp.remakeConstraints { contentViewBottomConstraint = $0.bottom.equalTo(bottomContainerView.snp.bottom).offset(17.adjustedH).constraint } } func updateBottomConstraint(_ offset: CGFloat) { - bottomConstraint?.update(offset: offset) + bottomConstraint?.update(offset: offset - 13.adjustedH) } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift index cea7c667..cd567f90 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift @@ -63,6 +63,7 @@ final class WriteActiveTypeQuestViewController: WriteQuestBaseViewController Date: Mon, 16 Mar 2026 12:51:51 +0900 Subject: [PATCH 14/17] =?UTF-8?q?fix:=20#408=20=ED=83=AD=EB=B0=94=20?= =?UTF-8?q?=ED=9E=88=EB=93=A0=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Quest/ViewController/CommonQuestViewController.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift index 5530799a..95a93e5c 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift @@ -105,6 +105,7 @@ extension CommonQuestViewController: DateNavigatorDelegate { writeCommonQuestViewController.navigationItem.hidesBackButton = true writeCommonQuestViewController.questScope = .common writeCommonQuestViewController.configureToWrite(questID, nil, QuestType.question, viewModel.question) + writeCommonQuestViewController.tabBarController?.tabBar.isHidden = true self.navigationController?.pushViewController(writeCommonQuestViewController, animated: false) } @@ -147,7 +148,7 @@ extension CommonQuestViewController: UITableViewDelegate { isMyAnswer: answer.isMyAnswer ) historyViewController.navigationItem.hidesBackButton = true - + historyViewController.tabBarController?.tabBar.isHidden = true self.navigationController?.pushViewController( historyViewController, animated: false From 96997f74c627e132416be52b57a5480c13210a55 Mon Sep 17 00:00:00 2001 From: yeonee Date: Mon, 16 Mar 2026 12:56:06 +0900 Subject: [PATCH 15/17] =?UTF-8?q?fox:=20#408=20=ED=83=AD=EB=B0=94=20?= =?UTF-8?q?=ED=9E=88=EB=93=A0=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewController/CommonQuestHistoryViewController.swift | 5 +++++ .../Quest/ViewController/CommonQuestViewController.swift | 2 -- .../WriteQuestionTypeQuestViewController.swift | 5 +++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestHistoryViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestHistoryViewController.swift index 04e602f5..ae397fd9 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestHistoryViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestHistoryViewController.swift @@ -21,6 +21,11 @@ final class CommonQuestHistoryViewController: BaseViewController { view = rootView } + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.tabBarController?.tabBar.isHidden = true + } + override func viewDidLoad() { super.viewDidLoad() diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift index 95a93e5c..eb47f5f4 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/CommonQuestViewController.swift @@ -105,7 +105,6 @@ extension CommonQuestViewController: DateNavigatorDelegate { writeCommonQuestViewController.navigationItem.hidesBackButton = true writeCommonQuestViewController.questScope = .common writeCommonQuestViewController.configureToWrite(questID, nil, QuestType.question, viewModel.question) - writeCommonQuestViewController.tabBarController?.tabBar.isHidden = true self.navigationController?.pushViewController(writeCommonQuestViewController, animated: false) } @@ -148,7 +147,6 @@ extension CommonQuestViewController: UITableViewDelegate { isMyAnswer: answer.isMyAnswer ) historyViewController.navigationItem.hidesBackButton = true - historyViewController.tabBarController?.tabBar.isHidden = true self.navigationController?.pushViewController( historyViewController, animated: false diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift index 3744b14c..2ade99b6 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift @@ -38,6 +38,11 @@ final class WriteQuestionTypeQuestViewController: WriteQuestBaseViewController Date: Mon, 16 Mar 2026 16:57:27 +0900 Subject: [PATCH 16/17] =?UTF-8?q?fix:=20#408=20=EB=94=94=ED=85=8C=EC=9D=BC?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Quest/View/Write/QuestTextField.swift | 1 - .../WriteActiveTypeQuestView.swift | 77 ++++++++++++------- .../WriteQuestionTypeQuestView.swift | 38 ++++++--- .../View/Write/WriteQuestTitleView.swift | 2 +- .../ArchiveQuestViewController.swift | 7 +- .../WriteActiveTypeQuestViewController.swift | 15 +++- ...WriteQuestionTypeQuestViewController.swift | 7 +- .../Protocol/EditQuestProtocol.swift | 2 +- 8 files changed, 101 insertions(+), 48 deletions(-) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/QuestTextField.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/QuestTextField.swift index 1e52b824..7b5e00dc 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/QuestTextField.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/QuestTextField.swift @@ -80,7 +80,6 @@ extension QuestTextField: UITextViewDelegate { applyTextViewStyle(text: "", color: .grayscale100) } textView.textColor = .grayscale100 - questTextViewDelegate?.textViewDidBeginEditing() } func textViewDidEndEditing(_ textView: UITextView) { diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/ActivationType/WriteActiveTypeQuestView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/ActivationType/WriteActiveTypeQuestView.swift index 0de2ad87..1981f37a 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/ActivationType/WriteActiveTypeQuestView.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/ActivationType/WriteActiveTypeQuestView.swift @@ -27,11 +27,12 @@ final class WriteActiveTypeQuestView: BaseView { var imgCount: Int = 0 private(set) var imageContainer = ImagePickerContainer() - private let textStackView = UIStackView() + private let questFieldTitleView = UIView() private let grayTag = ByeBooFilledTag(tagType: .smallGray, text: "선택") private let thinkTitleLabel = UILabel() private(set) var questTextField = QuestTextField(type: .activation) + private let bottomContainerView = UIView() private(set) var textCountLabel = UILabel() private var bottomConstraint: Constraint? private var contentViewBottomConstraint: Constraint? @@ -44,19 +45,21 @@ final class WriteActiveTypeQuestView: BaseView { headerView, divider, imgTitleContainerView, - textStackView, + questFieldTitleView, imageContainer, questTextField, - textCountLabel + bottomContainerView ) imgTitleContainerView.addSubviews( yellowTag, imgTitleLabel, imgCountLabel ) - textStackView.addArrangedSubviews( + questFieldTitleView.addSubviews( grayTag, thinkTitleLabel ) + + bottomContainerView.addSubview(textCountLabel) } override func setStyle() { @@ -89,18 +92,14 @@ final class WriteActiveTypeQuestView: BaseView { color: .grayscale400 ) - textStackView.do { - $0.axis = .horizontal - $0.spacing = 8 - $0.alignment = .center - } - thinkTitleLabel.applyByeBooFont( style: .body2M16, text: "생각 적기", color: .grayscale50 ) + bottomContainerView.backgroundColor = .grayscale900 + textCountLabel.applyByeBooFont ( style: .cap2R12, text: "\(count)/\(limitCount)", @@ -117,6 +116,8 @@ final class WriteActiveTypeQuestView: BaseView { $0.edges.equalTo(scrollView.contentLayoutGuide) $0.width.equalTo(scrollView.frameLayoutGuide) $0.height.greaterThanOrEqualTo(scrollView.frameLayoutGuide).priority(250) + contentViewBottomConstraint = + $0.bottom.equalTo(bottomContainerView.snp.bottom).offset(32.adjustedH).constraint } headerView.snp.makeConstraints { @@ -160,23 +161,39 @@ final class WriteActiveTypeQuestView: BaseView { $0.width.height.equalTo(327.adjustedW) } - textStackView.snp.makeConstraints { + questFieldTitleView.snp.makeConstraints { $0.top.equalTo(imageContainer.snp.bottom).offset(16.adjustedH) - $0.width.equalTo(327.adjustedW) $0.height.equalTo(24.adjustedH) - $0.leading.trailing.equalToSuperview().inset(24.adjustedW) + $0.leading.equalToSuperview().inset(24.adjustedW) + } + + grayTag.snp.makeConstraints { + $0.top.equalToSuperview() + $0.leading.equalToSuperview() + $0.centerY.equalToSuperview() + } + + thinkTitleLabel.snp.makeConstraints { + $0.top.equalToSuperview() + $0.leading.equalTo(grayTag.snp.trailing).offset(8.adjustedH) + $0.centerY.equalToSuperview() } questTextField.snp.makeConstraints { - $0.top.equalTo(textStackView.snp.bottom).offset(8.adjustedH) + $0.top.equalTo(questFieldTitleView.snp.bottom).offset(12.adjustedH) $0.leading.trailing.equalToSuperview().inset(24.adjustedW) $0.height.greaterThanOrEqualTo(280.adjustedH) } - textCountLabel.snp.makeConstraints { + bottomContainerView.snp.makeConstraints { $0.top.equalTo(questTextField.snp.bottom).offset(32.adjustedH) + $0.leading.trailing.equalToSuperview() + $0.height.equalTo(42.adjustedH) + } + + textCountLabel.snp.makeConstraints { + $0.bottom.equalToSuperview().inset(13.adjustedH) $0.trailing.equalToSuperview().inset(24.adjustedW) - $0.bottom.equalToSuperview().inset(24.adjustedH) } } @@ -200,7 +217,7 @@ extension WriteActiveTypeQuestView: WriteQuestBaseProtocol { headerView.tipTag ?? UIView() } var bottomView: UIView { - textCountLabel + bottomContainerView } } @@ -220,11 +237,12 @@ extension WriteActiveTypeQuestView { extension WriteActiveTypeQuestView: UpdateUIWhenKeyboardProtocol { func updateUIWhenKeyboardUp() { - textCountLabel.removeFromSuperview() - addSubview(textCountLabel) - textCountLabel.snp.remakeConstraints { - $0.trailing.equalToSuperview().inset(24.adjustedW) - bottomConstraint = $0.bottom.equalToSuperview().inset(13.adjustedH).constraint + bottomContainerView.removeFromSuperview() + addSubview(bottomContainerView) + bottomContainerView.snp.remakeConstraints { + $0.leading.trailing.equalToSuperview() + $0.height.equalTo(42.adjustedH) + bottomConstraint = $0.bottom.equalToSuperview().constraint } contentView.snp.remakeConstraints { @@ -233,7 +251,7 @@ extension WriteActiveTypeQuestView: UpdateUIWhenKeyboardProtocol { $0.height.greaterThanOrEqualTo(scrollView.frameLayoutGuide).priority(250) } questTextField.snp.remakeConstraints { - $0.top.equalTo(textStackView.snp.bottom).offset(8.adjustedH) + $0.top.equalTo(questFieldTitleView.snp.bottom).offset(12.adjustedH) $0.leading.trailing.equalToSuperview().inset(24.adjustedW) $0.height.greaterThanOrEqualTo(280.adjustedH) $0.bottom.equalToSuperview().inset(17.adjustedH) @@ -241,18 +259,19 @@ extension WriteActiveTypeQuestView: UpdateUIWhenKeyboardProtocol { } func updateUIWhenKeyboardDown() { - textCountLabel.removeFromSuperview() - contentView.addSubview(textCountLabel) + bottomContainerView.removeFromSuperview() + contentView.addSubview(bottomContainerView) questTextField.snp.remakeConstraints { - $0.top.equalTo(textStackView.snp.bottom).offset(8.adjustedH) + $0.top.equalTo(questFieldTitleView.snp.bottom).offset(12.adjustedH) $0.leading.trailing.equalToSuperview().inset(24.adjustedW) $0.height.greaterThanOrEqualTo(280.adjustedH) } - textCountLabel.snp.remakeConstraints { + bottomContainerView.snp.remakeConstraints { $0.top.equalTo(questTextField.snp.bottom).offset(32.adjustedH) - $0.trailing.equalToSuperview().inset(24.adjustedW) + $0.leading.trailing.equalToSuperview() $0.bottom.equalToSuperview().inset(24.adjustedH) + $0.height.equalTo(42.adjustedH) } contentView.snp.remakeConstraints { @@ -263,7 +282,7 @@ extension WriteActiveTypeQuestView: UpdateUIWhenKeyboardProtocol { } func updateBottomConstraint(_ offset: CGFloat) { - bottomConstraint?.update(offset: offset - 13.adjustedH) + bottomConstraint?.update(offset: offset) } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/QuestionType/WriteQuestionTypeQuestView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/QuestionType/WriteQuestionTypeQuestView.swift index ab6cd253..ed525120 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/QuestionType/WriteQuestionTypeQuestView.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/View/QuestionType/WriteQuestionTypeQuestView.swift @@ -133,16 +133,16 @@ final class WriteQuestionTypeQuestView: BaseView { bottomContainerView.snp.makeConstraints { $0.top.equalTo(questTextField.snp.bottom).offset(32.adjustedH) $0.leading.trailing.equalToSuperview() + $0.height.equalTo(56.adjustedH) } descriptionStackView.snp.makeConstraints { - $0.top.equalToSuperview().inset(12.adjustedH) + $0.bottom.equalToSuperview().inset(13.adjustedH) $0.leading.equalToSuperview().inset(24.adjustedW) - $0.bottom.equalToSuperview().inset(12.adjustedW) } textCountLabel.snp.makeConstraints { - $0.centerY.equalTo(descriptionStackView) + $0.bottom.equalToSuperview().inset(13.adjustedH) $0.trailing.equalToSuperview().inset(24.adjustedW) } } @@ -183,31 +183,47 @@ extension WriteQuestionTypeQuestView: UpdateUIWhenKeyboardProtocol { addSubview(bottomContainerView) bottomContainerView.snp.remakeConstraints { $0.leading.trailing.equalToSuperview() + $0.height.equalTo(42.adjustedH) bottomConstraint = $0.bottom.equalToSuperview().constraint } - contentView.snp.makeConstraints { - contentViewBottomConstraint = - $0.bottom.equalTo(questTextField.snp.bottom).offset(12.adjustedH).constraint + contentView.snp.remakeConstraints { + $0.edges.equalTo(scrollView.contentLayoutGuide) + $0.width.equalTo(scrollView.frameLayoutGuide) + $0.height.greaterThanOrEqualTo(scrollView.frameLayoutGuide).priority(250) + } + + questTextField.snp.remakeConstraints { + $0.top.equalTo(divider.snp.bottom).offset(8.adjustedH) + $0.leading.trailing.equalToSuperview().inset(24.adjustedW) + $0.height.greaterThanOrEqualTo(280.adjustedH) + $0.bottom.equalToSuperview().inset(17.adjustedH) } } func updateUIWhenKeyboardDown() { bottomContainerView.removeFromSuperview() contentView.addSubview(bottomContainerView) + + questTextField.snp.remakeConstraints { + $0.top.equalTo(divider.snp.bottom).offset(20.adjustedH) + $0.leading.trailing.equalToSuperview().inset(24.adjustedW) + $0.height.greaterThanOrEqualTo(280.adjustedH) + } + bottomContainerView.snp.remakeConstraints { $0.top.equalTo(questTextField.snp.bottom).offset(32.adjustedH) $0.leading.trailing.equalToSuperview() $0.bottom.equalToSuperview().inset(17.adjustedH) + $0.height.equalTo(42.adjustedH) } - - contentViewBottomConstraint?.deactivate() contentView.snp.remakeConstraints { - contentViewBottomConstraint = - $0.bottom.equalTo(bottomContainerView.snp.bottom).offset(17.adjustedH).constraint + $0.edges.equalTo(scrollView.contentLayoutGuide) + $0.width.equalTo(scrollView.frameLayoutGuide) + $0.height.greaterThanOrEqualTo(scrollView.frameLayoutGuide).priority(250) } } func updateBottomConstraint(_ offset: CGFloat) { - bottomConstraint?.update(offset: offset - 13.adjustedH) + bottomConstraint?.update(offset: offset) } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/WriteQuestTitleView.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/WriteQuestTitleView.swift index f63d638c..2682a983 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/WriteQuestTitleView.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/View/Write/WriteQuestTitleView.swift @@ -101,7 +101,7 @@ final class WriteQuestTitleView: BaseView { extension WriteQuestTitleView { func bind(questScope: QuestScope?, questNum: Int, title: String) { - self.questNum = questNum + questNumLabel.text = "\(questNum)번째 퀘스트" self.titleLabel.text = title if let questScope { diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/ArchiveQuestViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/ArchiveQuestViewController.swift index f753e456..92426597 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/ArchiveQuestViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/ArchiveQuestViewController.swift @@ -170,7 +170,12 @@ extension ArchiveQuestViewController { var viewController: ( BaseViewController & EditQuestProtocol ) viewController = setNavigateViewController(type: rootView.type) viewController.questMode = .edit - viewController.getExistingQuest(questID: self.viewModel.questID ,questAnswer: entity.answer, image: entity.imageUrl, imageKey: entity.imageKey) + viewController.getExistingQuest( + questID: self.viewModel.questID , + questAnswer: entity.answer, + questNumber: entity.questNumber, + image: entity.imageUrl, + imageKey: entity.imageKey) viewController.tabBarController?.tabBar.isHidden = true self.navigationController?.pushViewController(viewController, animated: false) } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift index cd567f90..7109a3b1 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift @@ -280,12 +280,22 @@ extension WriteActiveTypeQuestViewController { } extension WriteActiveTypeQuestViewController: EditQuestProtocol { - func getExistingQuest(questID: Int, questAnswer: String?, image: String?, imageKey: String?) { + func getExistingQuest( + questID: Int, + questAnswer: String?, + questNumber: Int?, + image: String?, + imageKey: String?) + { self.questID = questID self.viewModel.action(.navigateFromArchiveViewController(questID: questID)) - guard let questAnswer = questAnswer, let image = image, let imageKey = imageKey else { return } + guard let questAnswer = questAnswer, + let questNumber = questNumber, + let image = image, + let imageKey = imageKey else { return } self.originalImageKey = imageKey self.answerText = questAnswer + self.questNumber = questNumber rootView.imageContainer.selectedImageView.kf.setImage(with: URL(string: image)) { result in switch result { case .success(let value): @@ -306,6 +316,7 @@ extension WriteActiveTypeQuestViewController: EditQuestProtocol { } else { rootView.questTextField.textView.text = questAnswer + applyTextViewGrowth() rootView.questTextField.isPlaceholderActive = false } } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift index 2ade99b6..0e176716 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift @@ -365,17 +365,20 @@ extension WriteQuestionTypeQuestViewController: EditQuestProtocol { func getExistingQuest( questID: Int, questAnswer: String?, + questNumber: Int?, image: String?, imageKey: String? ) { self.questID = questID self.viewModel.action(.viewDidLoadWhenEditMode(questID: questID)) - guard let questAnswer = questAnswer else { + guard let questAnswer = questAnswer, let questNumber = questNumber else { return } self.answerText = questAnswer + self.questNumber = questNumber + setQuestTextField(answer: questAnswer) rootView.textCountLabel.text = "\(answerText.count)/\(rootView.limitCount)" self.navigationItem.rightBarButtonItem?.isEnabled = false @@ -391,7 +394,7 @@ extension WriteQuestionTypeQuestViewController: QuestCompleteProtocol { extension WriteQuestionTypeQuestViewController: WriteQuestTextViewProtocol { func textViewDidBeginEditing() { - self.rootView.updateUIWhenKeyboardUp() +// self.rootView.updateUIWhenKeyboardUp() } func textViewDidEndEditing() { diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Protocol/EditQuestProtocol.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Protocol/EditQuestProtocol.swift index f50e4c5e..544217bd 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Protocol/EditQuestProtocol.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Protocol/EditQuestProtocol.swift @@ -7,5 +7,5 @@ protocol EditQuestProtocol { var questMode: QuestMode { get set } - func getExistingQuest(questID: Int, questAnswer: String?, image: String?, imageKey: String?) + func getExistingQuest(questID: Int, questAnswer: String?, questNumber: Int?, image: String?, imageKey: String?) } From a040c291fba1415e3064e9c997fdbedf6d5ba4ff Mon Sep 17 00:00:00 2001 From: yeonee Date: Mon, 16 Mar 2026 21:08:02 +0900 Subject: [PATCH 17/17] =?UTF-8?q?chore:=20#408=20=ED=95=84=EC=9A=94?= =?UTF-8?q?=EC=97=86=EB=8A=94=20=ED=95=A8=EC=88=98=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewController/WriteActiveTypeQuestViewController.swift | 4 ---- .../Quest/ViewController/WriteQuestBaseViewController.swift | 1 - .../ViewController/WriteQuestionTypeQuestViewController.swift | 4 ---- 3 files changed, 9 deletions(-) diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift index 7109a3b1..fd11e45f 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteActiveTypeQuestViewController.swift @@ -337,10 +337,6 @@ extension WriteActiveTypeQuestViewController: QuestCompleteProtocol { } extension WriteActiveTypeQuestViewController: WriteQuestTextViewProtocol { - func textViewDidBeginEditing() { - self.rootView.updateUIWhenKeyboardUp() - } - func textViewDidEndEditing() { self.rootView.questCountLabelView.textColor = .grayscale300 self.rootView.updateUIWhenKeyboardDown() diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestBaseViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestBaseViewController.swift index 2458847d..6d029e49 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestBaseViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestBaseViewController.swift @@ -18,7 +18,6 @@ protocol WriteQuestBaseProtocol where Self: UIView { } protocol WriteQuestTextViewProtocol: AnyObject { - func textViewDidBeginEditing() func textViewDidEndEditing() func textViewDidChange(count: Int) } diff --git a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift index 0e176716..dfd40b89 100644 --- a/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift +++ b/ByeBoo-iOS/ByeBoo-iOS/Presentation/Feature/Quest/ViewController/WriteQuestionTypeQuestViewController.swift @@ -393,10 +393,6 @@ extension WriteQuestionTypeQuestViewController: QuestCompleteProtocol { extension WriteQuestionTypeQuestViewController: WriteQuestTextViewProtocol { - func textViewDidBeginEditing() { -// self.rootView.updateUIWhenKeyboardUp() - } - func textViewDidEndEditing() { self.rootView.questCountLabelView.textColor = .grayscale300 self.rootView.updateUIWhenKeyboardDown()