From efaab96d624bf913dda189770e21fe659d882741 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Tue, 2 Jul 2024 23:27:08 +0900 Subject: [PATCH 01/28] =?UTF-8?q?Feat:=20RecipeDetailViewModel=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Feed/RecipeDetailViewModel.swift | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/RecipeDetailViewModel.swift diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/RecipeDetailViewModel.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/RecipeDetailViewModel.swift new file mode 100644 index 0000000..98bcdf2 --- /dev/null +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/RecipeDetailViewModel.swift @@ -0,0 +1,26 @@ +// +// RecipeItemViewModel.swift +// HomeCafeRecipes +// +// Created by 김건호 on 6/13/24. +// + +import Foundation + +struct RecipeDetailViewModel { + let id: Int + let name: String + let description: String + let imageUrls: [URL] + let isLikedByCurrentUser: Bool + let createdAt: Date + + init(recipe: Recipe) { + self.id = recipe.id + self.name = recipe.name + self.description = recipe.description + self.imageUrls = recipe.imageUrls.compactMap { URL(string: $0) } + self.isLikedByCurrentUser = recipe.isLikedByCurrentUser + self.createdAt = recipe.createdAt + } +} From 27b024e1014a23602d3f3ac81a9f22d3557cb5e7 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Tue, 2 Jul 2024 23:27:29 +0900 Subject: [PATCH 02/28] =?UTF-8?q?Feat:=20RecipeDetailView=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Feed/View/RecipeDetailView.swift | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift new file mode 100644 index 0000000..a087847 --- /dev/null +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift @@ -0,0 +1,114 @@ +// +// RecipeDetailView.swift +// HomeCafeRecipes +// +// Created by 김건호 on 6/13/24. +// + +import UIKit +import Kingfisher + +final class RecipeDetailView: UIView { + + private let scrollView = UIScrollView() + private let pageControl = UIPageControl() + private let recipenameLabel = UILabel() + private let recipedescriptionLabel = UILabel() + private let photoIndexLabel = UILabel() + private var recipeimageUrls: [URL] = [] + + override init(frame: CGRect) { + super.init(frame: frame) + setupUI() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setupUI() { + backgroundColor = .white + addSubview(scrollView) + addSubview(pageControl) + addSubview(recipenameLabel) + addSubview(recipedescriptionLabel) + addSubview(photoIndexLabel) + + scrollView.translatesAutoresizingMaskIntoConstraints = false + pageControl.translatesAutoresizingMaskIntoConstraints = false + recipenameLabel.translatesAutoresizingMaskIntoConstraints = false + recipedescriptionLabel.translatesAutoresizingMaskIntoConstraints = false + photoIndexLabel.translatesAutoresizingMaskIntoConstraints = false + + scrollView.isPagingEnabled = true + scrollView.showsHorizontalScrollIndicator = false + scrollView.delegate = self + + NSLayoutConstraint.activate([ + scrollView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor), + scrollView.leadingAnchor.constraint(equalTo: leadingAnchor), + scrollView.trailingAnchor.constraint(equalTo: trailingAnchor), + scrollView.heightAnchor.constraint(equalToConstant: 200), + + pageControl.topAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 10), + pageControl.centerXAnchor.constraint(equalTo: centerXAnchor), + + photoIndexLabel.topAnchor.constraint(equalTo: pageControl.bottomAnchor, constant: 10), + photoIndexLabel.centerXAnchor.constraint(equalTo: centerXAnchor), + + recipenameLabel.topAnchor.constraint(equalTo: photoIndexLabel.bottomAnchor, constant: 20), + recipenameLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20), + recipenameLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20), + + recipedescriptionLabel.topAnchor.constraint(equalTo: recipenameLabel.bottomAnchor, constant: 20), + recipedescriptionLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20), + recipedescriptionLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20) + ]) + + recipenameLabel.font = .systemFont(ofSize: 24, weight: .bold) + recipenameLabel.numberOfLines = 0 + recipedescriptionLabel.font = .systemFont(ofSize: 16) + recipedescriptionLabel.numberOfLines = 0 + photoIndexLabel.font = .systemFont(ofSize: 16) + } + + func configure(with viewModel: RecipeDetailViewModel) { + recipenameLabel.text = viewModel.name + recipedescriptionLabel.text = viewModel.description + recipeimageUrls = viewModel.imageUrls + + setupScrollView() + pageControl.numberOfPages = recipeimageUrls.count + updatePhotoIndexLabel(currentPage: 0) + } + + private func setupScrollView() { + let imageViewWidth = UIScreen.main.bounds.width + + for (index, url) in recipeimageUrls.enumerated() { + let imageView = UIImageView() + imageView.kf.setImage(with: url) + imageView.contentMode = .scaleAspectFill + imageView.clipsToBounds = true + + let xPos = CGFloat(index) * imageViewWidth + imageView.frame = CGRect(x: xPos, y: 0, width: imageViewWidth, height: 200) + scrollView.addSubview(imageView) + } + + let contentWidth = imageViewWidth * CGFloat(recipeimageUrls.count) + scrollView.contentSize = CGSize(width: contentWidth, height: 200) + } + + private func updatePhotoIndexLabel(currentPage: Int) { + photoIndexLabel.text = "\(currentPage + 1) / \(recipeimageUrls.count)" + } +} + +extension RecipeDetailView: UIScrollViewDelegate { + func scrollViewDidScroll(_ scrollView: UIScrollView) { + let pageIndex = round(scrollView.contentOffset.x / UIScreen.main.bounds.width) + pageControl.currentPage = Int(pageIndex) + updatePhotoIndexLabel(currentPage: Int(pageIndex)) + } +} From c5666173f1c0f47129a69f73e8ba16dfd8ac1c9b Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Tue, 2 Jul 2024 23:27:44 +0900 Subject: [PATCH 03/28] =?UTF-8?q?Feat:=20RecipeDetailViewController=20?= =?UTF-8?q?=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/RecipeDetailViewController.swift | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift new file mode 100644 index 0000000..1d63d2a --- /dev/null +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift @@ -0,0 +1,84 @@ +// +// RecipeDetailViewController.swift +// HomeCafeRecipes +// +// Created by 김건호 on 6/14/24. +// + +import UIKit +import RxSwift + +final class RecipeDetailViewController: UIViewController { + + private let recipeDetailView = RecipeDetailView() + private let customNavigationBar = CustomNavigationBar() + private let interactor: RecipeDetailInteractor + private let disposeBag = DisposeBag() + private var recipeDetailViewModel: RecipeDetailViewModel? + + init(interactor: RecipeDetailInteractor) { + self.interactor = interactor + super.init(nibName: nil, bundle: nil) + self.interactor.setDelegate(self) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidLoad() { + super.viewDidLoad() + setupUI() + interactor.viewDidLoad() + } + + private func setupUI() { + view.backgroundColor = .white + view.addSubview(recipeDetailView) + view.addSubview(customNavigationBar) + + recipeDetailView.translatesAutoresizingMaskIntoConstraints = false + customNavigationBar.translatesAutoresizingMaskIntoConstraints = false + + NSLayoutConstraint.activate([ + customNavigationBar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), + customNavigationBar.leadingAnchor.constraint(equalTo: view.leadingAnchor), + customNavigationBar.trailingAnchor.constraint(equalTo: view.trailingAnchor), + customNavigationBar.heightAnchor.constraint(equalToConstant: 44), + + recipeDetailView.topAnchor.constraint(equalTo: customNavigationBar.bottomAnchor), + recipeDetailView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + recipeDetailView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + recipeDetailView.bottomAnchor.constraint(equalTo: view.bottomAnchor) + ]) + + customNavigationBar.backButton.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside) + } + + private func displayError(_ error: Error) { + let alert = UIAlertController(title: "해당 레시피를 로드하는데 실패했습니다.", message: error.localizedDescription, preferredStyle: .alert) + alert.addAction(UIAlertAction(title: "OK", style: .default)) + present(alert, animated: true) + } + + @objc private func backButtonTapped() { + navigationController?.popViewController(animated: true) + } +} + +// MARK: - RecipeDetailInteractorDelegate +extension RecipeDetailViewController: RecipeDetailInteractorDelegate { + func fetchedRecipe(result: Result) { + switch result { + case .success(let recipe): + let recipeItemViewModel = RecipeListMapper().mapToRecipeDetailViewModel(from: recipe) + DispatchQueue.main.async { + self.recipeDetailView.configure(with: recipeItemViewModel) + } + case .failure(let error): + DispatchQueue.main.async { + self.displayError(error) + } + } + } +} From 6f92e1ab8e504a819941e92de1150c4d4770506e Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Tue, 2 Jul 2024 23:28:20 +0900 Subject: [PATCH 04/28] =?UTF-8?q?Fix:=20=20mapToRecipeItemViewModel?= =?UTF-8?q?=EC=97=90=EC=84=9C=20mapToRecipeDetailViewModel=EB=A1=9C=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 --- .../Presentation/Mapper/RecipeListMapper.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Mapper/RecipeListMapper.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Mapper/RecipeListMapper.swift index 40b833b..df47d7e 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Mapper/RecipeListMapper.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Mapper/RecipeListMapper.swift @@ -12,7 +12,7 @@ struct RecipeListMapper { return recipes.map { RecipeListItemViewModel(recipe: $0) } } - func mapToRecipeItemViewModel(from recipe: Recipe) -> RecipeItemViewModel { - return RecipeItemViewModel(recipe: recipe) + func mapToRecipeDetailViewModel(from recipe: Recipe) -> RecipeDetailViewModel { + return RecipeDetailViewModel(recipe: recipe) } } From 80b6640b9ed810afe374ef6777101198ae90245a Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Tue, 2 Jul 2024 23:34:22 +0900 Subject: [PATCH 05/28] =?UTF-8?q?Feat:=20CustomNavigationBar=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/CustomNavigationBar.swift | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 HomeCafeRecipes/HomeCafeRecipes/Presentation/CustomNavigationBar.swift diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/CustomNavigationBar.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/CustomNavigationBar.swift new file mode 100644 index 0000000..067dbc7 --- /dev/null +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/CustomNavigationBar.swift @@ -0,0 +1,49 @@ +// +// CustomNavigationBar.swift +// HomeCafeRecipes +// +// Created by 김건호 on 6/22/24. +// + +import UIKit + +final class CustomNavigationBar: UIView { + + private let titleLabel = UILabel() + let backButton = UIButton(type: .system) + + override init(frame: CGRect) { + super.init(frame: frame) + setupUI() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setupUI() { + + backButton.setImage(UIImage(systemName: "chevron.backward"), for: .normal) + backButton.tintColor = .black + addSubview(backButton) + + titleLabel.font = UIFont.systemFont(ofSize: 18, weight: .bold) + titleLabel.textAlignment = .center + addSubview(titleLabel) + + backButton.translatesAutoresizingMaskIntoConstraints = false + titleLabel.translatesAutoresizingMaskIntoConstraints = false + + NSLayoutConstraint.activate([ + backButton.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16), + backButton.centerYAnchor.constraint(equalTo: centerYAnchor), + + titleLabel.centerXAnchor.constraint(equalTo: centerXAnchor), + titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor) + ]) + } + + func setTitle(_ title: String) { + titleLabel.text = title + } +} From 28213484278542042f180ed4dd5442e469fcb000 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Wed, 3 Jul 2024 12:13:35 +0900 Subject: [PATCH 06/28] =?UTF-8?q?Feat:=20DetailView=EC=97=90=20=EB=93=A4?= =?UTF-8?q?=EC=96=B4=EA=B0=88=20Fonts=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HomeCafeRecipes/HomeCafeRecipes/Resources/Fonts.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Resources/Fonts.swift b/HomeCafeRecipes/HomeCafeRecipes/Resources/Fonts.swift index 8cc5c31..5e6ed74 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Resources/Fonts.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Resources/Fonts.swift @@ -10,4 +10,6 @@ import UIKit struct Fonts { static let titleFont: UIFont = .systemFont(ofSize: 16, weight: .bold) static let bodyFont: UIFont = .systemFont(ofSize: 14, weight: .regular) + static let DetailtitleFont: UIFont = .systemFont(ofSize: 24, weight: .bold) + static let DetailBodyFont: UIFont = .systemFont(ofSize: 16, weight: .regular) } From 1f1c396c29cf093ba3a209a553cd80d43c2b428b Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Wed, 3 Jul 2024 12:13:54 +0900 Subject: [PATCH 07/28] =?UTF-8?q?Fix:=20DeatilView=EC=97=90=20=EB=93=A4?= =?UTF-8?q?=EC=96=B4=EA=B0=88=20Fonts=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/Feed/View/RecipeDetailView.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift index a087847..627572d 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift @@ -65,11 +65,11 @@ final class RecipeDetailView: UIView { recipedescriptionLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20) ]) - recipenameLabel.font = .systemFont(ofSize: 24, weight: .bold) + recipenameLabel.font = Fonts.DetailtitleFont recipenameLabel.numberOfLines = 0 - recipedescriptionLabel.font = .systemFont(ofSize: 16) + recipedescriptionLabel.font = Fonts.DetailBodyFont recipedescriptionLabel.numberOfLines = 0 - photoIndexLabel.font = .systemFont(ofSize: 16) + photoIndexLabel.font = Fonts.DetailBodyFont } func configure(with viewModel: RecipeDetailViewModel) { From 9881443390c3837bc4acb38d47feaee244b17756 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Thu, 4 Jul 2024 15:15:50 +0900 Subject: [PATCH 08/28] =?UTF-8?q?Fix:=20ViewModel=20=EB=84=A4=EC=9D=B4?= =?UTF-8?q?=EB=B0=8D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Feed/RecipeDetailViewModel.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/RecipeDetailViewModel.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/RecipeDetailViewModel.swift index 98bcdf2..998ed92 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/RecipeDetailViewModel.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/RecipeDetailViewModel.swift @@ -9,18 +9,18 @@ import Foundation struct RecipeDetailViewModel { let id: Int - let name: String - let description: String - let imageUrls: [URL] - let isLikedByCurrentUser: Bool + let RecipeName: String + let RecipeDescription: String + let RecipeImageUrls: [URL] + let isLiked: Bool let createdAt: Date init(recipe: Recipe) { self.id = recipe.id - self.name = recipe.name - self.description = recipe.description - self.imageUrls = recipe.imageUrls.compactMap { URL(string: $0) } - self.isLikedByCurrentUser = recipe.isLikedByCurrentUser + self.RecipeName = recipe.name + self.RecipeDescription = recipe.description + self.RecipeImageUrls = recipe.imageUrls.compactMap { URL(string: $0) } + self.isLiked = recipe.isLikedByCurrentUser self.createdAt = recipe.createdAt } } From fa15e8fe442d5860a953160437d0cdc74f8cfcd7 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Thu, 4 Jul 2024 15:16:54 +0900 Subject: [PATCH 09/28] =?UTF-8?q?Fix:=20=EB=B3=80=EA=B2=BD=EB=90=9C=20?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/Feed/View/RecipeDetailView.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift index 627572d..61d3a39 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift @@ -73,9 +73,9 @@ final class RecipeDetailView: UIView { } func configure(with viewModel: RecipeDetailViewModel) { - recipenameLabel.text = viewModel.name - recipedescriptionLabel.text = viewModel.description - recipeimageUrls = viewModel.imageUrls + recipenameLabel.text = viewModel.RecipeName + recipedescriptionLabel.text = viewModel.RecipeDescription + recipeimageUrls = viewModel.RecipeImageUrls setupScrollView() pageControl.numberOfPages = recipeimageUrls.count From d508f7e80a92cd29d5d3433a5459e95462166401 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Thu, 4 Jul 2024 15:18:23 +0900 Subject: [PATCH 10/28] =?UTF-8?q?Fix:=20=EC=8D=A8=EB=93=9C=ED=8C=8C?= =?UTF-8?q?=ED=8B=B0=EC=99=80=20=ED=8D=BC=EC=8A=A4=ED=8A=B8=ED=8C=8C?= =?UTF-8?q?=ED=8B=B0=20=EC=82=AC=EC=9D=B4=20=ED=95=9C=EC=A4=84=20=EB=9D=84?= =?UTF-8?q?=EC=9A=B0=EA=B8=B0=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/Feed/View/RecipeDetailView.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift index 61d3a39..da40766 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift @@ -6,6 +6,7 @@ // import UIKit + import Kingfisher final class RecipeDetailView: UIView { From 092afac7eaa4f27ad5f90c581fbfa92200543ff7 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Thu, 4 Jul 2024 15:20:37 +0900 Subject: [PATCH 11/28] =?UTF-8?q?Fix:=20recipeNameLabel=EB=A1=9C=20?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Feed/View/RecipeDetailView.swift | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift index da40766..0330bba 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift @@ -13,7 +13,7 @@ final class RecipeDetailView: UIView { private let scrollView = UIScrollView() private let pageControl = UIPageControl() - private let recipenameLabel = UILabel() + private let recipeNameLabel = UILabel() private let recipedescriptionLabel = UILabel() private let photoIndexLabel = UILabel() private var recipeimageUrls: [URL] = [] @@ -31,13 +31,13 @@ final class RecipeDetailView: UIView { backgroundColor = .white addSubview(scrollView) addSubview(pageControl) - addSubview(recipenameLabel) + addSubview(recipeNameLabel) addSubview(recipedescriptionLabel) addSubview(photoIndexLabel) scrollView.translatesAutoresizingMaskIntoConstraints = false pageControl.translatesAutoresizingMaskIntoConstraints = false - recipenameLabel.translatesAutoresizingMaskIntoConstraints = false + recipeNameLabel.translatesAutoresizingMaskIntoConstraints = false recipedescriptionLabel.translatesAutoresizingMaskIntoConstraints = false photoIndexLabel.translatesAutoresizingMaskIntoConstraints = false @@ -57,24 +57,24 @@ final class RecipeDetailView: UIView { photoIndexLabel.topAnchor.constraint(equalTo: pageControl.bottomAnchor, constant: 10), photoIndexLabel.centerXAnchor.constraint(equalTo: centerXAnchor), - recipenameLabel.topAnchor.constraint(equalTo: photoIndexLabel.bottomAnchor, constant: 20), - recipenameLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20), - recipenameLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20), + recipeNameLabel.topAnchor.constraint(equalTo: photoIndexLabel.bottomAnchor, constant: 20), + recipeNameLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20), + recipeNameLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20), - recipedescriptionLabel.topAnchor.constraint(equalTo: recipenameLabel.bottomAnchor, constant: 20), + recipedescriptionLabel.topAnchor.constraint(equalTo: recipeNameLabel.bottomAnchor, constant: 20), recipedescriptionLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20), recipedescriptionLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20) ]) - recipenameLabel.font = Fonts.DetailtitleFont - recipenameLabel.numberOfLines = 0 + recipeNameLabel.font = Fonts.DetailtitleFont + recipeNameLabel.numberOfLines = 0 recipedescriptionLabel.font = Fonts.DetailBodyFont recipedescriptionLabel.numberOfLines = 0 photoIndexLabel.font = Fonts.DetailBodyFont } func configure(with viewModel: RecipeDetailViewModel) { - recipenameLabel.text = viewModel.RecipeName + recipeNameLabel.text = viewModel.RecipeName recipedescriptionLabel.text = viewModel.RecipeDescription recipeimageUrls = viewModel.RecipeImageUrls From 1b83f41a156f9c3ac5a4d5f8b0bbb38471394e87 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Thu, 4 Jul 2024 15:21:21 +0900 Subject: [PATCH 12/28] =?UTF-8?q?Fix:=20recipeDescriptionLabel=EB=A1=9C=20?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Feed/View/RecipeDetailView.swift | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift index 0330bba..c201914 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift @@ -14,7 +14,7 @@ final class RecipeDetailView: UIView { private let scrollView = UIScrollView() private let pageControl = UIPageControl() private let recipeNameLabel = UILabel() - private let recipedescriptionLabel = UILabel() + private let recipeDescriptionLabel = UILabel() private let photoIndexLabel = UILabel() private var recipeimageUrls: [URL] = [] @@ -32,13 +32,13 @@ final class RecipeDetailView: UIView { addSubview(scrollView) addSubview(pageControl) addSubview(recipeNameLabel) - addSubview(recipedescriptionLabel) + addSubview(recipeDescriptionLabel) addSubview(photoIndexLabel) scrollView.translatesAutoresizingMaskIntoConstraints = false pageControl.translatesAutoresizingMaskIntoConstraints = false recipeNameLabel.translatesAutoresizingMaskIntoConstraints = false - recipedescriptionLabel.translatesAutoresizingMaskIntoConstraints = false + recipeDescriptionLabel.translatesAutoresizingMaskIntoConstraints = false photoIndexLabel.translatesAutoresizingMaskIntoConstraints = false scrollView.isPagingEnabled = true @@ -61,21 +61,21 @@ final class RecipeDetailView: UIView { recipeNameLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20), recipeNameLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20), - recipedescriptionLabel.topAnchor.constraint(equalTo: recipeNameLabel.bottomAnchor, constant: 20), - recipedescriptionLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20), - recipedescriptionLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20) + recipeDescriptionLabel.topAnchor.constraint(equalTo: recipeNameLabel.bottomAnchor, constant: 20), + recipeDescriptionLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20), + recipeDescriptionLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20) ]) recipeNameLabel.font = Fonts.DetailtitleFont recipeNameLabel.numberOfLines = 0 - recipedescriptionLabel.font = Fonts.DetailBodyFont - recipedescriptionLabel.numberOfLines = 0 + recipeDescriptionLabel.font = Fonts.DetailBodyFont + recipeDescriptionLabel.numberOfLines = 0 photoIndexLabel.font = Fonts.DetailBodyFont } func configure(with viewModel: RecipeDetailViewModel) { recipeNameLabel.text = viewModel.RecipeName - recipedescriptionLabel.text = viewModel.RecipeDescription + recipeDescriptionLabel.text = viewModel.RecipeDescription recipeimageUrls = viewModel.RecipeImageUrls setupScrollView() From a78dd5357574d2d7491be72722cf9f7b3abbd56e Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Thu, 4 Jul 2024 15:21:59 +0900 Subject: [PATCH 13/28] =?UTF-8?q?Fix:=20recipeImageUrls=EB=A1=9C=20?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/Feed/View/RecipeDetailView.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift index c201914..e5e5886 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift @@ -16,7 +16,7 @@ final class RecipeDetailView: UIView { private let recipeNameLabel = UILabel() private let recipeDescriptionLabel = UILabel() private let photoIndexLabel = UILabel() - private var recipeimageUrls: [URL] = [] + private var recipeImageUrls: [URL] = [] override init(frame: CGRect) { super.init(frame: frame) @@ -76,17 +76,17 @@ final class RecipeDetailView: UIView { func configure(with viewModel: RecipeDetailViewModel) { recipeNameLabel.text = viewModel.RecipeName recipeDescriptionLabel.text = viewModel.RecipeDescription - recipeimageUrls = viewModel.RecipeImageUrls + recipeImageUrls = viewModel.RecipeImageUrls setupScrollView() - pageControl.numberOfPages = recipeimageUrls.count + pageControl.numberOfPages = recipeImageUrls.count updatePhotoIndexLabel(currentPage: 0) } private func setupScrollView() { let imageViewWidth = UIScreen.main.bounds.width - for (index, url) in recipeimageUrls.enumerated() { + for (index, url) in recipeImageUrls.enumerated() { let imageView = UIImageView() imageView.kf.setImage(with: url) imageView.contentMode = .scaleAspectFill @@ -97,12 +97,12 @@ final class RecipeDetailView: UIView { scrollView.addSubview(imageView) } - let contentWidth = imageViewWidth * CGFloat(recipeimageUrls.count) + let contentWidth = imageViewWidth * CGFloat(recipeImageUrls.count) scrollView.contentSize = CGSize(width: contentWidth, height: 200) } private func updatePhotoIndexLabel(currentPage: Int) { - photoIndexLabel.text = "\(currentPage + 1) / \(recipeimageUrls.count)" + photoIndexLabel.text = "\(currentPage + 1) / \(recipeImageUrls.count)" } } From 18901d0f9640ac43accf45340325eee8a757d352 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Thu, 4 Jul 2024 20:29:51 +0900 Subject: [PATCH 14/28] =?UTF-8?q?Fix:=20recipeimageUrls=EB=A5=BC=20?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A1=A4=EB=B7=B0=EB=A5=BC=20=EA=B5=AC?= =?UTF-8?q?=EC=84=B1=ED=95=98=EB=8A=94=EB=8D=B0=20=EB=B0=94=EB=A1=9C=20?= =?UTF-8?q?=EC=A0=84=EB=8B=AC=ED=95=B4=EC=84=9C=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/Feed/View/RecipeDetailView.swift | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift index e5e5886..eef3a99 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift @@ -16,7 +16,6 @@ final class RecipeDetailView: UIView { private let recipeNameLabel = UILabel() private let recipeDescriptionLabel = UILabel() private let photoIndexLabel = UILabel() - private var recipeImageUrls: [URL] = [] override init(frame: CGRect) { super.init(frame: frame) @@ -75,15 +74,13 @@ final class RecipeDetailView: UIView { func configure(with viewModel: RecipeDetailViewModel) { recipeNameLabel.text = viewModel.RecipeName - recipeDescriptionLabel.text = viewModel.RecipeDescription - recipeImageUrls = viewModel.RecipeImageUrls - - setupScrollView() - pageControl.numberOfPages = recipeImageUrls.count + recipeDescriptionLabel.text = viewModel.RecipeDescription + setupScrollView(with: viewModel.RecipeImageUrls) + pageControl.numberOfPages = viewModel.RecipeImageUrls.count updatePhotoIndexLabel(currentPage: 0) } - private func setupScrollView() { + private func setupScrollView(with recipeImageUrls: [URL]) { let imageViewWidth = UIScreen.main.bounds.width for (index, url) in recipeImageUrls.enumerated() { @@ -102,7 +99,7 @@ final class RecipeDetailView: UIView { } private func updatePhotoIndexLabel(currentPage: Int) { - photoIndexLabel.text = "\(currentPage + 1) / \(recipeImageUrls.count)" + photoIndexLabel.text = "\(currentPage + 1) / \(pageControl.numberOfPages)" } } From 75ce3f8217f3672bca237c23d21a199dbf7b8ee3 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Thu, 4 Jul 2024 20:50:35 +0900 Subject: [PATCH 15/28] =?UTF-8?q?Fix:=20for=20-=20in=20=EB=B0=98=EB=B3=B5?= =?UTF-8?q?=EB=AC=B8=EC=97=90=EC=84=9C=20forEach=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/Feed/View/RecipeDetailView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift index eef3a99..a6e551f 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift @@ -83,7 +83,7 @@ final class RecipeDetailView: UIView { private func setupScrollView(with recipeImageUrls: [URL]) { let imageViewWidth = UIScreen.main.bounds.width - for (index, url) in recipeImageUrls.enumerated() { + recipeImageUrls.enumerated().forEach { index, url in let imageView = UIImageView() imageView.kf.setImage(with: url) imageView.contentMode = .scaleAspectFill From efc1c64fae76b16a89706dd6f1f39ec6416ea7de Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Thu, 4 Jul 2024 21:23:50 +0900 Subject: [PATCH 16/28] =?UTF-8?q?Fix:=20imagesAdded=EB=A5=BC=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EC=97=AC=20=EC=9D=B4=EB=AF=B8=EC=A7=80?= =?UTF-8?q?=EB=B7=B0=20=EC=A4=91=EB=B3=B5=20=EC=B6=94=EA=B0=80=20=EB=B0=A9?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/Feed/View/RecipeDetailView.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift index a6e551f..08c0659 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift @@ -16,6 +16,7 @@ final class RecipeDetailView: UIView { private let recipeNameLabel = UILabel() private let recipeDescriptionLabel = UILabel() private let photoIndexLabel = UILabel() + private var imagesAdded = false override init(frame: CGRect) { super.init(frame: frame) @@ -81,6 +82,7 @@ final class RecipeDetailView: UIView { } private func setupScrollView(with recipeImageUrls: [URL]) { + guard !imagesAdded else { return } let imageViewWidth = UIScreen.main.bounds.width recipeImageUrls.enumerated().forEach { index, url in @@ -92,6 +94,7 @@ final class RecipeDetailView: UIView { let xPos = CGFloat(index) * imageViewWidth imageView.frame = CGRect(x: xPos, y: 0, width: imageViewWidth, height: 200) scrollView.addSubview(imageView) + imagesAdded = true } let contentWidth = imageViewWidth * CGFloat(recipeImageUrls.count) From 4830cf58cc4cc41be850156b4f58da9472159bfe Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Thu, 4 Jul 2024 22:32:15 +0900 Subject: [PATCH 17/28] =?UTF-8?q?Fix:=20clipsToBounds=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/Feed/View/RecipeDetailView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift index 08c0659..60a61e7 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift @@ -89,7 +89,7 @@ final class RecipeDetailView: UIView { let imageView = UIImageView() imageView.kf.setImage(with: url) imageView.contentMode = .scaleAspectFill - imageView.clipsToBounds = true + let xPos = CGFloat(index) * imageViewWidth imageView.frame = CGRect(x: xPos, y: 0, width: imageViewWidth, height: 200) From 0832b39b56525d15b68adaba086074e89f1f3572 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Thu, 4 Jul 2024 22:33:12 +0900 Subject: [PATCH 18/28] =?UTF-8?q?Fix:=20setupUI=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=EB=A5=BC=20setupLayout,setupScrollView,setupPageContr?= =?UTF-8?q?ol,setupLabels=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Feed/View/RecipeDetailView.swift | 48 ++++++++++++------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift index 60a61e7..8117496 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift @@ -21,6 +21,7 @@ final class RecipeDetailView: UIView { override init(frame: CGRect) { super.init(frame: frame) setupUI() + setupLayout() } required init?(coder: NSCoder) { @@ -29,22 +30,12 @@ final class RecipeDetailView: UIView { private func setupUI() { backgroundColor = .white - addSubview(scrollView) - addSubview(pageControl) - addSubview(recipeNameLabel) - addSubview(recipeDescriptionLabel) - addSubview(photoIndexLabel) - - scrollView.translatesAutoresizingMaskIntoConstraints = false - pageControl.translatesAutoresizingMaskIntoConstraints = false - recipeNameLabel.translatesAutoresizingMaskIntoConstraints = false - recipeDescriptionLabel.translatesAutoresizingMaskIntoConstraints = false - photoIndexLabel.translatesAutoresizingMaskIntoConstraints = false - - scrollView.isPagingEnabled = true - scrollView.showsHorizontalScrollIndicator = false - scrollView.delegate = self + setupScrollView() + setupPageControl() + setupLabels() + } + private func setupLayout() { NSLayoutConstraint.activate([ scrollView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor), scrollView.leadingAnchor.constraint(equalTo: leadingAnchor), @@ -65,6 +56,29 @@ final class RecipeDetailView: UIView { recipeDescriptionLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20), recipeDescriptionLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20) ]) + } + + private func setupScrollView() { + addSubview(scrollView) + scrollView.translatesAutoresizingMaskIntoConstraints = false + scrollView.isPagingEnabled = true + scrollView.showsHorizontalScrollIndicator = false + scrollView.delegate = self + } + + private func setupPageControl() { + addSubview(pageControl) + pageControl.translatesAutoresizingMaskIntoConstraints = false + } + + private func setupLabels() { + addSubview(recipeNameLabel) + addSubview(recipeDescriptionLabel) + addSubview(photoIndexLabel) + + recipeNameLabel.translatesAutoresizingMaskIntoConstraints = false + recipeDescriptionLabel.translatesAutoresizingMaskIntoConstraints = false + photoIndexLabel.translatesAutoresizingMaskIntoConstraints = false recipeNameLabel.font = Fonts.DetailtitleFont recipeNameLabel.numberOfLines = 0 @@ -76,12 +90,12 @@ final class RecipeDetailView: UIView { func configure(with viewModel: RecipeDetailViewModel) { recipeNameLabel.text = viewModel.RecipeName recipeDescriptionLabel.text = viewModel.RecipeDescription - setupScrollView(with: viewModel.RecipeImageUrls) + setupScrollViewContent(with: viewModel.RecipeImageUrls) pageControl.numberOfPages = viewModel.RecipeImageUrls.count updatePhotoIndexLabel(currentPage: 0) } - private func setupScrollView(with recipeImageUrls: [URL]) { + private func setupScrollViewContent(with recipeImageUrls: [URL]) { guard !imagesAdded else { return } let imageViewWidth = UIScreen.main.bounds.width From 60fa4e2f463198b1b2acf53f8b12d4e3da79b6ed Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Thu, 4 Jul 2024 23:30:07 +0900 Subject: [PATCH 19/28] =?UTF-8?q?Fix:=20contentView=EB=A1=9C=20=EB=84=A4?= =?UTF-8?q?=EC=9D=B4=EB=B0=8D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Feed/View/RecipeDetailViewController.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift index 1d63d2a..cd9fd4a 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift @@ -10,7 +10,7 @@ import RxSwift final class RecipeDetailViewController: UIViewController { - private let recipeDetailView = RecipeDetailView() + private let contentView = RecipeDetailView() private let customNavigationBar = CustomNavigationBar() private let interactor: RecipeDetailInteractor private let disposeBag = DisposeBag() @@ -34,10 +34,10 @@ final class RecipeDetailViewController: UIViewController { private func setupUI() { view.backgroundColor = .white - view.addSubview(recipeDetailView) + view.addSubview(contentView) view.addSubview(customNavigationBar) - recipeDetailView.translatesAutoresizingMaskIntoConstraints = false + contentView.translatesAutoresizingMaskIntoConstraints = false customNavigationBar.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ @@ -46,10 +46,10 @@ final class RecipeDetailViewController: UIViewController { customNavigationBar.trailingAnchor.constraint(equalTo: view.trailingAnchor), customNavigationBar.heightAnchor.constraint(equalToConstant: 44), - recipeDetailView.topAnchor.constraint(equalTo: customNavigationBar.bottomAnchor), - recipeDetailView.leadingAnchor.constraint(equalTo: view.leadingAnchor), - recipeDetailView.trailingAnchor.constraint(equalTo: view.trailingAnchor), - recipeDetailView.bottomAnchor.constraint(equalTo: view.bottomAnchor) + contentView.topAnchor.constraint(equalTo: customNavigationBar.bottomAnchor), + contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + contentView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + contentView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) customNavigationBar.backButton.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside) @@ -73,7 +73,7 @@ extension RecipeDetailViewController: RecipeDetailInteractorDelegate { case .success(let recipe): let recipeItemViewModel = RecipeListMapper().mapToRecipeDetailViewModel(from: recipe) DispatchQueue.main.async { - self.recipeDetailView.configure(with: recipeItemViewModel) + self.contentView.configure(with: recipeItemViewModel) } case .failure(let error): DispatchQueue.main.async { From 61a0df92675386dbf58748c0134715f05f8f3398 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Thu, 4 Jul 2024 23:30:57 +0900 Subject: [PATCH 20/28] =?UTF-8?q?Fix:=20=EC=8D=A8=EB=93=9C=ED=8C=8C?= =?UTF-8?q?=ED=8B=B0=20=EC=82=AC=EC=9D=B4=20=EA=B0=9C=ED=96=89=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 --- .../Presentation/Feed/View/RecipeDetailViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift index cd9fd4a..a638232 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift @@ -6,6 +6,7 @@ // import UIKit + import RxSwift final class RecipeDetailViewController: UIViewController { From 690680d78dfc1fc1d54a0a2ec9531b74962b2227 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Fri, 5 Jul 2024 13:28:05 +0900 Subject: [PATCH 21/28] =?UTF-8?q?Fix:=20RecipeDetailViewController?= =?UTF-8?q?=EC=97=90=20view=20=3D=20contentView=20=EC=B2=98=EB=A6=AC,=20cu?= =?UTF-8?q?stomNavigationBar=EB=A5=BC=20RecipeDetailView=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Feed/View/RecipeDetailView.swift | 57 ++++++++++++------- .../View/RecipeDetailViewController.swift | 29 ++-------- 2 files changed, 40 insertions(+), 46 deletions(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift index 8117496..1fb5bd8 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift @@ -11,6 +11,7 @@ import Kingfisher final class RecipeDetailView: UIView { + let customNavigationBar = CustomNavigationBar() private let scrollView = UIScrollView() private let pageControl = UIPageControl() private let recipeNameLabel = UILabel() @@ -30,34 +31,17 @@ final class RecipeDetailView: UIView { private func setupUI() { backgroundColor = .white + setupNavigationBar() setupScrollView() setupPageControl() setupLabels() } - private func setupLayout() { - NSLayoutConstraint.activate([ - scrollView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor), - scrollView.leadingAnchor.constraint(equalTo: leadingAnchor), - scrollView.trailingAnchor.constraint(equalTo: trailingAnchor), - scrollView.heightAnchor.constraint(equalToConstant: 200), - - pageControl.topAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 10), - pageControl.centerXAnchor.constraint(equalTo: centerXAnchor), - - photoIndexLabel.topAnchor.constraint(equalTo: pageControl.bottomAnchor, constant: 10), - photoIndexLabel.centerXAnchor.constraint(equalTo: centerXAnchor), - - recipeNameLabel.topAnchor.constraint(equalTo: photoIndexLabel.bottomAnchor, constant: 20), - recipeNameLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20), - recipeNameLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20), - - recipeDescriptionLabel.topAnchor.constraint(equalTo: recipeNameLabel.bottomAnchor, constant: 20), - recipeDescriptionLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20), - recipeDescriptionLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20) - ]) + private func setupNavigationBar() { + addSubview(customNavigationBar) + customNavigationBar.translatesAutoresizingMaskIntoConstraints = false } - + private func setupScrollView() { addSubview(scrollView) scrollView.translatesAutoresizingMaskIntoConstraints = false @@ -87,6 +71,35 @@ final class RecipeDetailView: UIView { photoIndexLabel.font = Fonts.DetailBodyFont } + private func setupLayout() { + NSLayoutConstraint.activate([ + customNavigationBar.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor), + customNavigationBar.leadingAnchor.constraint(equalTo: leadingAnchor), + customNavigationBar.trailingAnchor.constraint(equalTo: trailingAnchor), + customNavigationBar.heightAnchor.constraint(equalToConstant: 44), + + scrollView.topAnchor.constraint(equalTo: customNavigationBar.bottomAnchor, constant: 10), + scrollView.leadingAnchor.constraint(equalTo: leadingAnchor), + scrollView.trailingAnchor.constraint(equalTo: trailingAnchor), + scrollView.heightAnchor.constraint(equalToConstant: 200), + + pageControl.topAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 10), + pageControl.centerXAnchor.constraint(equalTo: centerXAnchor), + + photoIndexLabel.topAnchor.constraint(equalTo: pageControl.bottomAnchor, constant: 10), + photoIndexLabel.centerXAnchor.constraint(equalTo: centerXAnchor), + + recipeNameLabel.topAnchor.constraint(equalTo: photoIndexLabel.bottomAnchor, constant: 20), + recipeNameLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20), + recipeNameLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20), + + recipeDescriptionLabel.topAnchor.constraint(equalTo: recipeNameLabel.bottomAnchor, constant: 20), + recipeDescriptionLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20), + recipeDescriptionLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20) + ]) + } + + func configure(with viewModel: RecipeDetailViewModel) { recipeNameLabel.text = viewModel.RecipeName recipeDescriptionLabel.text = viewModel.RecipeDescription diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift index a638232..804610f 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift @@ -27,35 +27,16 @@ final class RecipeDetailViewController: UIViewController { fatalError("init(coder:) has not been implemented") } + override func loadView() { + view = contentView + } + override func viewDidLoad() { super.viewDidLoad() - setupUI() interactor.viewDidLoad() + contentView.customNavigationBar.backButton.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside) } - - private func setupUI() { - view.backgroundColor = .white - view.addSubview(contentView) - view.addSubview(customNavigationBar) - - contentView.translatesAutoresizingMaskIntoConstraints = false - customNavigationBar.translatesAutoresizingMaskIntoConstraints = false - - NSLayoutConstraint.activate([ - customNavigationBar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), - customNavigationBar.leadingAnchor.constraint(equalTo: view.leadingAnchor), - customNavigationBar.trailingAnchor.constraint(equalTo: view.trailingAnchor), - customNavigationBar.heightAnchor.constraint(equalToConstant: 44), - contentView.topAnchor.constraint(equalTo: customNavigationBar.bottomAnchor), - contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor), - contentView.trailingAnchor.constraint(equalTo: view.trailingAnchor), - contentView.bottomAnchor.constraint(equalTo: view.bottomAnchor) - ]) - - customNavigationBar.backButton.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside) - } - private func displayError(_ error: Error) { let alert = UIAlertController(title: "해당 레시피를 로드하는데 실패했습니다.", message: error.localizedDescription, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default)) From beca64ca834f0b9bc8c7a0d9a45b0c302438f271 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Fri, 5 Jul 2024 13:29:37 +0900 Subject: [PATCH 22/28] =?UTF-8?q?Fix:=20mark=20=EC=A3=BC=EC=84=9D=20?= =?UTF-8?q?=ED=95=9C=20=EC=A4=84=20=EA=B0=9C=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/Feed/View/RecipeDetailViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift index 804610f..f4d487c 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift @@ -49,6 +49,7 @@ final class RecipeDetailViewController: UIViewController { } // MARK: - RecipeDetailInteractorDelegate + extension RecipeDetailViewController: RecipeDetailInteractorDelegate { func fetchedRecipe(result: Result) { switch result { From 1c0bb265c3a9453295504a8098c066d5c78bac98 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Fri, 5 Jul 2024 13:34:24 +0900 Subject: [PATCH 23/28] =?UTF-8?q?Fix:=20mapper=20=EC=9D=B8=EC=8A=A4?= =?UTF-8?q?=ED=84=B4=EC=8A=A4=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/Feed/View/RecipeDetailViewController.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift index f4d487c..81df52f 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift @@ -16,6 +16,7 @@ final class RecipeDetailViewController: UIViewController { private let interactor: RecipeDetailInteractor private let disposeBag = DisposeBag() private var recipeDetailViewModel: RecipeDetailViewModel? + private let recipeListMapper = RecipeListMapper() init(interactor: RecipeDetailInteractor) { self.interactor = interactor @@ -54,7 +55,7 @@ extension RecipeDetailViewController: RecipeDetailInteractorDelegate { func fetchedRecipe(result: Result) { switch result { case .success(let recipe): - let recipeItemViewModel = RecipeListMapper().mapToRecipeDetailViewModel(from: recipe) + let recipeItemViewModel = recipeListMapper.mapToRecipeDetailViewModel(from: recipe) DispatchQueue.main.async { self.contentView.configure(with: recipeItemViewModel) } From e3b3ad95a40e71c87c26b9e731e698bcdb9999ea Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Fri, 5 Jul 2024 13:35:01 +0900 Subject: [PATCH 24/28] =?UTF-8?q?Fix:=20DetailTitleFont=EB=A1=9C=20?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HomeCafeRecipes/HomeCafeRecipes/Resources/Fonts.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Resources/Fonts.swift b/HomeCafeRecipes/HomeCafeRecipes/Resources/Fonts.swift index 5e6ed74..9ee14f9 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Resources/Fonts.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Resources/Fonts.swift @@ -10,6 +10,6 @@ import UIKit struct Fonts { static let titleFont: UIFont = .systemFont(ofSize: 16, weight: .bold) static let bodyFont: UIFont = .systemFont(ofSize: 14, weight: .regular) - static let DetailtitleFont: UIFont = .systemFont(ofSize: 24, weight: .bold) + static let DetailTitleFont: UIFont = .systemFont(ofSize: 24, weight: .bold) static let DetailBodyFont: UIFont = .systemFont(ofSize: 16, weight: .regular) } From a82aabdee7015f38c087a9c67946bde67be79c74 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Fri, 5 Jul 2024 13:38:21 +0900 Subject: [PATCH 25/28] =?UTF-8?q?Fix:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EB=B9=84=EB=8F=99=EA=B8=B0=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/Feed/View/RecipeDetailViewController.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift index 81df52f..c6ec16d 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift @@ -60,9 +60,7 @@ extension RecipeDetailViewController: RecipeDetailInteractorDelegate { self.contentView.configure(with: recipeItemViewModel) } case .failure(let error): - DispatchQueue.main.async { - self.displayError(error) - } + self.displayError(error) } } } From ca4c88a5df64322dcf241684e6e08c655807fb57 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Fri, 5 Jul 2024 13:39:49 +0900 Subject: [PATCH 26/28] =?UTF-8?q?Add:=20project.pbxproj=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 --- .../HomeCafeRecipes.xcodeproj/project.pbxproj | 140 +++++++++++++----- 1 file changed, 104 insertions(+), 36 deletions(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes.xcodeproj/project.pbxproj b/HomeCafeRecipes/HomeCafeRecipes.xcodeproj/project.pbxproj index b1eecef..b781e52 100644 --- a/HomeCafeRecipes/HomeCafeRecipes.xcodeproj/project.pbxproj +++ b/HomeCafeRecipes/HomeCafeRecipes.xcodeproj/project.pbxproj @@ -9,15 +9,12 @@ /* Begin PBXBuildFile section */ 1D1283A22C15E94300C5A870 /* Recipe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D1283A12C15E94300C5A870 /* Recipe.swift */; }; 1D1283A42C15EA8100C5A870 /* RecipeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D1283A32C15EA8100C5A870 /* RecipeType.swift */; }; - 1D1283A62C15EAA600C5A870 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D1283A52C15EAA600C5A870 /* User.swift */; }; - 1D1283A82C15EABB00C5A870 /* Comment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D1283A72C15EABB00C5A870 /* Comment.swift */; }; 1D1283AA2C15EBCF00C5A870 /* SearchFeedUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D1283A92C15EBCF00C5A870 /* SearchFeedUseCase.swift */; }; 1D1283AC2C15EBE600C5A870 /* FetchFeedListUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D1283AB2C15EBE600C5A870 /* FetchFeedListUseCase.swift */; }; 1D1283AF2C1697DB00C5A870 /* RxCocoa in Frameworks */ = {isa = PBXBuildFile; productRef = 1D1283AE2C1697DB00C5A870 /* RxCocoa */; }; 1D1283B12C1697DB00C5A870 /* RxSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 1D1283B02C1697DB00C5A870 /* RxSwift */; }; 1D1283B42C16983900C5A870 /* RxSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 1D1283B32C16983900C5A870 /* RxSwift */; }; 1D1283B62C16984E00C5A870 /* RxCocoa in Frameworks */ = {isa = PBXBuildFile; productRef = 1D1283B52C16984E00C5A870 /* RxCocoa */; }; - 1D1283C82C16CE7C00C5A870 /* DateFormatter+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D1283C72C16CE7C00C5A870 /* DateFormatter+Extensions.swift */; }; 1D1283CA2C16D9C600C5A870 /* RecipeFetchService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D1283C92C16D9C600C5A870 /* RecipeFetchService.swift */; }; 1D2C16E62BE532B700C04508 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D2C16E52BE532B700C04508 /* AppDelegate.swift */; }; 1D2C16EA2BE532B700C04508 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D2C16E92BE532B700C04508 /* ViewController.swift */; }; @@ -28,14 +25,28 @@ 1D4741D22C1B4F8D009381CE /* RecipeDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D4741CD2C1B4F8D009381CE /* RecipeDTO.swift */; }; 1D4741D32C1B4F8D009381CE /* RecipePageDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D4741CE2C1B4F8D009381CE /* RecipePageDTO.swift */; }; 1D4741D42C1B4F8D009381CE /* NetworkResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D4741CF2C1B4F8D009381CE /* NetworkResponseDTO.swift */; }; - 1D4741D52C1B4F8D009381CE /* UserDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D4741D02C1B4F8D009381CE /* UserDTO.swift */; }; - 1DDFFD812C1C096A0083B077 /* RecipeMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDFFD802C1C096A0083B077 /* RecipeMapper.swift */; }; + 1DDE911D2C36717B0078DFD3 /* String+Validation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE911B2C36717B0078DFD3 /* String+Validation.swift */; }; + 1DDE911E2C36717B0078DFD3 /* UIImageViewImageLoading.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE911C2C36717B0078DFD3 /* UIImageViewImageLoading.swift */; }; + 1DDE91212C3671840078DFD3 /* Fonts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91202C3671840078DFD3 /* Fonts.swift */; }; + 1DDE91232C3671920078DFD3 /* CustomNavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91222C3671910078DFD3 /* CustomNavigationBar.swift */; }; + 1DDE91252C3671B20078DFD3 /* RecipeListMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91242C3671B20078DFD3 /* RecipeListMapper.swift */; }; + 1DDE91282C3671DB0078DFD3 /* DateFormatter+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91272C3671DB0078DFD3 /* DateFormatter+Extensions.swift */; }; + 1DDE912B2C3671EC0078DFD3 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91292C3671EC0078DFD3 /* User.swift */; }; + 1DDE912C2C3671EC0078DFD3 /* Comment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE912A2C3671EC0078DFD3 /* Comment.swift */; }; + 1DDE912E2C3671FD0078DFD3 /* FetchRecipeDetailUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE912D2C3671FD0078DFD3 /* FetchRecipeDetailUseCase.swift */; }; + 1DDE91302C36720A0078DFD3 /* RecipeDetailInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE912F2C36720A0078DFD3 /* RecipeDetailInteractor.swift */; }; + 1DDE91332C3672170078DFD3 /* RecipeDetailCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91322C3672170078DFD3 /* RecipeDetailCoordinator.swift */; }; + 1DDE91352C3672230078DFD3 /* RecipeDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91342C3672230078DFD3 /* RecipeDetailViewModel.swift */; }; + 1DDE91382C36722A0078DFD3 /* RecipeDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91362C36722A0078DFD3 /* RecipeDetailViewController.swift */; }; + 1DDE91392C36722A0078DFD3 /* RecipeDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91372C36722A0078DFD3 /* RecipeDetailView.swift */; }; + 1DDE913B2C3672410078DFD3 /* UserDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE913A2C3672410078DFD3 /* UserDTO.swift */; }; + 1DDE913D2C3672490078DFD3 /* RecipeDetailFetchService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE913C2C3672490078DFD3 /* RecipeDetailFetchService.swift */; }; + 1DDE913F2C3672720078DFD3 /* RecipeDetailRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE913E2C3672720078DFD3 /* RecipeDetailRepository.swift */; }; + 1DDE91412C3672850078DFD3 /* RecipeDetailDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91402C3672850078DFD3 /* RecipeDetailDTO.swift */; }; 1DE19E9D2C1B3DC10031804A /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19E9C2C1B3DC10031804A /* SceneDelegate.swift */; }; 1DE19EA72C1B420A0031804A /* FeedListRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EA52C1B420A0031804A /* FeedListRepository.swift */; }; 1DE19EA82C1B420A0031804A /* SearchFeedListRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EA62C1B420A0031804A /* SearchFeedListRepository.swift */; }; 1DE19EB12C1B42200031804A /* NetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EB02C1B42200031804A /* NetworkService.swift */; }; - 1DE19EBF2C1B422F0031804A /* RecipeItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EB42C1B422F0031804A /* RecipeItemViewModel.swift */; }; - 1DE19EC02C1B422F0031804A /* RecipeDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EB62C1B422F0031804A /* RecipeDetailView.swift */; }; 1DE19EC22C1B422F0031804A /* RecipeListItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EBA2C1B422F0031804A /* RecipeListItemViewModel.swift */; }; 1DE19EC32C1B422F0031804A /* SearchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EBB2C1B422F0031804A /* SearchBar.swift */; }; 1DE19EC42C1B422F0031804A /* RecipeListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EBC2C1B422F0031804A /* RecipeListViewController.swift */; }; @@ -65,11 +76,8 @@ /* Begin PBXFileReference section */ 1D1283A12C15E94300C5A870 /* Recipe.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Recipe.swift; sourceTree = ""; }; 1D1283A32C15EA8100C5A870 /* RecipeType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeType.swift; sourceTree = ""; }; - 1D1283A52C15EAA600C5A870 /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = ""; }; - 1D1283A72C15EABB00C5A870 /* Comment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Comment.swift; sourceTree = ""; }; 1D1283A92C15EBCF00C5A870 /* SearchFeedUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchFeedUseCase.swift; sourceTree = ""; }; 1D1283AB2C15EBE600C5A870 /* FetchFeedListUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchFeedListUseCase.swift; sourceTree = ""; }; - 1D1283C72C16CE7C00C5A870 /* DateFormatter+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DateFormatter+Extensions.swift"; sourceTree = ""; }; 1D1283C92C16D9C600C5A870 /* RecipeFetchService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeFetchService.swift; sourceTree = ""; }; 1D2C16E22BE532B700C04508 /* HomeCafeRecipes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HomeCafeRecipes.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1D2C16E52BE532B700C04508 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -86,14 +94,28 @@ 1D4741CD2C1B4F8D009381CE /* RecipeDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDTO.swift; sourceTree = ""; }; 1D4741CE2C1B4F8D009381CE /* RecipePageDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipePageDTO.swift; sourceTree = ""; }; 1D4741CF2C1B4F8D009381CE /* NetworkResponseDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkResponseDTO.swift; sourceTree = ""; }; - 1D4741D02C1B4F8D009381CE /* UserDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDTO.swift; sourceTree = ""; }; - 1DDFFD802C1C096A0083B077 /* RecipeMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeMapper.swift; sourceTree = ""; }; + 1DDE911B2C36717B0078DFD3 /* String+Validation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Validation.swift"; sourceTree = ""; }; + 1DDE911C2C36717B0078DFD3 /* UIImageViewImageLoading.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageViewImageLoading.swift; sourceTree = ""; }; + 1DDE91202C3671840078DFD3 /* Fonts.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Fonts.swift; sourceTree = ""; }; + 1DDE91222C3671910078DFD3 /* CustomNavigationBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomNavigationBar.swift; sourceTree = ""; }; + 1DDE91242C3671B20078DFD3 /* RecipeListMapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeListMapper.swift; sourceTree = ""; }; + 1DDE91272C3671DB0078DFD3 /* DateFormatter+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DateFormatter+Extensions.swift"; sourceTree = ""; }; + 1DDE91292C3671EC0078DFD3 /* User.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = ""; }; + 1DDE912A2C3671EC0078DFD3 /* Comment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Comment.swift; sourceTree = ""; }; + 1DDE912D2C3671FD0078DFD3 /* FetchRecipeDetailUseCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchRecipeDetailUseCase.swift; sourceTree = ""; }; + 1DDE912F2C36720A0078DFD3 /* RecipeDetailInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailInteractor.swift; sourceTree = ""; }; + 1DDE91322C3672170078DFD3 /* RecipeDetailCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailCoordinator.swift; sourceTree = ""; }; + 1DDE91342C3672230078DFD3 /* RecipeDetailViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailViewModel.swift; sourceTree = ""; }; + 1DDE91362C36722A0078DFD3 /* RecipeDetailViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailViewController.swift; sourceTree = ""; }; + 1DDE91372C36722A0078DFD3 /* RecipeDetailView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailView.swift; sourceTree = ""; }; + 1DDE913A2C3672410078DFD3 /* UserDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDTO.swift; sourceTree = ""; }; + 1DDE913C2C3672490078DFD3 /* RecipeDetailFetchService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailFetchService.swift; sourceTree = ""; }; + 1DDE913E2C3672720078DFD3 /* RecipeDetailRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailRepository.swift; sourceTree = ""; }; + 1DDE91402C3672850078DFD3 /* RecipeDetailDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailDTO.swift; sourceTree = ""; }; 1DE19E9C2C1B3DC10031804A /* SceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 1DE19EA52C1B420A0031804A /* FeedListRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedListRepository.swift; sourceTree = ""; }; 1DE19EA62C1B420A0031804A /* SearchFeedListRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchFeedListRepository.swift; sourceTree = ""; }; 1DE19EB02C1B42200031804A /* NetworkService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkService.swift; sourceTree = ""; }; - 1DE19EB42C1B422F0031804A /* RecipeItemViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeItemViewModel.swift; sourceTree = ""; }; - 1DE19EB62C1B422F0031804A /* RecipeDetailView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailView.swift; sourceTree = ""; }; 1DE19EBA2C1B422F0031804A /* RecipeListItemViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeListItemViewModel.swift; sourceTree = ""; }; 1DE19EBB2C1B422F0031804A /* SearchBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchBar.swift; sourceTree = ""; }; 1DE19EBC2C1B422F0031804A /* RecipeListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeListViewController.swift; sourceTree = ""; }; @@ -135,10 +157,10 @@ 1D12839F2C15E7A700C5A870 /* Entities */ = { isa = PBXGroup; children = ( + 1DDE912A2C3671EC0078DFD3 /* Comment.swift */, + 1DDE91292C3671EC0078DFD3 /* User.swift */, 1D1283A12C15E94300C5A870 /* Recipe.swift */, 1D1283A32C15EA8100C5A870 /* RecipeType.swift */, - 1D1283A52C15EAA600C5A870 /* User.swift */, - 1D1283A72C15EABB00C5A870 /* Comment.swift */, ); path = Entities; sourceTree = ""; @@ -147,6 +169,7 @@ isa = PBXGroup; children = ( 1D1283A92C15EBCF00C5A870 /* SearchFeedUseCase.swift */, + 1DDE912D2C3671FD0078DFD3 /* FetchRecipeDetailUseCase.swift */, 1D1283AB2C15EBE600C5A870 /* FetchFeedListUseCase.swift */, ); path = UseCases; @@ -173,19 +196,12 @@ children = ( 1D4741CB2C1B4F8D009381CE /* DTO */, 1D1283C92C16D9C600C5A870 /* RecipeFetchService.swift */, + 1DDE913C2C3672490078DFD3 /* RecipeDetailFetchService.swift */, 1DE19EB02C1B42200031804A /* NetworkService.swift */, ); path = Network; sourceTree = ""; }; - 1D1283C62C16CD9200C5A870 /* Utilities */ = { - isa = PBXGroup; - children = ( - 1D1283C72C16CE7C00C5A870 /* DateFormatter+Extensions.swift */, - ); - path = Utilities; - sourceTree = ""; - }; 1D2C16D92BE532B700C04508 = { isa = PBXGroup; children = ( @@ -211,8 +227,11 @@ 1D2C16E42BE532B700C04508 /* HomeCafeRecipes */ = { isa = PBXGroup; children = ( + 1DDE91312C3672170078DFD3 /* Coordinators */, + 1DDE91262C3671DB0078DFD3 /* Utilities */, + 1DDE911F2C3671840078DFD3 /* Resources */, + 1DDE911A2C36717B0078DFD3 /* Extensions */, 1DE19EB22C1B422F0031804A /* Presentation */, - 1D1283C62C16CD9200C5A870 /* Utilities */, 1D1283AD2C16974B00C5A870 /* Data */, 1D740B402C15E6680001B704 /* Domain */, 1D2C16E52BE532B700C04508 /* AppDelegate.swift */, @@ -246,10 +265,11 @@ isa = PBXGroup; children = ( 1D4741CC2C1B4F8D009381CE /* RecipeImageDTO.swift */, + 1DDE91402C3672850078DFD3 /* RecipeDetailDTO.swift */, 1D4741CD2C1B4F8D009381CE /* RecipeDTO.swift */, + 1DDE913A2C3672410078DFD3 /* UserDTO.swift */, 1D4741CE2C1B4F8D009381CE /* RecipePageDTO.swift */, 1D4741CF2C1B4F8D009381CE /* NetworkResponseDTO.swift */, - 1D4741D02C1B4F8D009381CE /* UserDTO.swift */, ); path = DTO; sourceTree = ""; @@ -264,10 +284,43 @@ path = Domain; sourceTree = ""; }; + 1DDE911A2C36717B0078DFD3 /* Extensions */ = { + isa = PBXGroup; + children = ( + 1DDE911B2C36717B0078DFD3 /* String+Validation.swift */, + 1DDE911C2C36717B0078DFD3 /* UIImageViewImageLoading.swift */, + ); + path = Extensions; + sourceTree = ""; + }; + 1DDE911F2C3671840078DFD3 /* Resources */ = { + isa = PBXGroup; + children = ( + 1DDE91202C3671840078DFD3 /* Fonts.swift */, + ); + path = Resources; + sourceTree = ""; + }; + 1DDE91262C3671DB0078DFD3 /* Utilities */ = { + isa = PBXGroup; + children = ( + 1DDE91272C3671DB0078DFD3 /* DateFormatter+Extensions.swift */, + ); + path = Utilities; + sourceTree = ""; + }; + 1DDE91312C3672170078DFD3 /* Coordinators */ = { + isa = PBXGroup; + children = ( + 1DDE91322C3672170078DFD3 /* RecipeDetailCoordinator.swift */, + ); + path = Coordinators; + sourceTree = ""; + }; 1DDFFD822C1C09AB0083B077 /* Mapper */ = { isa = PBXGroup; children = ( - 1DDFFD802C1C096A0083B077 /* RecipeMapper.swift */, + 1DDE91242C3671B20078DFD3 /* RecipeListMapper.swift */, ); path = Mapper; sourceTree = ""; @@ -276,6 +329,7 @@ isa = PBXGroup; children = ( 1DE19EA52C1B420A0031804A /* FeedListRepository.swift */, + 1DDE913E2C3672720078DFD3 /* RecipeDetailRepository.swift */, 1DE19EA62C1B420A0031804A /* SearchFeedListRepository.swift */, ); path = Repositories; @@ -284,6 +338,7 @@ 1DE19EB22C1B422F0031804A /* Presentation */ = { isa = PBXGroup; children = ( + 1DDE91222C3671910078DFD3 /* CustomNavigationBar.swift */, 1DDFFD822C1C09AB0083B077 /* Mapper */, 1DE19EB32C1B422F0031804A /* Feed */, 1DE19EB72C1B422F0031804A /* FeedList */, @@ -294,7 +349,7 @@ 1DE19EB32C1B422F0031804A /* Feed */ = { isa = PBXGroup; children = ( - 1DE19EB42C1B422F0031804A /* RecipeItemViewModel.swift */, + 1DDE91342C3672230078DFD3 /* RecipeDetailViewModel.swift */, 1DE19EB52C1B422F0031804A /* View */, ); path = Feed; @@ -303,7 +358,8 @@ 1DE19EB52C1B422F0031804A /* View */ = { isa = PBXGroup; children = ( - 1DE19EB62C1B422F0031804A /* RecipeDetailView.swift */, + 1DDE91372C36722A0078DFD3 /* RecipeDetailView.swift */, + 1DDE91362C36722A0078DFD3 /* RecipeDetailViewController.swift */, ); path = View; sourceTree = ""; @@ -331,6 +387,7 @@ 1DF829AF2C299F1F00C337FC /* Interactor */ = { isa = PBXGroup; children = ( + 1DDE912F2C36720A0078DFD3 /* RecipeDetailInteractor.swift */, 1DF829B02C299F1F00C337FC /* RecipeListInteractor.swift */, ); path = Interactor; @@ -480,30 +537,41 @@ 1DF829B12C299F1F00C337FC /* RecipeListInteractor.swift in Sources */, 1D2C16EA2BE532B700C04508 /* ViewController.swift in Sources */, 1DE19EC52C1B422F0031804A /* RecipeListView.swift in Sources */, + 1DDE911E2C36717B0078DFD3 /* UIImageViewImageLoading.swift in Sources */, + 1DDE912B2C3671EC0078DFD3 /* User.swift in Sources */, + 1DDE91352C3672230078DFD3 /* RecipeDetailViewModel.swift in Sources */, + 1DDE913B2C3672410078DFD3 /* UserDTO.swift in Sources */, 1D4741D32C1B4F8D009381CE /* RecipePageDTO.swift in Sources */, + 1DDE91392C36722A0078DFD3 /* RecipeDetailView.swift in Sources */, 1D2C16E62BE532B700C04508 /* AppDelegate.swift in Sources */, + 1DDE91282C3671DB0078DFD3 /* DateFormatter+Extensions.swift in Sources */, + 1DDE91332C3672170078DFD3 /* RecipeDetailCoordinator.swift in Sources */, + 1DDE91382C36722A0078DFD3 /* RecipeDetailViewController.swift in Sources */, 1DE19EB12C1B42200031804A /* NetworkService.swift in Sources */, - 1D1283A62C15EAA600C5A870 /* User.swift in Sources */, + 1DDE913F2C3672720078DFD3 /* RecipeDetailRepository.swift in Sources */, 1D1283AC2C15EBE600C5A870 /* FetchFeedListUseCase.swift in Sources */, - 1D1283A82C15EABB00C5A870 /* Comment.swift in Sources */, - 1D1283C82C16CE7C00C5A870 /* DateFormatter+Extensions.swift in Sources */, + 1DDE91252C3671B20078DFD3 /* RecipeListMapper.swift in Sources */, 1D1283A42C15EA8100C5A870 /* RecipeType.swift in Sources */, 1D4741D22C1B4F8D009381CE /* RecipeDTO.swift in Sources */, - 1DE19EC02C1B422F0031804A /* RecipeDetailView.swift in Sources */, 1D1283AA2C15EBCF00C5A870 /* SearchFeedUseCase.swift in Sources */, 1DE19EA82C1B420A0031804A /* SearchFeedListRepository.swift in Sources */, - 1D4741D52C1B4F8D009381CE /* UserDTO.swift in Sources */, 1DE19EC22C1B422F0031804A /* RecipeListItemViewModel.swift in Sources */, 1DE19EC32C1B422F0031804A /* SearchBar.swift in Sources */, 1DE19E9D2C1B3DC10031804A /* SceneDelegate.swift in Sources */, + 1DDE91232C3671920078DFD3 /* CustomNavigationBar.swift in Sources */, 1D4741D12C1B4F8D009381CE /* RecipeImageDTO.swift in Sources */, + 1DDE91412C3672850078DFD3 /* RecipeDetailDTO.swift in Sources */, 1DE19EA72C1B420A0031804A /* FeedListRepository.swift in Sources */, 1DE19EC62C1B422F0031804A /* RecipeListCell.swift in Sources */, - 1DDFFD812C1C096A0083B077 /* RecipeMapper.swift in Sources */, + 1DDE91212C3671840078DFD3 /* Fonts.swift in Sources */, + 1DDE913D2C3672490078DFD3 /* RecipeDetailFetchService.swift in Sources */, + 1DDE91302C36720A0078DFD3 /* RecipeDetailInteractor.swift in Sources */, 1DE19EC42C1B422F0031804A /* RecipeListViewController.swift in Sources */, - 1DE19EBF2C1B422F0031804A /* RecipeItemViewModel.swift in Sources */, + 1DDE912C2C3671EC0078DFD3 /* Comment.swift in Sources */, + 1DDE911D2C36717B0078DFD3 /* String+Validation.swift in Sources */, 1D1283A22C15E94300C5A870 /* Recipe.swift in Sources */, 1D1283CA2C16D9C600C5A870 /* RecipeFetchService.swift in Sources */, + 1DDE912E2C3671FD0078DFD3 /* FetchRecipeDetailUseCase.swift in Sources */, 1D4741D42C1B4F8D009381CE /* NetworkResponseDTO.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; From 14ecdf69ba4c0121bd0c58a2907b6f6e8d4dc837 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Fri, 5 Jul 2024 22:05:45 +0900 Subject: [PATCH 27/28] =?UTF-8?q?Fix:=20=EC=B9=B4=EB=A9=9C=EC=BC=80?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4=20=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20ViewModel=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/Feed/RecipeDetailViewModel.swift | 14 ++++++-------- .../Presentation/Feed/View/RecipeDetailView.swift | 14 +++++++------- .../HomeCafeRecipes/Resources/Fonts.swift | 4 ++-- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/RecipeDetailViewModel.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/RecipeDetailViewModel.swift index 998ed92..f9243e5 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/RecipeDetailViewModel.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/RecipeDetailViewModel.swift @@ -9,18 +9,16 @@ import Foundation struct RecipeDetailViewModel { let id: Int - let RecipeName: String - let RecipeDescription: String - let RecipeImageUrls: [URL] + let recipeName: String + let recipeDescription: String + let recipeImageUrls: [URL] let isLiked: Bool - let createdAt: Date init(recipe: Recipe) { self.id = recipe.id - self.RecipeName = recipe.name - self.RecipeDescription = recipe.description - self.RecipeImageUrls = recipe.imageUrls.compactMap { URL(string: $0) } + self.recipeName = recipe.name + self.recipeDescription = recipe.description + self.recipeImageUrls = recipe.imageUrls.compactMap { URL(string: $0) } self.isLiked = recipe.isLikedByCurrentUser - self.createdAt = recipe.createdAt } } diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift index 1fb5bd8..b298e23 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift @@ -64,11 +64,11 @@ final class RecipeDetailView: UIView { recipeDescriptionLabel.translatesAutoresizingMaskIntoConstraints = false photoIndexLabel.translatesAutoresizingMaskIntoConstraints = false - recipeNameLabel.font = Fonts.DetailtitleFont + recipeNameLabel.font = Fonts.detailTitleFont recipeNameLabel.numberOfLines = 0 - recipeDescriptionLabel.font = Fonts.DetailBodyFont + recipeDescriptionLabel.font = Fonts.detailBodyFont recipeDescriptionLabel.numberOfLines = 0 - photoIndexLabel.font = Fonts.DetailBodyFont + photoIndexLabel.font = Fonts.detailBodyFont } private func setupLayout() { @@ -101,10 +101,10 @@ final class RecipeDetailView: UIView { func configure(with viewModel: RecipeDetailViewModel) { - recipeNameLabel.text = viewModel.RecipeName - recipeDescriptionLabel.text = viewModel.RecipeDescription - setupScrollViewContent(with: viewModel.RecipeImageUrls) - pageControl.numberOfPages = viewModel.RecipeImageUrls.count + recipeNameLabel.text = viewModel.recipeName + recipeDescriptionLabel.text = viewModel.recipeDescription + setupScrollViewContent(with: viewModel.recipeImageUrls) + pageControl.numberOfPages = viewModel.recipeImageUrls.count updatePhotoIndexLabel(currentPage: 0) } diff --git a/HomeCafeRecipes/HomeCafeRecipes/Resources/Fonts.swift b/HomeCafeRecipes/HomeCafeRecipes/Resources/Fonts.swift index 9ee14f9..ff22c10 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Resources/Fonts.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Resources/Fonts.swift @@ -10,6 +10,6 @@ import UIKit struct Fonts { static let titleFont: UIFont = .systemFont(ofSize: 16, weight: .bold) static let bodyFont: UIFont = .systemFont(ofSize: 14, weight: .regular) - static let DetailTitleFont: UIFont = .systemFont(ofSize: 24, weight: .bold) - static let DetailBodyFont: UIFont = .systemFont(ofSize: 16, weight: .regular) + static let detailTitleFont: UIFont = .systemFont(ofSize: 24, weight: .bold) + static let detailBodyFont: UIFont = .systemFont(ofSize: 16, weight: .regular) } From 557a785962a0abc2d809bc0e6af6a827949892e2 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Mon, 8 Jul 2024 17:45:41 +0900 Subject: [PATCH 28/28] =?UTF-8?q?Fix:=20=EA=B8=B0=EC=A1=B4=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=ED=95=9C=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=ED=9B=84=20=EB=8B=A4=EC=8B=9C=20addSubview=20?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EB=A1=9C=EC=A7=81=EC=9C=BC=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 --- .../Presentation/Feed/View/RecipeDetailView.swift | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift index b298e23..9923ca6 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailView.swift @@ -109,7 +109,8 @@ final class RecipeDetailView: UIView { } private func setupScrollViewContent(with recipeImageUrls: [URL]) { - guard !imagesAdded else { return } + scrollView.subviews.forEach { $0.removeFromSuperview() } + let imageViewWidth = UIScreen.main.bounds.width recipeImageUrls.enumerated().forEach { index, url in @@ -117,11 +118,9 @@ final class RecipeDetailView: UIView { imageView.kf.setImage(with: url) imageView.contentMode = .scaleAspectFill - let xPos = CGFloat(index) * imageViewWidth imageView.frame = CGRect(x: xPos, y: 0, width: imageViewWidth, height: 200) scrollView.addSubview(imageView) - imagesAdded = true } let contentWidth = imageViewWidth * CGFloat(recipeImageUrls.count)