From 2edfc1bc7f9333715938f41f74a772e5b1d443fb Mon Sep 17 00:00:00 2001 From: OneTen19 Date: Wed, 27 Nov 2024 21:17:37 +0900 Subject: [PATCH 01/11] =?UTF-8?q?Feat/#54=20-=20Navigation=20bar=20&=20Tab?= =?UTF-8?q?bar=20=EA=B4=80=EB=A0=A8=20=EC=84=B8=ED=8C=85=EB=93=A4=20-=20?= =?UTF-8?q?=EC=82=AC=EC=A7=84=20=EC=84=A0=ED=83=9D=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EC=A0=84=ED=99=98=20=EC=8B=9C,=20=ED=83=AD=20=EB=B0=94=20?= =?UTF-8?q?=EA=B0=80=EB=A6=AC=EA=B3=A0=20=EC=84=A0=ED=83=9D=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EB=82=98=EC=98=A4=EA=B2=8C=EB=81=94=20-=20?= =?UTF-8?q?=EC=82=AC=EC=A7=84=20=EC=84=A0=ED=83=9D=20=EC=A2=85=EB=A3=8C=20?= =?UTF-8?q?=EC=8B=9C=EC=97=90=EB=8A=94=20=EB=8B=A4=EC=8B=9C=20=ED=83=AD=20?= =?UTF-8?q?=EB=B0=94=20=EB=82=98=EC=98=A4=EA=B2=8C=20-=20=EA=B0=81?= =?UTF-8?q?=EA=B0=81=20=EC=9D=B4=EB=8F=99=20=ED=99=94=EB=A9=B4=EB=B3=84?= =?UTF-8?q?=EB=A1=9C=20=EB=84=A4=EB=B9=84=EA=B2=8C=EC=9D=B4=EC=85=98=20?= =?UTF-8?q?=ED=83=80=EC=9D=B4=ED=8B=80=20=EB=B0=8F=20=EB=92=A4=EB=A1=9C?= =?UTF-8?q?=EA=B0=80=EA=B8=B0=20=EB=B2=84=ED=8A=BC=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../saftyReport.xcodeproj/project.pbxproj | 8 + .../Gallery/GalleryDetailViewController.swift | 10 + .../Gallery/GalleryViewController.swift | 257 ++++++++++-------- .../ReportDetailViewController.swift | 1 + 4 files changed, 158 insertions(+), 118 deletions(-) diff --git a/saftyReport/saftyReport.xcodeproj/project.pbxproj b/saftyReport/saftyReport.xcodeproj/project.pbxproj index b10a3e4..7dce4ab 100644 --- a/saftyReport/saftyReport.xcodeproj/project.pbxproj +++ b/saftyReport/saftyReport.xcodeproj/project.pbxproj @@ -161,6 +161,8 @@ /* Begin XCBuildConfiguration section */ 7837ED592CE48AA300FCAF66 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReferenceAnchor = 7837ED472CE48AA200FCAF66 /* saftyReport */; + baseConfigurationReferenceRelativePath = Resource/Config.xcconfig; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -189,6 +191,8 @@ }; 7837ED5A2CE48AA300FCAF66 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReferenceAnchor = 7837ED472CE48AA200FCAF66 /* saftyReport */; + baseConfigurationReferenceRelativePath = Resource/Config.xcconfig; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -217,6 +221,8 @@ }; 7837ED5B2CE48AA300FCAF66 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReferenceAnchor = 7837ED472CE48AA200FCAF66 /* saftyReport */; + baseConfigurationReferenceRelativePath = Resource/Config.xcconfig; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; @@ -280,6 +286,8 @@ }; 7837ED5C2CE48AA300FCAF66 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReferenceAnchor = 7837ED472CE48AA200FCAF66 /* saftyReport */; + baseConfigurationReferenceRelativePath = Resource/Config.xcconfig; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; diff --git a/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift b/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift index f279206..d6b6426 100644 --- a/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift +++ b/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift @@ -66,11 +66,13 @@ class GalleryDetailViewController: UIViewController { setUI() setLayout() + setupNavigationBar() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) + tabBarController?.tabBar.isHidden = true checkbox.setBackgroundImage( isChecked ? .icnCheckboxISquareSelectedWhite24Px : .icnCheckboxISquareUnselectedWhite24Px, for: .normal @@ -130,6 +132,14 @@ class GalleryDetailViewController: UIViewController { } + private func setupNavigationBar() { + let customNavigationItem = CustomNavigationItem() + customNavigationItem.setUpNavigationBar(for: .back) + navigationItem.backBarButtonItem = customNavigationItem.backBarButtonItem + navigationItem.backBarButtonItem?.tintColor = .gray1 + navigationItem.title = "상세 보기" + } + @objc private func checkboxTapped() { isChecked.toggle() diff --git a/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift b/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift index aac4ecd..2dfba2b 100644 --- a/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift +++ b/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift @@ -35,6 +35,17 @@ class GalleryViewController: UIViewController { setUI() setLayout() setupCollectionView() + setupNavigationBar() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + tabBarController?.tabBar.isHidden = true + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + tabBarController?.tabBar.isHidden = false } private func setUI() { @@ -60,6 +71,134 @@ class GalleryViewController: UIViewController { } + private func setupNavigationBar() { + let customNavigationItem = CustomNavigationItem() + customNavigationItem.setUpNavigationBar(for: .back) + navigationItem.backBarButtonItem = customNavigationItem.backBarButtonItem + navigationItem.backBarButtonItem?.tintColor = .gray1 + navigationItem.title = "안전신문고 갤러리" + } + + @objc private func usingButtonTapped() { + print("사용 버튼이 눌렸습니다.") + } + +} + +extension GalleryViewController: UICollectionViewDelegate { + func collectionView( + _ collectionView: UICollectionView, + viewForSupplementaryElementOfKind kind: String, + at indexPath: IndexPath + ) -> UICollectionReusableView { + guard kind == UICollectionView.elementKindSectionHeader, + let header = collectionView.dequeueReusableSupplementaryView( + ofKind: kind, + withReuseIdentifier: GalleryContentsSectionHeader.identifier, + for: indexPath + ) as? GalleryContentsSectionHeader else { + return UICollectionReusableView() + } + if indexPath.section == 2 { + let sectionTitles = "2024년 11월 14일" + header.configure(with: sectionTitles) + } else if indexPath.section == 3{ + let sectionTitles = "2024년 11월 13일" + header.configure(with: sectionTitles) + } + + return header + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + guard let cell = collectionView.cellForItem(at: indexPath) as? ContentsCell else { return } + + let nextViewController = GalleryDetailViewController() + nextViewController.isChecked = cell.isChecked + nextViewController.indexPath = indexPath + + nextViewController.checkboxHandler = { [weak self] isChecked, indexPath in + guard let self = self else { return } + + if let cell = self.collectionView.cellForItem(at: indexPath) as? ContentsCell { + // 체크박스 상태 업데이트 + cell.isChecked = isChecked + cell.checkbox.setImage( + isChecked ? .icnCheckboxISquareSelectedWhite24Px : .icnCheckboxISquareUnselectedWhite24Px, + for: .normal + ) + } + } + + self.navigationController?.pushViewController(nextViewController, animated: true) + } + +} + +extension GalleryViewController: UICollectionViewDataSource { + func numberOfSections(in collectionView: UICollectionView) -> Int { + return 4 + } + + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) + -> Int { + switch section { + case 0: + return 1 + case 1: + return 1 + case 2: + return 6 + case 3: + return 6 + default: + return 0 + } + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) + -> UICollectionViewCell { + switch indexPath.section { + case 0: + guard let cell = collectionView.dequeueReusableCell( + withReuseIdentifier: MediaSelectCell.cellIdentifier, + for: indexPath + ) as? MediaSelectCell else { + return UICollectionViewCell(frame: .zero) + } + return cell + case 1: + guard let cell = collectionView.dequeueReusableCell( + withReuseIdentifier: WarningCell.cellIdentifier, + for: indexPath + ) as? WarningCell else { + return UICollectionViewCell(frame: .zero) + } + return cell + case 2: + guard let cell = collectionView.dequeueReusableCell( + withReuseIdentifier: ContentsCell.cellIdentifier, + for: indexPath + ) as? ContentsCell else { + return UICollectionViewCell(frame: .zero) + } + + return cell + default: + guard let cell = collectionView.dequeueReusableCell( + withReuseIdentifier: ContentsCell.cellIdentifier, + for: indexPath + ) as? ContentsCell else { + return UICollectionViewCell(frame: .zero) + } + + return cell + } + } + +} + +extension GalleryViewController { private func setupCollectionView() { collectionView.collectionViewLayout = createSection() collectionView.delegate = self @@ -189,122 +328,4 @@ class GalleryViewController: UIViewController { return sectionHeader } - - @objc private func usingButtonTapped() { - print("사용 버튼이 눌렸습니다.") - } - -} - -extension GalleryViewController: UICollectionViewDelegate { - func collectionView( - _ collectionView: UICollectionView, - viewForSupplementaryElementOfKind kind: String, - at indexPath: IndexPath - ) -> UICollectionReusableView { - guard kind == UICollectionView.elementKindSectionHeader, - let header = collectionView.dequeueReusableSupplementaryView( - ofKind: kind, - withReuseIdentifier: GalleryContentsSectionHeader.identifier, - for: indexPath - ) as? GalleryContentsSectionHeader else { - return UICollectionReusableView() - } - if indexPath.section == 2 { - let sectionTitles = "2024년 11월 14일" - header.configure(with: sectionTitles) - } else if indexPath.section == 3{ - let sectionTitles = "2024년 11월 13일" - header.configure(with: sectionTitles) - } - - return header - } - - func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - guard let cell = collectionView.cellForItem(at: indexPath) as? ContentsCell else { return } - - let nextViewController = GalleryDetailViewController() - nextViewController.isChecked = cell.isChecked - nextViewController.indexPath = indexPath - - nextViewController.checkboxHandler = { [weak self] isChecked, indexPath in - guard let self = self else { return } - - if let cell = self.collectionView.cellForItem(at: indexPath) as? ContentsCell { - // 체크박스 상태 업데이트 - cell.isChecked = isChecked - cell.checkbox.setImage( - isChecked ? .icnCheckboxISquareSelectedWhite24Px : .icnCheckboxISquareUnselectedWhite24Px, - for: .normal - ) - } - } - - self.navigationController?.pushViewController(nextViewController, animated: true) - } - -} - -extension GalleryViewController: UICollectionViewDataSource { - func numberOfSections(in collectionView: UICollectionView) -> Int { - return 4 - } - - func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) - -> Int { - switch section { - case 0: - return 1 - case 1: - return 1 - case 2: - return 6 - case 3: - return 6 - default: - return 0 - } - } - - func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) - -> UICollectionViewCell { - switch indexPath.section { - case 0: - guard let cell = collectionView.dequeueReusableCell( - withReuseIdentifier: MediaSelectCell.cellIdentifier, - for: indexPath - ) as? MediaSelectCell else { - return UICollectionViewCell(frame: .zero) - } - return cell - case 1: - guard let cell = collectionView.dequeueReusableCell( - withReuseIdentifier: WarningCell.cellIdentifier, - for: indexPath - ) as? WarningCell else { - return UICollectionViewCell(frame: .zero) - } - return cell - case 2: - guard let cell = collectionView.dequeueReusableCell( - withReuseIdentifier: ContentsCell.cellIdentifier, - for: indexPath - ) as? ContentsCell else { - return UICollectionViewCell(frame: .zero) - } - - return cell - default: - guard let cell = collectionView.dequeueReusableCell( - withReuseIdentifier: ContentsCell.cellIdentifier, - for: indexPath - ) as? ContentsCell else { - return UICollectionViewCell(frame: .zero) - } - - return cell - } - } - } diff --git a/saftyReport/saftyReport/Source/ReportDetail/ReportDetailViewController.swift b/saftyReport/saftyReport/Source/ReportDetail/ReportDetailViewController.swift index 3d1e688..d5b749d 100644 --- a/saftyReport/saftyReport/Source/ReportDetail/ReportDetailViewController.swift +++ b/saftyReport/saftyReport/Source/ReportDetail/ReportDetailViewController.swift @@ -93,6 +93,7 @@ class ReportDetailViewController: UIViewController { let customNavigationItem = CustomNavigationItem() customNavigationItem.setUpNavigationBar(for: .back) navigationItem.backBarButtonItem = customNavigationItem.backBarButtonItem + navigationItem.backBarButtonItem?.tintColor = .gray1 navigationItem.title = "신고하기" navigationController?.setNavigationBarHidden(false, animated: false) From a2dece1c6fd1057bbb6329ae8d1973895deed7dc Mon Sep 17 00:00:00 2001 From: OneTen19 Date: Wed, 27 Nov 2024 21:20:47 +0900 Subject: [PATCH 02/11] Feat/#54 - Address View navigation bar & tabbar --- .../ReportAddressViewController.swift | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/saftyReport/saftyReport/Source/ReportDetail/ReportAddress/ReportAddressViewController.swift b/saftyReport/saftyReport/Source/ReportDetail/ReportAddress/ReportAddressViewController.swift index b142c70..38a5fb6 100644 --- a/saftyReport/saftyReport/Source/ReportDetail/ReportAddress/ReportAddressViewController.swift +++ b/saftyReport/saftyReport/Source/ReportDetail/ReportAddress/ReportAddressViewController.swift @@ -74,6 +74,17 @@ class ReportAddressViewController: UIViewController { setUI() setLayout() + setupNavigationBar() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + tabBarController?.tabBar.isHidden = true + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + tabBarController?.tabBar.isHidden = false } private func setUI() { @@ -136,6 +147,15 @@ class ReportAddressViewController: UIViewController { } } + private func setupNavigationBar() { + let customNavigationItem = CustomNavigationItem() + customNavigationItem.setUpNavigationBar(for: .back) + navigationItem.backBarButtonItem = customNavigationItem.backBarButtonItem + navigationItem.backBarButtonItem?.tintColor = .gray1 + navigationItem.title = "주소 입력" + } + + @objc private func searchKeywordButtonTapped() { print("키워드 검색 버튼이 눌렸습니다.") } From 9e5cf726fbf49d99ed2682c94c61cf23c1053802 Mon Sep 17 00:00:00 2001 From: OneTen19 Date: Wed, 27 Nov 2024 22:24:25 +0900 Subject: [PATCH 03/11] =?UTF-8?q?Feat/#54=20-=20NetworkManager=EC=97=90=20?= =?UTF-8?q?photoAPI=20function=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DTO/Response/GalleryResponse.swift | 6 +- .../saftyReport/Network/NetworkManager.swift | 74 +++++++++++++++++++ .../Source/Gallery/GalleryItem.swift | 26 ------- .../Gallery/GalleryViewController.swift | 2 +- 4 files changed, 78 insertions(+), 30 deletions(-) delete mode 100644 saftyReport/saftyReport/Source/Gallery/GalleryItem.swift diff --git a/saftyReport/saftyReport/Network/DTO/Response/GalleryResponse.swift b/saftyReport/saftyReport/Network/DTO/Response/GalleryResponse.swift index 2be7522..9d3614d 100644 --- a/saftyReport/saftyReport/Network/DTO/Response/GalleryResponse.swift +++ b/saftyReport/saftyReport/Network/DTO/Response/GalleryResponse.swift @@ -12,12 +12,12 @@ import Foundation struct GalleryResponse: Codable { let status: Int? let message: String? - let data: GalleryDataObject? + let data: GalleryData? } -// MARK: - GalleryDataObject +// MARK: - GalleryData -struct GalleryDataObject: Codable { +struct GalleryData: Codable { let photoList: [GalleryPhotoList]? } diff --git a/saftyReport/saftyReport/Network/NetworkManager.swift b/saftyReport/saftyReport/Network/NetworkManager.swift index 228a8c3..785269f 100644 --- a/saftyReport/saftyReport/Network/NetworkManager.swift +++ b/saftyReport/saftyReport/Network/NetworkManager.swift @@ -6,3 +6,77 @@ // import Foundation + +import Alamofire + +class NetworkManager { + + func photoAPI(compleation: @escaping (Result<[GalleryPhotoList], NetworkError>) -> Void) { + guard let baseURL = Bundle.main.object(forInfoDictionaryKey: "BASE_URL") as? String else { return } + + let url = baseURL + "/api/v1/report/photo" + + AF.request(url, method: .get, headers: ["Content-Type": "application/json"]) + .validate() + .response { [weak self] response in + guard let statusCode = response.response?.statusCode, + let data = response.data, + let self + else { + compleation(.failure(.unknownError)) + print("여기가 안됨 1") + return + } + + switch response.result { + case .success: + let photoList = self.decodePhoto(data: data) + compleation(.success(photoList)) + case .failure: + let error = self.handleStatusCode(statusCode, data: data) + compleation(.failure(error)) + } + + } + + } + + func decodePhoto(data: Data) -> [GalleryPhotoList] { + guard let response = try? JSONDecoder().decode(GalleryResponse.self, from: data) + else { + return [] + } + return response.data?.photoList ?? [] + } + + + +} + +extension NetworkManager { + func decodeError(data: Data) -> String { + guard let failResponse = try? JSONDecoder().decode( + FailResponse.self, + from: data + ) else { return "" } + return failResponse.status?.description ?? "" + } + + func handleStatusCode(_ statusCode: Int, data: Data) -> NetworkError { + let errorCode = decodeError(data: data) + switch (statusCode, errorCode) { + case (400, "00"): + return .invalidRequest + case (400, "01"): + return .expressionError + case (404, ""): + return .invalidURL + case (409, "00"): + return .duplicateError + case (500, ""): + return .serverError + default: + return .unknownError + } + } +} diff --git a/saftyReport/saftyReport/Source/Gallery/GalleryItem.swift b/saftyReport/saftyReport/Source/Gallery/GalleryItem.swift deleted file mode 100644 index f64f3d9..0000000 --- a/saftyReport/saftyReport/Source/Gallery/GalleryItem.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// GalleryItem.swift -// saftyReport -// -// Created by OneTen on 11/18/24. -// - -import UIKit - -struct GalleryItem: Hashable { - let id = UUID() - let url: String? - let image: UIImage - let date: String -} - -extension GalleryItem { - static let dummyGalleryItem: [GalleryItem] = [ - GalleryItem(url: nil, image: UIImage(systemName: "square.fill")!, date: "대충 시간"), - GalleryItem(url: nil, image: UIImage(systemName: "square.fill")!, date: "대충 시간"), - GalleryItem(url: nil, image: UIImage(systemName: "square.fill")!, date: "대충 시간"), - GalleryItem(url: nil, image: UIImage(systemName: "square.fill")!, date: "대충 시간"), - GalleryItem(url: nil, image: UIImage(systemName: "square.fill")!, date: "대충 시간"), - GalleryItem(url: nil, image: UIImage(systemName: "square.fill")!, date: "대충 시간"), - ] -} diff --git a/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift b/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift index 2dfba2b..a2338a5 100644 --- a/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift +++ b/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift @@ -9,9 +9,9 @@ import UIKit import SnapKit import Then -import Kingfisher class GalleryViewController: UIViewController { + private var photoList: [GalleryPhotoList] = [] private let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewLayout()) From 37371e3e9f5d6ac84d8f1dc497a50d90f7029a1c Mon Sep 17 00:00:00 2001 From: OneTen19 Date: Thu, 28 Nov 2024 00:06:42 +0900 Subject: [PATCH 04/11] =?UTF-8?q?Feat/#54=20-=20GalleryView=20API=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0=20=EC=84=B1=EA=B3=B5!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../saftyReport/Network/NetworkManager.swift | 8 +++++-- .../Gallery/GalleryViewController.swift | 21 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/saftyReport/saftyReport/Network/NetworkManager.swift b/saftyReport/saftyReport/Network/NetworkManager.swift index 785269f..29511c9 100644 --- a/saftyReport/saftyReport/Network/NetworkManager.swift +++ b/saftyReport/saftyReport/Network/NetworkManager.swift @@ -14,9 +14,12 @@ class NetworkManager { func photoAPI(compleation: @escaping (Result<[GalleryPhotoList], NetworkError>) -> Void) { guard let baseURL = Bundle.main.object(forInfoDictionaryKey: "BASE_URL") as? String else { return } - let url = baseURL + "/api/v1/report/photo" + let url = "\(baseURL)/api/v1/report/photo" - AF.request(url, method: .get, headers: ["Content-Type": "application/json"]) + let headers: HTTPHeaders = ["Content-Type": "application/json", + "userId": "1"] + + AF.request(url, method: .get, headers: headers) .validate() .response { [weak self] response in guard let statusCode = response.response?.statusCode, @@ -34,6 +37,7 @@ class NetworkManager { compleation(.success(photoList)) case .failure: let error = self.handleStatusCode(statusCode, data: data) + print(error.localizedDescription) compleation(.failure(error)) } diff --git a/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift b/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift index a2338a5..2dcb10b 100644 --- a/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift +++ b/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift @@ -11,6 +11,7 @@ import SnapKit import Then class GalleryViewController: UIViewController { + private let networkManager = NetworkManager() private var photoList: [GalleryPhotoList] = [] private let collectionView = UICollectionView(frame: .zero, @@ -36,6 +37,7 @@ class GalleryViewController: UIViewController { setLayout() setupCollectionView() setupNavigationBar() + connectAPI() } override func viewWillAppear(_ animated: Bool) { @@ -83,6 +85,25 @@ class GalleryViewController: UIViewController { print("사용 버튼이 눌렸습니다.") } + private func connectAPI() { + + DispatchQueue.main.async { + self.networkManager.photoAPI { [weak self] result in + guard let self = self else { return } + + switch result { + case let .success(list): + self.photoList = list + case let .failure(error): + print(error.localizedDescription) + } + + + } + } + + } + } extension GalleryViewController: UICollectionViewDelegate { From ed114066860e489c3285b920297661713b655808 Mon Sep 17 00:00:00 2001 From: OneTen19 Date: Thu, 28 Nov 2024 01:06:58 +0900 Subject: [PATCH 05/11] =?UTF-8?q?Fix/#54=20-=20image=20url=EB=93=A4=20nil?= =?UTF-8?q?=EB=A1=9C=20=EC=A0=84=EB=8B=AC=EB=90=98=EB=8D=98=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DTO/Response/GalleryResponse.swift | 6 ++ .../saftyReport/Network/NetworkManager.swift | 65 +++++++++++-------- .../Gallery/GalleryDetailViewController.swift | 5 +- 3 files changed, 47 insertions(+), 29 deletions(-) diff --git a/saftyReport/saftyReport/Network/DTO/Response/GalleryResponse.swift b/saftyReport/saftyReport/Network/DTO/Response/GalleryResponse.swift index 9d3614d..09ec235 100644 --- a/saftyReport/saftyReport/Network/DTO/Response/GalleryResponse.swift +++ b/saftyReport/saftyReport/Network/DTO/Response/GalleryResponse.swift @@ -26,4 +26,10 @@ struct GalleryData: Codable { struct GalleryPhotoList: Codable { let photoID: Int? let photoURL, createdAt: String? + + enum CodingKeys: String, CodingKey { + case photoID = "photoId" + case photoURL = "photoUrl" + case createdAt + } } diff --git a/saftyReport/saftyReport/Network/NetworkManager.swift b/saftyReport/saftyReport/Network/NetworkManager.swift index 29511c9..13420f6 100644 --- a/saftyReport/saftyReport/Network/NetworkManager.swift +++ b/saftyReport/saftyReport/Network/NetworkManager.swift @@ -1,85 +1,94 @@ -// -// NetworkManager.swift -// saftyReport -// -// Created by 이지훈 on 11/18/24. -// - import Foundation - import Alamofire class NetworkManager { func photoAPI(compleation: @escaping (Result<[GalleryPhotoList], NetworkError>) -> Void) { - guard let baseURL = Bundle.main.object(forInfoDictionaryKey: "BASE_URL") as? String else { return } + guard let baseURL = Bundle.main.object(forInfoDictionaryKey: "BASE_URL") as? String else { + print("[Error] BASE_URL is missing in Info.plist") + compleation(.failure(.unknownError)) + return + } let url = "\(baseURL)/api/v1/report/photo" + print("[Request] URL: \(url)") - let headers: HTTPHeaders = ["Content-Type": "application/json", - "userId": "1"] + let headers: HTTPHeaders = ["userId": "1"] + print("[Request] Headers: \(headers)") AF.request(url, method: .get, headers: headers) .validate() .response { [weak self] response in guard let statusCode = response.response?.statusCode, let data = response.data, - let self + let self = self else { + print("[Error] Response or Data is nil") compleation(.failure(.unknownError)) - print("여기가 안됨 1") return } + print("[Response] Status Code: \(statusCode)") + switch response.result { case .success: let photoList = self.decodePhoto(data: data) + print("[Success] Photo List Decoded: \(photoList)") compleation(.success(photoList)) - case .failure: + case .failure(let error): + print("[Error] Request Failed: \(error.localizedDescription)") let error = self.handleStatusCode(statusCode, data: data) - print(error.localizedDescription) compleation(.failure(error)) } - } - } func decodePhoto(data: Data) -> [GalleryPhotoList] { - guard let response = try? JSONDecoder().decode(GalleryResponse.self, from: data) - else { + do { + let response = try JSONDecoder().decode(GalleryResponse.self, from: data) + print("[Decode Success] GalleryResponse Decoded Successfully") + return response.data?.photoList ?? [] + } catch { + print("[Decode Error] Failed to Decode GalleryResponse: \(error)") return [] } - return response.data?.photoList ?? [] } - - - } extension NetworkManager { func decodeError(data: Data) -> String { - guard let failResponse = try? JSONDecoder().decode( - FailResponse.self, - from: data - ) else { return "" } - return failResponse.status?.description ?? "" + do { + let failResponse = try JSONDecoder().decode(FailResponse.self, from: data) + print("[Decode Error Response] Status: \(failResponse.status?.description ?? "Unknown")") + return failResponse.status?.description ?? "" + } catch { + print("[Decode Error] Failed to Decode Error Response: \(error)") + return "" + } } func handleStatusCode(_ statusCode: Int, data: Data) -> NetworkError { let errorCode = decodeError(data: data) + print("[Handle Status Code] Status Code: \(statusCode), Error Code: \(errorCode)") + switch (statusCode, errorCode) { case (400, "00"): + print("[Error] Invalid Request (400, 00)") return .invalidRequest case (400, "01"): + print("[Error] Expression Error (400, 01)") return .expressionError case (404, ""): + print("[Error] Invalid URL (404)") return .invalidURL case (409, "00"): + print("[Error] Duplicate Error (409, 00)") return .duplicateError case (500, ""): + print("[Error] Server Error (500)") return .serverError default: + print("[Error] Unknown Error") return .unknownError } } diff --git a/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift b/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift index d6b6426..a27bbb2 100644 --- a/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift +++ b/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift @@ -22,7 +22,6 @@ class GalleryDetailViewController: UIViewController { private var imageView = UIImageView().then { $0.contentMode = .scaleAspectFit -// $0.image = .test $0.backgroundColor = .gray // 이미지 넣으면 지울 코드 } @@ -132,6 +131,10 @@ class GalleryDetailViewController: UIViewController { } +// func configure(item: GalleryPhotoList){ +// imageView.image = item. +// } + private func setupNavigationBar() { let customNavigationItem = CustomNavigationItem() customNavigationItem.setUpNavigationBar(for: .back) From 931ad02105b43d5cd5529f8db36c75b39fb30e7d Mon Sep 17 00:00:00 2001 From: OneTen19 Date: Thu, 28 Nov 2024 01:19:17 +0900 Subject: [PATCH 06/11] =?UTF-8?q?Chore/#54=20-=20Delete=20CodingKeys=20-?= =?UTF-8?q?=20=EC=BD=94=EB=93=9C=20=EA=B0=84=EA=B2=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Network/DTO/Response/GalleryResponse.swift | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/saftyReport/saftyReport/Network/DTO/Response/GalleryResponse.swift b/saftyReport/saftyReport/Network/DTO/Response/GalleryResponse.swift index 09ec235..d33e4eb 100644 --- a/saftyReport/saftyReport/Network/DTO/Response/GalleryResponse.swift +++ b/saftyReport/saftyReport/Network/DTO/Response/GalleryResponse.swift @@ -24,12 +24,6 @@ struct GalleryData: Codable { // MARK: - GalleryPhotoList struct GalleryPhotoList: Codable { - let photoID: Int? - let photoURL, createdAt: String? - - enum CodingKeys: String, CodingKey { - case photoID = "photoId" - case photoURL = "photoUrl" - case createdAt - } + let photoId: Int? + let photoUrl, createdAt: String? } From 26fbb31377ebe39633fd6cae9167fedaae94b0ef Mon Sep 17 00:00:00 2001 From: OneTen19 Date: Thu, 28 Nov 2024 01:31:51 +0900 Subject: [PATCH 07/11] =?UTF-8?q?Add/#54=20-=20UIImageView=20Extension=20-?= =?UTF-8?q?=20url=EB=A1=9C=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=84=B8?= =?UTF-8?q?=ED=8C=85=ED=95=98=EB=8A=94=20=EA=B3=BC=EC=A0=95=20load?= =?UTF-8?q?=EB=9D=BC=EB=8A=94=20=ED=95=A8=EC=88=98=EB=A1=9C=20=EB=94=B0?= =?UTF-8?q?=EB=A1=9C=20=EB=BA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Resource/Extension/UIImageView+.swift | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 saftyReport/saftyReport/Resource/Extension/UIImageView+.swift diff --git a/saftyReport/saftyReport/Resource/Extension/UIImageView+.swift b/saftyReport/saftyReport/Resource/Extension/UIImageView+.swift new file mode 100644 index 0000000..f68b375 --- /dev/null +++ b/saftyReport/saftyReport/Resource/Extension/UIImageView+.swift @@ -0,0 +1,22 @@ +// +// UIImageView+.swift +// saftyReport +// +// Created by OneTen on 11/28/24. +// + +import UIKit + +extension UIImageView { + func load(url: URL) { + DispatchQueue.global().async { [weak self] in + if let data = try? Data(contentsOf: url) { + if let image = UIImage(data: data) { + DispatchQueue.main.async { + self?.image = image + } + } + } + } + } +} From a132200ffdb6cb7aed475989745f78006b5ba33e Mon Sep 17 00:00:00 2001 From: OneTen19 Date: Thu, 28 Nov 2024 21:34:03 +0900 Subject: [PATCH 08/11] =?UTF-8?q?Feat/#54=20-=20=EC=9D=BC=EB=8B=A8=20?= =?UTF-8?q?=EC=82=AC=EC=A7=84=EB=93=A4=EC=9D=80=20=EB=A7=A4=EC=B9=98=20?= =?UTF-8?q?=EB=81=9D=20-=20=EC=B2=B4=ED=81=AC=EB=B0=95=EC=8A=A4=EA=B0=80?= =?UTF-8?q?=20=EC=97=B0=EB=8F=99=EC=9D=B4=20=EC=95=88=EB=90=A8=20-=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=EB=B2=84=ED=8A=BC=20=ED=99=9C=EC=84=B1?= =?UTF-8?q?=ED=99=94/=EB=B9=84=ED=99=9C=EC=84=B1=ED=99=94=20=EC=96=B4?= =?UTF-8?q?=EB=96=BB=EA=B2=8C=20=ED=95=B4=EC=95=BC=ED=95=A0=20=EC=A7=80=20?= =?UTF-8?q?=EB=AA=A8=EB=A5=B4=EA=B2=A0=EC=9D=8C=20-=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=96=B4=EB=96=BB=EA=B2=8C=20=EB=B3=B4=EB=82=B4?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../saftyReport/Network/NetworkManager.swift | 5 -- .../Source/Gallery/Cell/ContentsCell.swift | 7 ++ .../Gallery/GalleryDetailViewController.swift | 42 ++++++++-- .../Gallery/GalleryViewController.swift | 79 ++++++++++++++----- 4 files changed, 102 insertions(+), 31 deletions(-) diff --git a/saftyReport/saftyReport/Network/NetworkManager.swift b/saftyReport/saftyReport/Network/NetworkManager.swift index 13420f6..daf1d17 100644 --- a/saftyReport/saftyReport/Network/NetworkManager.swift +++ b/saftyReport/saftyReport/Network/NetworkManager.swift @@ -11,10 +11,8 @@ class NetworkManager { } let url = "\(baseURL)/api/v1/report/photo" - print("[Request] URL: \(url)") let headers: HTTPHeaders = ["userId": "1"] - print("[Request] Headers: \(headers)") AF.request(url, method: .get, headers: headers) .validate() @@ -28,12 +26,10 @@ class NetworkManager { return } - print("[Response] Status Code: \(statusCode)") switch response.result { case .success: let photoList = self.decodePhoto(data: data) - print("[Success] Photo List Decoded: \(photoList)") compleation(.success(photoList)) case .failure(let error): print("[Error] Request Failed: \(error.localizedDescription)") @@ -46,7 +42,6 @@ class NetworkManager { func decodePhoto(data: Data) -> [GalleryPhotoList] { do { let response = try JSONDecoder().decode(GalleryResponse.self, from: data) - print("[Decode Success] GalleryResponse Decoded Successfully") return response.data?.photoList ?? [] } catch { print("[Decode Error] Failed to Decode GalleryResponse: \(error)") diff --git a/saftyReport/saftyReport/Source/Gallery/Cell/ContentsCell.swift b/saftyReport/saftyReport/Source/Gallery/Cell/ContentsCell.swift index dfe58ff..3282562 100644 --- a/saftyReport/saftyReport/Source/Gallery/Cell/ContentsCell.swift +++ b/saftyReport/saftyReport/Source/Gallery/Cell/ContentsCell.swift @@ -9,6 +9,7 @@ import UIKit import SnapKit import Then +import Kingfisher class ContentsCell: UICollectionViewCell { var isChecked = false @@ -63,5 +64,11 @@ class ContentsCell: UICollectionViewCell { checkbox.setImage(.icnCheckboxISquareUnselectedWhite24Px, for: .normal) } } + + func configure(item: GalleryPhotoList){ + if let imageURL = URL(string: item.photoUrl ?? "") { + imageView.kf.setImage(with: imageURL) + } + } } diff --git a/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift b/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift index a27bbb2..abc6538 100644 --- a/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift +++ b/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift @@ -21,8 +21,7 @@ class GalleryDetailViewController: UIViewController { } private var imageView = UIImageView().then { - $0.contentMode = .scaleAspectFit - $0.backgroundColor = .gray // 이미지 넣으면 지울 코드 + $0.contentMode = .scaleToFill } private lazy var checkbox = UIButton().then { @@ -39,7 +38,7 @@ class GalleryDetailViewController: UIViewController { } private var createdAtLabel = UILabel().then { - $0.attributedText = .styled(text: "촬영일시", style: .caption1) + $0.attributedText = .styled(text: "촬영일시 :", style: .caption1) $0.font = .systemFont(ofSize: 12, weight: .bold) $0.textColor = .gray13 } @@ -116,10 +115,11 @@ class GalleryDetailViewController: UIViewController { createdAtLabel.snp.makeConstraints { $0.leading.equalToSuperview().inset(8) + $0.width.equalTo(50) } dateTimeLabel.snp.makeConstraints { - $0.leading.equalTo(createdAtLabel.snp.trailing).offset(20) + $0.leading.equalTo(createdAtLabel.snp.trailing).offset(10) } logoLabel.snp.makeConstraints { @@ -131,9 +131,19 @@ class GalleryDetailViewController: UIViewController { } -// func configure(item: GalleryPhotoList){ -// imageView.image = item. -// } + func configure(item: GalleryPhotoList){ + if let imageURL = URL(string: item.photoUrl ?? "") { + imageView.kf.setImage(with: imageURL) + + print("[갤러리 디테일뷰]") + print("[URL] \(imageURL)") + print("[ID] \(item.photoId!)") + print("[CreatedAt] \(item.createdAt!)") + } + + let dateTime = formatDateTime(item.createdAt ?? "") + dateTimeLabel.text = dateTime + } private func setupNavigationBar() { let customNavigationItem = CustomNavigationItem() @@ -154,3 +164,21 @@ class GalleryDetailViewController: UIViewController { } } + +extension GalleryDetailViewController { + private func formatDateTime(_ dateTime: String) -> String { + let inputFormatter = DateFormatter() + inputFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss" // 서버에서 받은 날짜 형식 + + let outputFormatter = DateFormatter() + outputFormatter.dateFormat = "yyyy/MM/dd HH:mm:ss" // 원하는 출력 형식 + + // 입력 문자열을 Date로 변환한 후, 다시 문자열로 변환 + if let date = inputFormatter.date(from: dateTime) { + return outputFormatter.string(from: date) + } else { + print("[Error] Invalid date format: \(dateTime)") + return dateTime // 변환 실패 시 원본 문자열 반환 + } + } +} diff --git a/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift b/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift index 2dcb10b..b0091a0 100644 --- a/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift +++ b/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift @@ -12,7 +12,9 @@ import Then class GalleryViewController: UIViewController { private let networkManager = NetworkManager() - private var photoList: [GalleryPhotoList] = [] + + private var firstSectionPhotoList: [GalleryPhotoList] = [] + private var secondSectionPhotoList: [GalleryPhotoList] = [] private let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewLayout()) @@ -26,9 +28,9 @@ class GalleryViewController: UIViewController { $0.setAttributedTitle(NSAttributedString.styled(text: "사용", style: .heading1), for: .normal) $0.titleLabel?.font = .systemFont(ofSize: 20, weight: .semibold) $0.setTitleColor(.gray1, for: .normal) - $0.backgroundColor = .primaryOrange $0.layer.cornerRadius = 10 $0.addTarget(self, action: #selector(usingButtonTapped), for: .touchUpInside) + $0.backgroundColor = .primaryLight } override func viewDidLoad() { @@ -37,12 +39,12 @@ class GalleryViewController: UIViewController { setLayout() setupCollectionView() setupNavigationBar() - connectAPI() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) tabBarController?.tabBar.isHidden = true + connectAPI() } override func viewWillDisappear(_ animated: Bool) { @@ -80,28 +82,37 @@ class GalleryViewController: UIViewController { navigationItem.backBarButtonItem?.tintColor = .gray1 navigationItem.title = "안전신문고 갤러리" } - + @objc private func usingButtonTapped() { print("사용 버튼이 눌렸습니다.") } private func connectAPI() { - DispatchQueue.main.async { self.networkManager.photoAPI { [weak self] result in guard let self = self else { return } switch result { case let .success(list): - self.photoList = list + + self.firstSectionPhotoList = list.filter({ + self.formatDateTime($0.createdAt!) == "2024년 10월 26일" + }) + .dropLast() + + + self.secondSectionPhotoList = list.filter({ + self.formatDateTime($0.createdAt!) == "2024년 11월 26일" + }) + .dropLast() + + self.collectionView.reloadData() case let .failure(error): print(error.localizedDescription) } - } } - } } @@ -114,17 +125,17 @@ extension GalleryViewController: UICollectionViewDelegate { ) -> UICollectionReusableView { guard kind == UICollectionView.elementKindSectionHeader, let header = collectionView.dequeueReusableSupplementaryView( - ofKind: kind, - withReuseIdentifier: GalleryContentsSectionHeader.identifier, - for: indexPath + ofKind: kind, + withReuseIdentifier: GalleryContentsSectionHeader.identifier, + for: indexPath ) as? GalleryContentsSectionHeader else { return UICollectionReusableView() } if indexPath.section == 2 { - let sectionTitles = "2024년 11월 14일" + let sectionTitles = "2024년 10월 26일" header.configure(with: sectionTitles) } else if indexPath.section == 3{ - let sectionTitles = "2024년 11월 13일" + let sectionTitles = "2024년 11월 26일" header.configure(with: sectionTitles) } @@ -151,6 +162,14 @@ extension GalleryViewController: UICollectionViewDelegate { } } + if indexPath.section == 2 { + nextViewController.configure(item: firstSectionPhotoList[indexPath.row]) + + } else { + nextViewController.configure(item: secondSectionPhotoList[indexPath.row]) + } + + self.navigationController?.pushViewController(nextViewController, animated: true) } @@ -169,9 +188,9 @@ extension GalleryViewController: UICollectionViewDataSource { case 1: return 1 case 2: - return 6 + return firstSectionPhotoList.count case 3: - return 6 + return secondSectionPhotoList.count default: return 0 } @@ -204,15 +223,19 @@ extension GalleryViewController: UICollectionViewDataSource { return UICollectionViewCell(frame: .zero) } + cell.configure(item: firstSectionPhotoList[indexPath.row]) + return cell default: guard let cell = collectionView.dequeueReusableCell( withReuseIdentifier: ContentsCell.cellIdentifier, - for: indexPath + for: indexPath.appending(9) ) as? ContentsCell else { return UICollectionViewCell(frame: .zero) } + cell.configure(item: secondSectionPhotoList[indexPath.row]) + return cell } } @@ -232,8 +255,8 @@ extension GalleryViewController { collectionView.register(ContentsCell.self, forCellWithReuseIdentifier: ContentsCell.cellIdentifier) collectionView.register(GalleryContentsSectionHeader.self, - forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, - withReuseIdentifier: GalleryContentsSectionHeader.identifier + forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, + withReuseIdentifier: GalleryContentsSectionHeader.identifier ) } @@ -332,7 +355,7 @@ extension GalleryViewController { trailing: 20 ) section.boundarySupplementaryItems = [self.createSectionHeader()] // 헤더 추가 - + return section } @@ -350,3 +373,21 @@ extension GalleryViewController { return sectionHeader } } + +extension GalleryViewController { + private func formatDateTime(_ dateTime: String) -> String { + let inputFormatter = DateFormatter() + inputFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss" // 서버에서 받은 날짜 형식 + + let outputFormatter = DateFormatter() + outputFormatter.dateFormat = "yyyy년 MM월 dd일" // 원하는 출력 형식 + + // 입력 문자열을 Date로 변환한 후, 다시 문자열로 변환 + if let date = inputFormatter.date(from: dateTime) { + return outputFormatter.string(from: date) + } else { + print("[Error] Invalid date format: \(dateTime)") + return dateTime // 변환 실패 시 원본 문자열 반환 + } + } +} From aac1188f55e64327835cf2ecf2a0c4947e96f8c3 Mon Sep 17 00:00:00 2001 From: OneTen19 Date: Thu, 28 Nov 2024 22:16:20 +0900 Subject: [PATCH 09/11] =?UTF-8?q?Feat/#54=20-=20Help=20=EC=A7=80=ED=9B=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../saftyReport/Source/Gallery/Cell/ContentsCell.swift | 6 +++--- .../Source/Gallery/GalleryDetailViewController.swift | 8 +++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/saftyReport/saftyReport/Source/Gallery/Cell/ContentsCell.swift b/saftyReport/saftyReport/Source/Gallery/Cell/ContentsCell.swift index 3282562..b59cbad 100644 --- a/saftyReport/saftyReport/Source/Gallery/Cell/ContentsCell.swift +++ b/saftyReport/saftyReport/Source/Gallery/Cell/ContentsCell.swift @@ -24,13 +24,13 @@ class ContentsCell: UICollectionViewCell { lazy var checkbox = UIButton().then { $0.clipsToBounds = true $0.contentMode = .scaleAspectFill - $0.setImage(isChecked ? .icnCheckboxISquareSelectedWhite24Px : .icnCheckboxISquareUnselectedWhite24Px, for: .normal) + $0.setImage(.icnCheckboxISquareUnselectedWhite24Px, for: .normal) $0.addTarget(self, action: #selector(checkboxTapped), for: .touchUpInside) } override init(frame: CGRect) { super .init(frame: frame) - + setUI() setLayout() } @@ -70,5 +70,5 @@ class ContentsCell: UICollectionViewCell { imageView.kf.setImage(with: imageURL) } } - + } diff --git a/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift b/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift index abc6538..ae02f58 100644 --- a/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift +++ b/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift @@ -13,9 +13,9 @@ import Then class GalleryDetailViewController: UIViewController { var checkboxHandler: ((Bool, IndexPath) -> ())? var indexPath: IndexPath! - + var isChecked = false - + private var baseView = UIView().then { $0.backgroundColor = .gray1 } @@ -70,11 +70,11 @@ class GalleryDetailViewController: UIViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - tabBarController?.tabBar.isHidden = true checkbox.setBackgroundImage( isChecked ? .icnCheckboxISquareSelectedWhite24Px : .icnCheckboxISquareUnselectedWhite24Px, for: .normal ) + tabBarController?.tabBar.isHidden = true } override func viewWillDisappear(_ animated: Bool) { @@ -132,6 +132,7 @@ class GalleryDetailViewController: UIViewController { } func configure(item: GalleryPhotoList){ + if let imageURL = URL(string: item.photoUrl ?? "") { imageView.kf.setImage(with: imageURL) @@ -143,6 +144,7 @@ class GalleryDetailViewController: UIViewController { let dateTime = formatDateTime(item.createdAt ?? "") dateTimeLabel.text = dateTime + } private func setupNavigationBar() { From 29b7cdfe3f5c548f8cad48e4ea566a50d0aabdd7 Mon Sep 17 00:00:00 2001 From: OneTen19 Date: Thu, 28 Nov 2024 22:35:09 +0900 Subject: [PATCH 10/11] =?UTF-8?q?Fix/#54=20-=20checkbox=20=EC=97=B0?= =?UTF-8?q?=EB=8F=99=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Source/Gallery/Cell/ContentsCell.swift | 9 +++++++- .../Gallery/GalleryViewController.swift | 22 +++++++++++-------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/saftyReport/saftyReport/Source/Gallery/Cell/ContentsCell.swift b/saftyReport/saftyReport/Source/Gallery/Cell/ContentsCell.swift index b59cbad..bbd667e 100644 --- a/saftyReport/saftyReport/Source/Gallery/Cell/ContentsCell.swift +++ b/saftyReport/saftyReport/Source/Gallery/Cell/ContentsCell.swift @@ -65,10 +65,17 @@ class ContentsCell: UICollectionViewCell { } } - func configure(item: GalleryPhotoList){ + func configure(item: GalleryPhotoList, isChecked: Bool = false){ if let imageURL = URL(string: item.photoUrl ?? "") { imageView.kf.setImage(with: imageURL) } + + self.isChecked = isChecked + self.checkbox.setImage( + isChecked ? .icnCheckboxISquareSelectedWhite24Px : .icnCheckboxISquareUnselectedWhite24Px, + for: .normal + ) + } } diff --git a/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift b/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift index b0091a0..337bd3e 100644 --- a/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift +++ b/saftyReport/saftyReport/Source/Gallery/GalleryViewController.swift @@ -14,7 +14,10 @@ class GalleryViewController: UIViewController { private let networkManager = NetworkManager() private var firstSectionPhotoList: [GalleryPhotoList] = [] + private var firstSectionCheckedStatus: Set = [] + private var secondSectionPhotoList: [GalleryPhotoList] = [] + private var secondSectionCheckedStatus: Set = [] private let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewLayout()) @@ -152,14 +155,15 @@ extension GalleryViewController: UICollectionViewDelegate { nextViewController.checkboxHandler = { [weak self] isChecked, indexPath in guard let self = self else { return } - if let cell = self.collectionView.cellForItem(at: indexPath) as? ContentsCell { - // 체크박스 상태 업데이트 - cell.isChecked = isChecked - cell.checkbox.setImage( - isChecked ? .icnCheckboxISquareSelectedWhite24Px : .icnCheckboxISquareUnselectedWhite24Px, - for: .normal - ) + if isChecked { + self.firstSectionCheckedStatus.insert(indexPath) + self.secondSectionCheckedStatus.insert(indexPath) + } else { + self.firstSectionCheckedStatus.remove(indexPath) + self.secondSectionCheckedStatus.remove(indexPath) } + + self.collectionView.reloadData() } if indexPath.section == 2 { @@ -223,7 +227,7 @@ extension GalleryViewController: UICollectionViewDataSource { return UICollectionViewCell(frame: .zero) } - cell.configure(item: firstSectionPhotoList[indexPath.row]) + cell.configure(item: firstSectionPhotoList[indexPath.row], isChecked: firstSectionCheckedStatus.contains(indexPath)) return cell default: @@ -234,7 +238,7 @@ extension GalleryViewController: UICollectionViewDataSource { return UICollectionViewCell(frame: .zero) } - cell.configure(item: secondSectionPhotoList[indexPath.row]) + cell.configure(item: secondSectionPhotoList[indexPath.row], isChecked: secondSectionCheckedStatus.contains(indexPath)) return cell } From 6e483b8d0265bcb3a58d8152d0074946342cc71d Mon Sep 17 00:00:00 2001 From: OneTen19 Date: Thu, 28 Nov 2024 22:44:42 +0900 Subject: [PATCH 11/11] Chore/#54 - swift lint --- .../saftyReport/Source/Gallery/Cell/ContentsCell.swift | 6 +++--- .../Source/Gallery/GalleryDetailViewController.swift | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/saftyReport/saftyReport/Source/Gallery/Cell/ContentsCell.swift b/saftyReport/saftyReport/Source/Gallery/Cell/ContentsCell.swift index bbd667e..0d530a8 100644 --- a/saftyReport/saftyReport/Source/Gallery/Cell/ContentsCell.swift +++ b/saftyReport/saftyReport/Source/Gallery/Cell/ContentsCell.swift @@ -72,9 +72,9 @@ class ContentsCell: UICollectionViewCell { self.isChecked = isChecked self.checkbox.setImage( - isChecked ? .icnCheckboxISquareSelectedWhite24Px : .icnCheckboxISquareUnselectedWhite24Px, - for: .normal - ) + isChecked ? .icnCheckboxISquareSelectedWhite24Px : .icnCheckboxISquareUnselectedWhite24Px, + for: .normal + ) } diff --git a/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift b/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift index ae02f58..1278520 100644 --- a/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift +++ b/saftyReport/saftyReport/Source/Gallery/GalleryDetailViewController.swift @@ -29,7 +29,7 @@ class GalleryDetailViewController: UIViewController { $0.setBackgroundImage(.icnCheckboxISquareUnselectedWhite24Px, for: .normal) $0.addTarget(self, action: #selector(checkboxTapped), for: .touchUpInside) } - + private var timeStackView = UIStackView().then { $0.layer.cornerRadius = 5 $0.layer.borderWidth = 1