diff --git a/Deartoday/Deartoday.xcodeproj/project.pbxproj b/Deartoday/Deartoday.xcodeproj/project.pbxproj index 4d369c8..f0c2caf 100644 --- a/Deartoday/Deartoday.xcodeproj/project.pbxproj +++ b/Deartoday/Deartoday.xcodeproj/project.pbxproj @@ -82,6 +82,7 @@ 984099E92881F4A700025092 /* sound_box.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 984099E82881F4A700025092 /* sound_box.mp3 */; }; 984099EB2881F4CD00025092 /* Sound.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984099EA2881F4CD00025092 /* Sound.swift */; }; 984099ED2881F50000025092 /* sound_player.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 984099EC2881F50000025092 /* sound_player.mp3 */; }; + 9862D07228AAE858000EAA7B /* CheckTimeTravelsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9862D07128AAE858000EAA7B /* CheckTimeTravelsViewController.swift */; }; 986E000128A4DCC9008EB3F2 /* CheckMessageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 986E000028A4DCC9008EB3F2 /* CheckMessageViewController.swift */; }; 986E000328A62A04008EB3F2 /* MessageCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 986E000228A62A04008EB3F2 /* MessageCollectionViewCell.swift */; }; 986F5C362887FA83001109F1 /* TravelInfoCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 986F5C342887FA83001109F1 /* TravelInfoCollectionReusableView.swift */; }; @@ -199,6 +200,7 @@ 984099E82881F4A700025092 /* sound_box.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = sound_box.mp3; sourceTree = ""; }; 984099EA2881F4CD00025092 /* Sound.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sound.swift; sourceTree = ""; }; 984099EC2881F50000025092 /* sound_player.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = sound_player.mp3; sourceTree = ""; }; + 9862D07128AAE858000EAA7B /* CheckTimeTravelsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckTimeTravelsViewController.swift; sourceTree = ""; }; 986E000028A4DCC9008EB3F2 /* CheckMessageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckMessageViewController.swift; sourceTree = ""; }; 986E000228A62A04008EB3F2 /* MessageCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageCollectionViewCell.swift; sourceTree = ""; }; 986F5C342887FA83001109F1 /* TravelInfoCollectionReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TravelInfoCollectionReusableView.swift; sourceTree = ""; }; @@ -862,6 +864,7 @@ isa = PBXGroup; children = ( 98A47512287DED14008891F5 /* CheckTimeTravelViewController.swift */, + 9862D07128AAE858000EAA7B /* CheckTimeTravelsViewController.swift */, ); path = Controller; sourceTree = ""; @@ -1181,6 +1184,7 @@ 92CC3BA2287D62C400EA5617 /* VirtualSpaceDataModel.swift in Sources */, 923C69B5287810DE00B8EC56 /* UITextField+.swift in Sources */, 9803F3C628848B4100A5A239 /* CheckTimeTravelResponse.swift in Sources */, + 9862D07228AAE858000EAA7B /* CheckTimeTravelsViewController.swift in Sources */, 98245CE728869A0A007821FA /* CheckTimeTravelDetailViewController.swift in Sources */, 92DB358428756B67001E2006 /* BaseTargetType.swift in Sources */, 98A4750F287DECF7008891F5 /* CheckTImeTravelDataModel.swift in Sources */, diff --git a/Deartoday/Deartoday/Resource/Support/SceneDelegate.swift b/Deartoday/Deartoday/Resource/Support/SceneDelegate.swift index 57e8e3f..ea20165 100644 --- a/Deartoday/Deartoday/Resource/Support/SceneDelegate.swift +++ b/Deartoday/Deartoday/Resource/Support/SceneDelegate.swift @@ -13,12 +13,12 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { - guard let scene = (scene as? UIWindowScene) else { return } - self.window = UIWindow(windowScene: scene) - self.window?.rootViewController = SplashViewController() - self.window?.makeKeyAndVisible() +// guard let scene = (scene as? UIWindowScene) else { return } +// self.window = UIWindow(windowScene: scene) +// self.window?.rootViewController = SplashViewController() +// self.window?.makeKeyAndVisible() -// guard let _ = (scene as? UIWindowScene) else { return } + guard let _ = (scene as? UIWindowScene) else { return } } func sceneDidDisconnect(_ scene: UIScene) { diff --git a/Deartoday/Deartoday/Screen/CheckTimeTravel/Controller/CheckTimeTravelViewController.swift b/Deartoday/Deartoday/Screen/CheckTimeTravel/Controller/CheckTimeTravelViewController.swift index 7c5cb3c..c3e6c50 100644 --- a/Deartoday/Deartoday/Screen/CheckTimeTravel/Controller/CheckTimeTravelViewController.swift +++ b/Deartoday/Deartoday/Screen/CheckTimeTravel/Controller/CheckTimeTravelViewController.swift @@ -7,10 +7,6 @@ import UIKit -enum TimeTravelSection { - case tape -} - final class CheckTimeTravelViewController: UIViewController { // MARK: - Property diff --git a/Deartoday/Deartoday/Screen/CheckTimeTravel/Controller/CheckTimeTravelsViewController.swift b/Deartoday/Deartoday/Screen/CheckTimeTravel/Controller/CheckTimeTravelsViewController.swift new file mode 100644 index 0000000..601831f --- /dev/null +++ b/Deartoday/Deartoday/Screen/CheckTimeTravel/Controller/CheckTimeTravelsViewController.swift @@ -0,0 +1,253 @@ +// +// CheckTimeTravelsViewController.swift +// Deartoday +// +// Created by 이경민 on 2022/08/16. +// + +import UIKit + +import SnapKit +import Then + +enum TimeTravelSection { + case tape +} + +final class CheckTimeTravelsViewController: UIViewController { + + // MARK: - Property + + private var dataSource: UITableViewDiffableDataSource! + private var snapshot: NSDiffableDataSourceSnapshot! + private var timeTapes: [TimeTapeDataModel] = [] + + // MARK: - UI Property + + private let tapesImageView = UIImageView(image: Constant.Image.imgTapeBundle) + private let emptyImageView = UIImageView(image: Constant.Image.imgTape) + + private let headerView = UIView().then { + $0.backgroundColor = .clear + } + + private let backButton = UIButton().then { + $0.setImage(Constant.Image.icBack, for: .normal) + $0.addTarget(self, action: #selector(backButtonDidTap), for: .touchUpInside) + } + + private let titleLabel = UILabel().then { + $0.font = .h1 + $0.text = "나의 시간 여행" + $0.textColor = .darkGray01 + $0.setPartialLabelColor(targetStringList: ["시간 여행"], color: .blue02) + } + + private let descriptionLabel = UILabel().then { + $0.font = .caption2 + $0.text = "디어투데이와 함께한 시간 여행을\n확인하고 그날의 행복을 추억해보세요" + $0.textColor = .gray00 + $0.numberOfLines = 0 + } + + private let emptyView = UIView().then { + $0.isHidden = true + $0.backgroundColor = .clear + } + + private let emptyDescriptionLabel = UILabel().then { + $0.font = .caption2 + $0.text = "아직 디어투데이와 함께한 시간 여행이 없어요\n지금 바로 시간 여행을 떠나볼까요?" + $0.textColor = .gray01 + $0.numberOfLines = 0 + } + + private let timeTravelButton = DDSButton().then { + $0.text = "시간 여행 떠나기" + $0.hasLeftIcon = true + $0.style = .present + } + + private let timeTravelView = UIView().then { + $0.backgroundColor = .clear + $0.isUserInteractionEnabled = true + } + + private lazy var tableView: UITableView = { + return UITableView(frame: .zero, style: .plain).then { + $0.separatorStyle = .none + $0.showsVerticalScrollIndicator = false + $0.isHidden = true + } + }() + + // MARK: - Life Cycle + + override func viewDidLoad() { + super.viewDidLoad() + setUI() + setLayout() + setTableView() + setGesture() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + getTimeTravelInfo() + } + + // MARK: - @objc + + @objc private func backButtonDidTap() { + navigationController?.popViewController(animated: true) + } + + @objc private func timeTravelComponentDidTap() { + let timeTravel = TimeTravelViewController() + timeTravel.modalTransitionStyle = .crossDissolve + timeTravel.modalPresentationStyle = .fullScreen + present(timeTravel, animated: true) { + self.navigationController?.popViewController(animated: false) + } + } + + // MARK: - Custom Method + + private func setUI() { + view.backgroundColor = .white + } + + private func setLayout() { + setHierarchy() + setConstraint() + } + + private func setTableView() { + tableView.delegate = self + registerXib() + setTableViewUI() + } + + private func setGesture() { + let timeTravelGesture = UIGestureRecognizer(target: self, action: #selector(timeTravelComponentDidTap)) + timeTravelView.addGestureRecognizer(timeTravelGesture) + } + + private func setDataSource() { + dataSource = UITableViewDiffableDataSource(tableView: tableView, cellProvider: { (tableView: UITableView, indexPath: IndexPath, identifier: TimeTapeDataModel) -> UITableViewCell? in + guard let cell = tableView.dequeueReusableCell(withIdentifier: TimeTapeTableViewCell.identifier, for: indexPath) as? TimeTapeTableViewCell else { return UITableViewCell() } + cell.selectionStyle = .none + cell.setData(model: self.timeTapes[indexPath.item]) + return cell + }) + } + + private func updateSnapshot() { + snapshot = NSDiffableDataSourceSnapshot() + snapshot.appendSections([.tape]) + snapshot.appendItems(timeTapes, toSection: .tape) + dataSource.apply(snapshot, animatingDifferences: true) + } + + private func updateTapeList() { + setDataSource() + updateSnapshot() + } + + private func registerXib() { + let nib = UINib(nibName: TimeTapeTableViewCell.identifier, bundle: nil) + tableView.register(nib, forCellReuseIdentifier: TimeTapeTableViewCell.identifier) + } + + private func setTableViewUI() { + tableView.estimatedRowHeight = 273 + tableView.rowHeight = UITableView.automaticDimension + } + + private func setTimeTravelTapeInfo() { + updateTapeList() + emptyView.isHidden = !(timeTapes.count == 0) + tableView.isHidden = (timeTapes.count == 0) + } + + private func setHierarchy() { + view.addSubviews([headerView, emptyView, tableView]) + headerView.addSubviews([backButton, tapesImageView, titleLabel, descriptionLabel]) + emptyView.addSubviews([emptyImageView, emptyDescriptionLabel, timeTravelButton]) + timeTravelButton.addSubview(timeTravelView) + } + + private func setConstraint() { + setHeaderViewConstraint() + setTableViewConstraint() + setEmptyViewConstraint() + } +} + + +// MARK: - UITableViewDelegate + +extension CheckTimeTravelsViewController: UITableViewDelegate { + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + guard let detail = UIStoryboard(name: Constant.Storyboard.CheckTimeTravelDetail, bundle: nil) + .instantiateViewController(withIdentifier: Constant.ViewController.CheckTimeTravelDetail) as? CheckTimeTravelDetailViewController else { return } + detail.timeTravelID = timeTapes[indexPath.item].timeTravelID + navigationController?.pushViewController(detail, animated: true) + } +} + +// MARK: - Network + +extension CheckTimeTravelsViewController { + private func getTimeTravelInfo() { + CheckTimeTravelAPI.shared.getCheckTimeTravel { [weak self] tapeData in + guard let tapeData = tapeData else { return } + self?.timeTapes = tapeData.data?.timeTravels ?? [] + self?.setTimeTravelTapeInfo() + } + } +} + +// MARK: - Constraint + +extension CheckTimeTravelsViewController { + private func setHeaderViewConstraint() { + headerView.snp.makeConstraints { + $0.top.leading.trailing.equalTo(view.safeAreaLayoutGuide).inset(0) + $0.height.equalTo(167) + } + + backButton.snp.makeConstraints { + $0.top.equalToSuperview().inset(14) + $0.leading.equalToSuperview().inset(6) + $0.width.height.equalTo(44) + } + + tapesImageView.snp.makeConstraints { + $0.top.equalToSuperview().inset(69) + $0.trailing.equalToSuperview().inset(16) + } + + titleLabel.snp.makeConstraints { + $0.top.equalTo(backButton.snp.bottom).offset(14) + $0.leading.equalToSuperview().inset(20) + } + + descriptionLabel.snp.makeConstraints { + $0.top.equalTo(titleLabel.snp.bottom).offset(4) + $0.leading.equalToSuperview().inset(20) + } + } + + private func setTableViewConstraint() { + tableView.snp.makeConstraints { + $0.top.equalTo(headerView.snp.bottom).offset(0) + $0.leading.trailing.equalToSuperview().inset(16) + $0.bottom.equalToSuperview().inset(0) + } + } + + private func setEmptyViewConstraint() { + + } +}