Skip to content

Commit

Permalink
[Design] 반려견 경험 입력 페이지 UI 구현 (#143)
Browse files Browse the repository at this point in the history
  • Loading branch information
woongaaaa authored Jan 11, 2025
2 parents 965509a + 76383b1 commit 5b64978
Show file tree
Hide file tree
Showing 8 changed files with 453 additions and 7 deletions.
3 changes: 0 additions & 3 deletions walkmong/walkmong/Application/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
window?.rootViewController = navigationController
}

let splashViewController = MatchingApplyWalkRequestViewController()
window?.rootViewController = splashViewController

window?.overrideUserInterfaceStyle = .light
window?.makeKeyAndVisible()
}
Expand Down
88 changes: 88 additions & 0 deletions walkmong/walkmong/Global/Components/CountingTextView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//
// CountingTextView.swift
// walkmong
//
// Created by 황채웅 on 1/11/25.
//

import Foundation
import UIKit

final class CountingTextView: UITextView {

private let maxCharacter: Int
private let countingLabel = MainParagraphLabel(text: "(0/250)")
private var placeHolderText: String

init(placeHolderText: String, maxCharacter: Int) {
self.placeHolderText = placeHolderText
self.maxCharacter = maxCharacter
super.init(frame: .zero, textContainer: nil)
self.textContainer.lineBreakMode = .byWordWrapping
self.textContainerInset = UIEdgeInsets(top: 12, left: 12, bottom: 12, right: 12)
self.textColor = .gray400
self.backgroundColor = .gray100
self.layer.cornerRadius = 5
self.text = placeHolderText
self.textAlignment = .left
self.font = UIFont(name: "Pretendard-Regular", size: 16)
self.showsVerticalScrollIndicator = false
self.delegate = self
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func layoutSubviews() {
addSubview()
setConstraints()
updateCountingLabel()
}

private func addSubview() {
self.addSubview(countingLabel)
}

private func setConstraints() {
countingLabel.textAlignment = .right
countingLabel.snp.makeConstraints { make in
make.trailing.equalToSuperview().inset(12)
make.bottom.equalToSuperview().inset(12)
}
}

private func updateCountingLabel() {
let currentCount = self.text == placeHolderText ? 0 : self.text.count
countingLabel.text = "(\(currentCount)/\(maxCharacter))"
countingLabel.textColor = currentCount == 0 ? .gray400 : .mainBlue
}

private func isPlaceholderActive() -> Bool {
return self.text == placeHolderText
}
}

extension CountingTextView: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
if textView.text.count > maxCharacter {
textView.text = String(textView.text.prefix(maxCharacter))
}
updateCountingLabel()
}

func textViewDidBeginEditing(_ textView: UITextView) {
if isPlaceholderActive() {
textView.text = ""
textView.textColor = .gray500
}
}

func textViewDidEndEditing(_ textView: UITextView) {
if textView.text.isEmpty {
textView.text = placeHolderText
textView.textColor = .gray400
}
updateCountingLabel()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,36 @@ import UIKit

final class MatchingApplyFirstIntroductionViewController: UIViewController {

private let matchingApplyFirstIntroductionView = MatchingApplyFirstIntroductionView()

override func viewDidLoad() {
super.viewDidLoad()

view.backgroundColor = .white
setUI()
}
private func addSubview() {
view.addSubview(matchingApplyFirstIntroductionView)
}

private func setConstraints() {
matchingApplyFirstIntroductionView.snp.makeConstraints { make in
make.horizontalEdges.bottom.equalToSuperview()
make.top.equalToSuperview().offset(156)
}
}

private func setUI() {
addSubview()
setConstraints()
addCustomNavigationBar(titleText: "", showLeftBackButton: true, showLeftCloseButton: false, showRightCloseButton: false, showRightRefreshButton: false)
addProgressBar(currentStep: 3, totalSteps: 7)
matchingApplyFirstIntroductionView.delegate = self
dismissKeyboardOnTap()
}
}

extension MatchingApplyFirstIntroductionViewController: MatchingApplyFirstIntroductionViewDelegate {
func didTapNextButton(_ message: String) {
//TODO: 산책 추가 정보 등록 API 호출
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,71 @@

import UIKit

protocol MatchingApplyFirstIntroductionViewDelegate: AnyObject {
func didTapNextButton(_ message: String)
}

final class MatchingApplyFirstIntroductionView: UIView {

private let titleLabel = MiddleTitleLabel(text: "본인을 소개하는 글을 작성해주세요.")

private let textView = CountingTextView(placeHolderText: "본인의 성향, 반려동물을 사랑하는 마음 등을 간단히 적어주세요. 상대방이 신뢰할 수 있는 소개가 좋아요! (최소 20자 이상)", maxCharacter: 250)

private let nextButton = NextButton(text: "저장하기")

weak var delegate: MatchingApplyFirstIntroductionViewDelegate?

override init(frame: CGRect) {
super.init(frame: frame)
addSubview()
setConstraints()
setButtonAction()
}

required init(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

private func addSubview() {
addSubviews(titleLabel, textView, nextButton)
}

private func setConstraints() {
titleLabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(15)
make.horizontalEdges.equalToSuperview().inset(18)
}
textView.snp.makeConstraints { make in
make.horizontalEdges.equalToSuperview().inset(16)
make.top.equalTo(titleLabel.snp.bottom).offset(20)
make.height.equalTo(169)
}
nextButton.snp.makeConstraints { make in
make.height.equalTo(54)
make.horizontalEdges.equalToSuperview().inset(20)
make.bottom.equalToSuperview().inset(58)
}
}

private func setButtonAction() {
nextButton.setButtonState(isEnabled: true)
nextButton.addTarget(self, action: #selector(nextButtonTapped), for: .touchUpInside)
}

@objc private func nextButtonTapped() {
if textView.text.count >= 20 {
delegate?.didTapNextButton(textView.text)
}else {
if let vc = self.getViewController() {
CustomAlertViewController.CustomAlertBuilder(viewController: vc)
.setButtonState(.singleButton)
.setTitleState(.useTitleOnly)
.setSingleButtonTitle("돌아가기")
.setTitleText("20자 이상 입력해주세요")
.showAlertView()
}
}
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,37 @@
import UIKit

final class MatchingApplyPetExperienceViewController: UIViewController {


private let matchingApplyPetExperienceView = MatchingApplyPetExperienceView()

override func viewDidLoad() {
super.viewDidLoad()

view.backgroundColor = .white
setUI()
}
private func addSubview() {
view.addSubview(matchingApplyPetExperienceView)
}

private func setConstraints() {
matchingApplyPetExperienceView.snp.makeConstraints { make in
make.horizontalEdges.bottom.equalToSuperview()
make.top.equalToSuperview().offset(156)
}
}

private func setUI() {
addSubview()
setConstraints()
addCustomNavigationBar(titleText: "", showLeftBackButton: true, showLeftCloseButton: false, showRightCloseButton: false, showRightRefreshButton: false)
addProgressBar(currentStep: 1, totalSteps: 7)
matchingApplyPetExperienceView.delegate = self
}
}

extension MatchingApplyPetExperienceViewController: MatchingApplyPetExperienceViewDelegate {
func didSelectExperience(_ experienceYn: String) {
let nextVC = MatchingApplyPetWalkExperienceViewController()
navigationController?.pushViewController(nextVC, animated: true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,100 @@

import UIKit

protocol MatchingApplyPetExperienceViewDelegate: AnyObject {
func didSelectExperience(_ experienceYn: String)
}

final class MatchingApplyPetExperienceView: UIView {

private let titleLabel = MiddleTitleLabel(text: "반려견을 키운 경험이 있나요?")
private let stackView: UIStackView = {
let stackView = UIStackView()
stackView.alignment = .fill
stackView.distribution = .fillEqually
stackView.axis = .vertical
stackView.spacing = 12
return stackView
}()
private let tenYearsButton = UIButton.createStyledButton(type: .largeSelection, style: .light, title: "10년 이상")
private let fiveYearsButton = UIButton.createStyledButton(type: .largeSelection, style: .light, title: "5년 이상")
private let threeYearsOverButton = UIButton.createStyledButton(type: .largeSelection, style: .light, title: "3년 이상")
private let threeYearsUnderButton = UIButton.createStyledButton(type: .largeSelection, style: .light, title: "3년 미만")
private let zeroButton = UIButton.createStyledButton(type: .largeSelection, style: .light, title: "반려동물을 키운 경험이 없어요")
private let nextButton = NextButton(text: "다음으로")

weak var delegate: MatchingApplyPetExperienceViewDelegate?

private var selectedButton: UIButton?

override init(frame: CGRect) {
super.init(frame: frame)
addSubview()
setConstraints()
setButtonAction()
}

required init(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

private func addSubview() {
addSubviews(titleLabel, stackView, nextButton)
stackView.addArrangedSubview(tenYearsButton)
stackView.addArrangedSubview(fiveYearsButton)
stackView.addArrangedSubview(threeYearsOverButton)
stackView.addArrangedSubview(threeYearsUnderButton)
stackView.addArrangedSubview(zeroButton)
}

private func setConstraints() {
titleLabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(15)
make.horizontalEdges.equalToSuperview().inset(18)
}
stackView.snp.makeConstraints { make in
make.height.equalTo(278)
make.horizontalEdges.equalToSuperview().inset(16)
make.bottom.equalTo(nextButton.snp.top).offset(-37)
}
nextButton.snp.makeConstraints { make in
make.height.equalTo(54)
make.horizontalEdges.equalToSuperview().inset(20)
make.bottom.equalToSuperview().inset(58)
}
}

private func setButtonAction() {
tenYearsButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
fiveYearsButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
threeYearsOverButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
threeYearsUnderButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
zeroButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
nextButton.addTarget(self, action: #selector(nextButtonTapped), for: .touchUpInside)
}

@objc private func buttonTapped(_ sender: UIButton) {
nextButton.setButtonState(isEnabled: true)
if selectedButton != sender {
if let previousButton = selectedButton {
previousButton.isSelected = false
previousButton.backgroundColor = .gray100
previousButton.setTitleColor(.gray500, for: .normal)
}
self.selectedButton = sender
if let currentButton = self.selectedButton {
currentButton.isSelected = true
currentButton.backgroundColor = .mainBlue
currentButton.setTitleColor(.gray100, for: .selected)
}
}
}

private func getExperienceYn() -> String {
return selectedButton == zeroButton ? "N" : "Y"
}

@objc private func nextButtonTapped() {
delegate?.didSelectExperience(getExperienceYn())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,37 @@
import UIKit

final class MatchingApplyPetWalkExperienceViewController: UIViewController {

private let matchingApplyPetWalkExperienceView = MatchingApplyPetWalkExperienceView()

override func viewDidLoad() {
super.viewDidLoad()

view.backgroundColor = .white
setUI()
}
private func addSubview() {
view.addSubview(matchingApplyPetWalkExperienceView)
}

private func setConstraints() {
matchingApplyPetWalkExperienceView.snp.makeConstraints { make in
make.horizontalEdges.bottom.equalToSuperview()
make.top.equalToSuperview().offset(156)
}
}

private func setUI() {
addSubview()
setConstraints()
addCustomNavigationBar(titleText: "", showLeftBackButton: true, showLeftCloseButton: false, showRightCloseButton: false, showRightRefreshButton: false)
addProgressBar(currentStep: 2, totalSteps: 7)
matchingApplyPetWalkExperienceView.delegate = self
}
}

extension MatchingApplyPetWalkExperienceViewController: MatchingApplyPetWalkExperienceViewDelegate {
func didTapNextButton(_ experience: Bool, _ breed: String) {
let nextVC = MatchingApplyFirstIntroductionViewController()
self.navigationController?.pushViewController(nextVC, animated: true)
}
}
Loading

0 comments on commit 5b64978

Please sign in to comment.