From ad39aec7031c19275d798fee42c7e2e3db297b60 Mon Sep 17 00:00:00 2001 From: trumanfromkorea Date: Mon, 12 Dec 2022 19:01:14 +0900 Subject: [PATCH 1/6] =?UTF-8?q?[refactor]=20ThemeButton=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=20(#110)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SpaceCapsule.xcodeproj/project.pbxproj | 4 +++ .../Components/Theme/ThemeButton.swift | 26 +++++++++++++++++++ .../Scene/Auth/Nickname/NicknameView.swift | 10 +------ .../CapsuleOpen/CapsuleOpenView.swift | 12 +-------- .../CapsuleClose/CapsuleCloseView.swift | 15 ++++------- .../CapsuleLocate/CapsuleLocateView.swift | 11 +------- .../CapsuleLocateViewController.swift | 1 - .../DatePicker/DatePickerView.swift | 15 +++-------- .../Profile/ProfileViewController.swift | 1 + 9 files changed, 42 insertions(+), 53 deletions(-) create mode 100644 SpaceCapsule/SpaceCapsule/Components/Theme/ThemeButton.swift diff --git a/SpaceCapsule/SpaceCapsule.xcodeproj/project.pbxproj b/SpaceCapsule/SpaceCapsule.xcodeproj/project.pbxproj index d72fcfe..3b87cab 100644 --- a/SpaceCapsule/SpaceCapsule.xcodeproj/project.pbxproj +++ b/SpaceCapsule/SpaceCapsule.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 0D1331C7293842D300B2CD28 /* Address.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1331C6293842D300B2CD28 /* Address.swift */; }; + 0D219825294730A600B7401B /* ThemeButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D219824294730A600B7401B /* ThemeButton.swift */; }; 0D46DEFA2923E1180045400A /* UIFont+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D46DEF92923E1180045400A /* UIFont+.swift */; }; 0D4C11372927489D00B1C2B6 /* UIViewPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D4C11362927489D00B1C2B6 /* UIViewPreview.swift */; }; 0D4C11392927495900B1C2B6 /* UIViewControllerPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D4C11382927495900B1C2B6 /* UIViewControllerPreview.swift */; }; @@ -192,6 +193,7 @@ /* Begin PBXFileReference section */ 0D1331C6293842D300B2CD28 /* Address.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Address.swift; sourceTree = ""; }; + 0D219824294730A600B7401B /* ThemeButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeButton.swift; sourceTree = ""; }; 0D2B7AB92934594400CE34E3 /* running.gpx */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = running.gpx; sourceTree = ""; }; 0D46DEF92923E1180045400A /* UIFont+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFont+.swift"; sourceTree = ""; }; 0D4C11362927489D00B1C2B6 /* UIViewPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewPreview.swift; sourceTree = ""; }; @@ -552,6 +554,7 @@ children = ( 59D8CFBB29360A8900FD9CF6 /* ThemeThumbnailImageView.swift */, 0D9D672D292486780038F529 /* ThemeLabel.swift */, + 0D219824294730A600B7401B /* ThemeButton.swift */, 0DA6610C292778BE00CF3563 /* ThemeTextField.swift */, 0D77D7C8292B5D490038D054 /* SelectButton.swift */, 2885A9FF293B6466003E5311 /* ProfileButton.swift */, @@ -1223,6 +1226,7 @@ 0DFF50E3294067E600079FA6 /* UIControl+Rx.swift in Sources */, 288A8EA729235AF1000229D2 /* NicknameViewModel.swift in Sources */, 28245562293B17B100DE03A1 /* UnOpenable.swift in Sources */, + 0D219825294730A600B7401B /* ThemeButton.swift in Sources */, 4A1D1BC3294033C200F47ACB /* CapsuleSettingsView.swift in Sources */, 288A8ECC29235BE9000229D2 /* HomeViewController.swift in Sources */, 0DA6610D292778BE00CF3563 /* ThemeTextField.swift in Sources */, diff --git a/SpaceCapsule/SpaceCapsule/Components/Theme/ThemeButton.swift b/SpaceCapsule/SpaceCapsule/Components/Theme/ThemeButton.swift new file mode 100644 index 0000000..8e67c10 --- /dev/null +++ b/SpaceCapsule/SpaceCapsule/Components/Theme/ThemeButton.swift @@ -0,0 +1,26 @@ +// +// ThemeButton.swift +// SpaceCapsule +// +// Created by 장재훈 on 2022/12/12. +// + +import UIKit + +final class ThemeButton: UIButton { + override var isEnabled: Bool { + didSet { + backgroundColor = isEnabled ? .themeColor200 : .themeGray200 + } + } + + convenience init(title: String) { + self.init() + + setTitle(title, for: .normal) + setTitleColor(.white, for: .normal) + titleLabel?.font = .themeFont(ofSize: FrameResource.fontSize100) + backgroundColor = .themeColor200 + layer.cornerRadius = FrameResource.commonCornerRadius + } +} diff --git a/SpaceCapsule/SpaceCapsule/Scene/Auth/Nickname/NicknameView.swift b/SpaceCapsule/SpaceCapsule/Scene/Auth/Nickname/NicknameView.swift index 523bb6e..82a4b71 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/Auth/Nickname/NicknameView.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/Auth/Nickname/NicknameView.swift @@ -16,15 +16,7 @@ final class NicknameView: UIView, BaseView { let nicknameTextField = ThemeTextField(placeholder: "닉네임을 입력해주세요") - let doneButton: UIButton = { - let button = UIButton() - button.setTitle("완료", for: .normal) - button.titleLabel?.font = .themeFont(ofSize: FrameResource.fontSize100) - button.backgroundColor = .themeColor200 - button.layer.cornerRadius = FrameResource.commonCornerRadius - - return button - }() + let doneButton = ThemeButton(title: "완료") // MARK: - Lifecycles diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenView.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenView.swift index a28ec9e..42038a8 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenView.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenView.swift @@ -34,16 +34,7 @@ final class CapsuleOpenView: UIView, BaseView, UnOpenable { return dateLabel }() - var openButton = { - let button = UIButton() - button.titleLabel?.font = .themeFont(ofSize: FrameResource.fontSize100) - button.setTitle("열기", for: .normal) - button.setTitleColor(.white, for: .normal) - button.backgroundColor = .themeColor200 - button.layer.cornerRadius = FrameResource.commonCornerRadius - - return button - }() + var openButton = ThemeButton(title: "열기") // MARK: - Lifecycle @@ -83,7 +74,6 @@ final class CapsuleOpenView: UIView, BaseView, UnOpenable { ) dateLabel.text = capsuleCellItem.closedDate.dateTimeString if !capsuleCellItem.isOpenable() { - openButton.backgroundColor = .themeGray200 openButton.isEnabled = false applyUnOpenableEffect() } diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseView.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseView.swift index ad1608b..0dbd252 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseView.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseView.swift @@ -17,7 +17,10 @@ final class CapsuleCloseView: UIView, BaseView, UnOpenable { let thumbnailImageURL: String } - var thumbnailImageView = ThemeThumbnailImageView(frame: .zero, width: UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio) + var thumbnailImageView = ThemeThumbnailImageView( + frame: .zero, + width: UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio + ) let blurEffectView = CapsuleBlurEffectView() @@ -41,15 +44,7 @@ final class CapsuleCloseView: UIView, BaseView, UnOpenable { return label }() - let closeButton = { - let button = UIButton() - button.titleLabel?.font = .themeFont(ofSize: FrameResource.fontSize100) - button.setTitle("완료", for: .normal) - button.setTitleColor(.white, for: .normal) - button.backgroundColor = .themeColor200 - button.layer.cornerRadius = FrameResource.commonCornerRadius - return button - }() + let closeButton = ThemeButton(title: "완료") // MARK: - Lifecycle diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleCreate/CapsuleLocate/CapsuleLocateView.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleCreate/CapsuleLocate/CapsuleLocateView.swift index 38ee33f..384de70 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleCreate/CapsuleLocate/CapsuleLocateView.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleCreate/CapsuleLocate/CapsuleLocateView.swift @@ -53,16 +53,7 @@ final class CapsuleLocateView: UIView, BaseView { let locationLabel = ThemeLabel(size: FrameResource.fontSize110, color: .themeGray400) - let doneButton: UIButton = { - let button = UIButton() - button.setTitle("완료", for: .normal) - button.titleLabel?.font = .themeFont(ofSize: FrameResource.fontSize100) - button.setTitleColor(.white, for: .normal) - button.backgroundColor = .themeColor200 - button.layer.cornerRadius = FrameResource.commonCornerRadius - - return button - }() + let doneButton = ThemeButton(title: "완료") // MARK: - Lifecycle diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleCreate/CapsuleLocate/CapsuleLocateViewController.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleCreate/CapsuleLocate/CapsuleLocateViewController.swift index 93a8af3..5209fb0 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleCreate/CapsuleLocate/CapsuleLocateViewController.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleCreate/CapsuleLocate/CapsuleLocateViewController.swift @@ -50,7 +50,6 @@ final class CapsuleLocateViewController: UIViewController, BaseViewController { .withUnretained(self) .subscribe(onNext: { owner, state in owner.mainView.doneButton.isEnabled = state - owner.mainView.doneButton.backgroundColor = state ? .themeColor200 : .themeGray200 }) .disposed(by: disposeBag) diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleCreate/DatePicker/DatePickerView.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleCreate/DatePicker/DatePickerView.swift index 618cc1a..58014b9 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleCreate/DatePicker/DatePickerView.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleCreate/DatePicker/DatePickerView.swift @@ -32,18 +32,9 @@ final class DatePickerView: UIView { return button }() - let doneButton: UIButton = { - let button = UIButton() - button.setTitle("완료", for: .normal) - button.titleLabel?.font = .themeFont(ofSize: FrameResource.fontSize100) - button.setTitleColor(.white, for: .normal) - button.backgroundColor = .themeColor200 - button.layer.cornerRadius = FrameResource.commonCornerRadius - - return button - }() - - let titleLabel = ThemeLabel(text: "추억 날짜 선택", size: FrameResource.fontSize120, color: .themeBlack) + let doneButton = ThemeButton(title: "완료") + + private let titleLabel = ThemeLabel(text: "추억 날짜 선택", size: FrameResource.fontSize120, color: .themeBlack) override init(frame: CGRect) { super.init(frame: frame) diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/Profile/ProfileViewController.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/Profile/ProfileViewController.swift index 92301c8..b921053 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/Profile/ProfileViewController.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/Profile/ProfileViewController.swift @@ -29,6 +29,7 @@ final class ProfileViewController: UIViewController, BaseViewController { var viewModel: ProfileViewModel? let profileView = ProfileView() fileprivate var currentNonce: String? + override func loadView() { view = profileView } From 43fd2fa264eaba45d8742cb692937689ff84d97f Mon Sep 17 00:00:00 2001 From: trumanfromkorea Date: Mon, 12 Dec 2022 22:31:06 +0900 Subject: [PATCH 2/6] =?UTF-8?q?[refactor]=20Capsule=20Thumbnail=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC=20=ED=9B=84=20CloseView=20=EC=A0=81=EC=9A=A9?= =?UTF-8?q?=20(#110)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SpaceCapsule.xcodeproj/project.pbxproj | 18 +- .../Components/BlurEffectView.swift | 4 +- .../Components/CapsuleThumbnailView.swift | 113 +++++++++ .../Components/Theme/ThemeButton.swift | 2 +- ...ageView.swift => ThumbnailImageView.swift} | 10 +- .../CapsuleOpen/CapsuleOpenView.swift | 13 +- .../CapsuleClose/CapsuleCloseView.swift | 217 +++++++++++------- .../CapsuleCloseViewController.swift | 6 +- .../Components/AddImageCell.swift | 1 + .../Components/ListCapsuleCell.swift | 10 +- .../CapsuleList/Components/UnOpenable.swift | 25 +- .../Home/Components/HomeCapsuleCell.swift | 10 +- 12 files changed, 303 insertions(+), 126 deletions(-) create mode 100644 SpaceCapsule/SpaceCapsule/Components/CapsuleThumbnailView.swift rename SpaceCapsule/SpaceCapsule/Components/Theme/{ThemeThumbnailImageView.swift => ThumbnailImageView.swift} (88%) diff --git a/SpaceCapsule/SpaceCapsule.xcodeproj/project.pbxproj b/SpaceCapsule/SpaceCapsule.xcodeproj/project.pbxproj index 3b87cab..3485fb9 100644 --- a/SpaceCapsule/SpaceCapsule.xcodeproj/project.pbxproj +++ b/SpaceCapsule/SpaceCapsule.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 0D1331C7293842D300B2CD28 /* Address.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D1331C6293842D300B2CD28 /* Address.swift */; }; 0D219825294730A600B7401B /* ThemeButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D219824294730A600B7401B /* ThemeButton.swift */; }; + 0D21982729473A2700B7401B /* CapsuleThumbnailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D21982629473A2700B7401B /* CapsuleThumbnailView.swift */; }; 0D46DEFA2923E1180045400A /* UIFont+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D46DEF92923E1180045400A /* UIFont+.swift */; }; 0D4C11372927489D00B1C2B6 /* UIViewPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D4C11362927489D00B1C2B6 /* UIViewPreview.swift */; }; 0D4C11392927495900B1C2B6 /* UIViewControllerPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D4C11382927495900B1C2B6 /* UIViewControllerPreview.swift */; }; @@ -171,7 +172,7 @@ 59D8CFB52935FDAC00FD9CF6 /* CarouselCollectionViewFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59D8CFB42935FDAC00FD9CF6 /* CarouselCollectionViewFlowLayout.swift */; }; 59D8CFB8293609D100FD9CF6 /* HomeCapsuleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59D8CFB7293609D100FD9CF6 /* HomeCapsuleCell.swift */; }; 59D8CFBA293609E000FD9CF6 /* HomeCapsuleCellItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59D8CFB9293609E000FD9CF6 /* HomeCapsuleCellItem.swift */; }; - 59D8CFBC29360A8900FD9CF6 /* ThemeThumbnailImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59D8CFBB29360A8900FD9CF6 /* ThemeThumbnailImageView.swift */; }; + 59D8CFBC29360A8900FD9CF6 /* ThumbnailImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59D8CFBB29360A8900FD9CF6 /* ThumbnailImageView.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -194,6 +195,7 @@ /* Begin PBXFileReference section */ 0D1331C6293842D300B2CD28 /* Address.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Address.swift; sourceTree = ""; }; 0D219824294730A600B7401B /* ThemeButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeButton.swift; sourceTree = ""; }; + 0D21982629473A2700B7401B /* CapsuleThumbnailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapsuleThumbnailView.swift; sourceTree = ""; }; 0D2B7AB92934594400CE34E3 /* running.gpx */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = running.gpx; sourceTree = ""; }; 0D46DEF92923E1180045400A /* UIFont+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFont+.swift"; sourceTree = ""; }; 0D4C11362927489D00B1C2B6 /* UIViewPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewPreview.swift; sourceTree = ""; }; @@ -352,7 +354,7 @@ 59D8CFB42935FDAC00FD9CF6 /* CarouselCollectionViewFlowLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CarouselCollectionViewFlowLayout.swift; sourceTree = ""; }; 59D8CFB7293609D100FD9CF6 /* HomeCapsuleCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeCapsuleCell.swift; sourceTree = ""; }; 59D8CFB9293609E000FD9CF6 /* HomeCapsuleCellItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeCapsuleCellItem.swift; sourceTree = ""; }; - 59D8CFBB29360A8900FD9CF6 /* ThemeThumbnailImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeThumbnailImageView.swift; sourceTree = ""; }; + 59D8CFBB29360A8900FD9CF6 /* ThumbnailImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThumbnailImageView.swift; sourceTree = ""; }; 59F567F72923BE1E00F756B2 /* SpaceCapsule.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SpaceCapsule.entitlements; sourceTree = ""; }; /* End PBXFileReference section */ @@ -402,6 +404,7 @@ 4A1D1BC52941F3C500F47ACB /* BlurEffectView.swift */, 0D9A834C293788A300D00303 /* Map */, 0DCB22942924CE61002CB095 /* Theme */, + 0D21982629473A2700B7401B /* CapsuleThumbnailView.swift */, ); path = Components; sourceTree = ""; @@ -552,12 +555,12 @@ 0DCB22942924CE61002CB095 /* Theme */ = { isa = PBXGroup; children = ( - 59D8CFBB29360A8900FD9CF6 /* ThemeThumbnailImageView.swift */, - 0D9D672D292486780038F529 /* ThemeLabel.swift */, + 2885A9FF293B6466003E5311 /* ProfileButton.swift */, + 0D77D7C8292B5D490038D054 /* SelectButton.swift */, 0D219824294730A600B7401B /* ThemeButton.swift */, + 0D9D672D292486780038F529 /* ThemeLabel.swift */, 0DA6610C292778BE00CF3563 /* ThemeTextField.swift */, - 0D77D7C8292B5D490038D054 /* SelectButton.swift */, - 2885A9FF293B6466003E5311 /* ProfileButton.swift */, + 59D8CFBB29360A8900FD9CF6 /* ThumbnailImageView.swift */, ); path = Theme; sourceTree = ""; @@ -1207,7 +1210,7 @@ 0DFF50DD29402E3100079FA6 /* EmptyView.swift in Sources */, 28A700D52938AE100049FAF8 /* AnimationResource.swift in Sources */, 288A8EE229235E3F000229D2 /* CapsuleLocateViewModel.swift in Sources */, - 59D8CFBC29360A8900FD9CF6 /* ThemeThumbnailImageView.swift in Sources */, + 59D8CFBC29360A8900FD9CF6 /* ThumbnailImageView.swift in Sources */, 0D752DB32944A964004A704C /* UIImage+resize.swift in Sources */, 0D4C11372927489D00B1C2B6 /* UIViewPreview.swift in Sources */, 288A8EB229235B5A000229D2 /* ProfileView.swift in Sources */, @@ -1226,6 +1229,7 @@ 0DFF50E3294067E600079FA6 /* UIControl+Rx.swift in Sources */, 288A8EA729235AF1000229D2 /* NicknameViewModel.swift in Sources */, 28245562293B17B100DE03A1 /* UnOpenable.swift in Sources */, + 0D21982729473A2700B7401B /* CapsuleThumbnailView.swift in Sources */, 0D219825294730A600B7401B /* ThemeButton.swift in Sources */, 4A1D1BC3294033C200F47ACB /* CapsuleSettingsView.swift in Sources */, 288A8ECC29235BE9000229D2 /* HomeViewController.swift in Sources */, diff --git a/SpaceCapsule/SpaceCapsule/Components/BlurEffectView.swift b/SpaceCapsule/SpaceCapsule/Components/BlurEffectView.swift index 79a58db..a6bf992 100644 --- a/SpaceCapsule/SpaceCapsule/Components/BlurEffectView.swift +++ b/SpaceCapsule/SpaceCapsule/Components/BlurEffectView.swift @@ -8,9 +8,9 @@ import UIKit final class CapsuleBlurEffectView: UIVisualEffectView { - init() { + init(width: CGFloat) { super.init(effect: UIBlurEffect(style: .systemUltraThinMaterialDark)) - self.layer.cornerRadius = FrameResource.listCapsuleCellWidth / 2 + self.layer.cornerRadius = width / 2 self.clipsToBounds = true } diff --git a/SpaceCapsule/SpaceCapsule/Components/CapsuleThumbnailView.swift b/SpaceCapsule/SpaceCapsule/Components/CapsuleThumbnailView.swift new file mode 100644 index 0000000..fa5698b --- /dev/null +++ b/SpaceCapsule/SpaceCapsule/Components/CapsuleThumbnailView.swift @@ -0,0 +1,113 @@ +// +// CapsuleOpenCloseView.swift +// SpaceCapsule +// +// Created by 장재훈 on 2022/12/12. +// + +import AVFoundation +import SnapKit +import UIKit + +class CapsuleThumbnailView: UIView { + struct Item { + let thumbnailImageURL: String + let closedDateString: String + let memoryDateString: String + let simpleAddress: String + } + + let thumbnailImageView = ThumbnailImageView( + frame: .zero, + width: UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio + ) + + let descriptionLabel = { + let label = ThemeLabel(size: FrameResource.fontSize140, color: .themeGray300) + label.numberOfLines = 3 + label.textAlignment = .center + + return label + }() + + let bottomButton = ThemeButton(title: " ") + + // MARK: - Lifecycle + + override init(frame: CGRect) { + super.init(frame: frame) + + configure() + addSubViews() + makeConstraints() + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - Methods + + func configure() { + backgroundColor = .themeBackground + } + + func configure(item: Item) { + descriptionLabel.asFontColor( + targetStringList: [item.memoryDateString, item.simpleAddress], + size: FrameResource.fontSize140, + color: .themeGray400 + ) + + thumbnailImageView.imageView.kr.setImage( + with: item.thumbnailImageURL, + placeholder: .empty, + scale: FrameResource.closedImageScale + ) + } + + func addSubViews() { + [thumbnailImageView, descriptionLabel, bottomButton].forEach { + addSubview($0) + } + } + + func makeConstraints() { + thumbnailImageView.snp.makeConstraints { + $0.centerX.equalToSuperview() + $0.centerY.equalToSuperview().multipliedBy(AnimationResource.fromOriginY) + $0.width.equalTo(UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio) + $0.height.equalTo(UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio * FrameResource.capsuleThumbnailHWRatio) + } + + descriptionLabel.snp.makeConstraints { + $0.centerX.equalToSuperview() + $0.top.equalTo(self.snp.centerY).multipliedBy(0.7) + .offset(FrameResource.capsuleThumbnailHeight / 2 + AnimationResource.capsuleMoveHeight) + $0.bottom.equalTo(bottomButton.snp.top).offset(-FrameResource.spacing200).priority(999) + } + + bottomButton.snp.makeConstraints { + $0.leading.equalToSuperview().offset(FrameResource.horizontalPadding) + $0.trailing.equalToSuperview().offset(-FrameResource.horizontalPadding) + $0.bottom.equalTo(safeAreaLayoutGuide.snp.bottom).offset(-FrameResource.spacing200) + $0.height.equalTo(FrameResource.buttonHeight) + } + } + + func animate() { + UIView.animate(withDuration: AnimationResource.capsuleMoveDuration, animations: { + self.layoutIfNeeded() + self.thumbnailImageView.center.y = (self.frame.height * AnimationResource.destinationHeightRatio) + }, completion: { _ in + UIView.animate( + withDuration: AnimationResource.capsuleMoveDuration, + delay: 0, + options: [.repeat, .autoreverse] + ) { + self.thumbnailImageView.transform = .init(translationX: 0, y: AnimationResource.capsuleMoveHeight) + } + }) + } +} diff --git a/SpaceCapsule/SpaceCapsule/Components/Theme/ThemeButton.swift b/SpaceCapsule/SpaceCapsule/Components/Theme/ThemeButton.swift index 8e67c10..366d749 100644 --- a/SpaceCapsule/SpaceCapsule/Components/Theme/ThemeButton.swift +++ b/SpaceCapsule/SpaceCapsule/Components/Theme/ThemeButton.swift @@ -14,7 +14,7 @@ final class ThemeButton: UIButton { } } - convenience init(title: String) { + convenience init(title: String = "") { self.init() setTitle(title, for: .normal) diff --git a/SpaceCapsule/SpaceCapsule/Components/Theme/ThemeThumbnailImageView.swift b/SpaceCapsule/SpaceCapsule/Components/Theme/ThumbnailImageView.swift similarity index 88% rename from SpaceCapsule/SpaceCapsule/Components/Theme/ThemeThumbnailImageView.swift rename to SpaceCapsule/SpaceCapsule/Components/Theme/ThumbnailImageView.swift index 0cc6509..b1d1660 100644 --- a/SpaceCapsule/SpaceCapsule/Components/Theme/ThemeThumbnailImageView.swift +++ b/SpaceCapsule/SpaceCapsule/Components/Theme/ThumbnailImageView.swift @@ -7,7 +7,7 @@ import UIKit -final class ThemeThumbnailImageView: UIView { +final class ThumbnailImageView: UIView { // MARK: - Properties let width: CGFloat @@ -20,6 +20,7 @@ final class ThemeThumbnailImageView: UIView { imageView.clipsToBounds = true imageView.backgroundColor = .white imageView.contentMode = .scaleAspectFill + return imageView }() @@ -27,6 +28,7 @@ final class ThemeThumbnailImageView: UIView { init(frame: CGRect, width: CGFloat) { self.width = width + print(width) super.init(frame: frame) configure() addSubViews() @@ -40,7 +42,7 @@ final class ThemeThumbnailImageView: UIView { // MARK: - Methods - func configure() { + private func configure() { backgroundColor = .themeGray100 layer.shadowOffset = FrameResource.capsuleCellShadowOffset layer.shadowRadius = FrameResource.capsuleCellShadowRadius @@ -48,13 +50,13 @@ final class ThemeThumbnailImageView: UIView { layer.cornerRadius = width / 2 } - func addSubViews() { + private func addSubViews() { [imageView].forEach { addSubview($0) } } - func makeConstraints() { + private func makeConstraints() { imageView.snp.makeConstraints { $0.edges.equalToSuperview() } diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenView.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenView.swift index 42038a8..a1549e5 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenView.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenView.swift @@ -10,7 +10,10 @@ import SnapKit import UIKit final class CapsuleOpenView: UIView, BaseView, UnOpenable { - var thumbnailImageView = ThemeThumbnailImageView(frame: .zero, width: UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio) + var thumbnailImageView = ThumbnailImageView( + frame: .zero, + width: UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio + ) var descriptionLabel = { let label = ThemeLabel(text: nil, size: FrameResource.fontSize140, color: .themeGray300) @@ -19,7 +22,7 @@ final class CapsuleOpenView: UIView, BaseView, UnOpenable { return label }() - let blurEffectView = CapsuleBlurEffectView() + let blurEffectView = CapsuleBlurEffectView(width: UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio) var lockImageView = { let lockImageView = UIImageView() @@ -28,7 +31,7 @@ final class CapsuleOpenView: UIView, BaseView, UnOpenable { return lockImageView }() - var dateLabel = { + var closedDateLabel = { let dateLabel = ThemeLabel(text: nil, size: FrameResource.fontSize80, color: .themeGray200) dateLabel.textAlignment = .center return dateLabel @@ -72,10 +75,10 @@ final class CapsuleOpenView: UIView, BaseView, UnOpenable { size: FrameResource.fontSize140, color: .themeGray400 ) - dateLabel.text = capsuleCellItem.closedDate.dateTimeString + closedDateLabel.text = capsuleCellItem.closedDate.dateTimeString if !capsuleCellItem.isOpenable() { openButton.isEnabled = false - applyUnOpenableEffect() +// applyUnOpenableEffect() } } diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseView.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseView.swift index 0dbd252..5c8b5a3 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseView.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseView.swift @@ -9,20 +9,8 @@ import AVFoundation import SnapKit import UIKit -final class CapsuleCloseView: UIView, BaseView, UnOpenable { - struct Item { - let closedDateString: String - let memoryDateString: String - let simpleAddress: String - let thumbnailImageURL: String - } - - var thumbnailImageView = ThemeThumbnailImageView( - frame: .zero, - width: UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio - ) - - let blurEffectView = CapsuleBlurEffectView() +final class CapsuleCloseView: CapsuleThumbnailView, BaseView, UnOpenable { + let blurEffectView = CapsuleBlurEffectView(width: UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio) var lockImageView = { let lockImageView = UIImageView() @@ -31,21 +19,14 @@ final class CapsuleCloseView: UIView, BaseView, UnOpenable { return lockImageView }() - var dateLabel = { - let dateLabel = ThemeLabel(text: nil, size: FrameResource.fontSize80, color: .themeGray200) + var closedDateLabel = { + let dateLabel = ThemeLabel(size: FrameResource.fontSize80, color: .themeGray200) dateLabel.textAlignment = .center + dateLabel.numberOfLines = 0 + return dateLabel }() - var descriptionLabel = { - let label = ThemeLabel(size: FrameResource.fontSize140, color: .themeGray300) - label.numberOfLines = 3 - label.textAlignment = .center - return label - }() - - let closeButton = ThemeButton(title: "완료") - // MARK: - Lifecycle override init(frame: CGRect) { @@ -62,70 +43,140 @@ final class CapsuleCloseView: UIView, BaseView, UnOpenable { // MARK: - Methods - func configure() { - backgroundColor = .themeBackground - } - - func configure(item: Item) { - dateLabel.text = "밀봉시간: \(item.closedDateString)" - + override func configure(item: Item) { + bottomButton.setTitle("완료", for: .normal) + descriptionLabel.text = """ \(item.memoryDateString) \(item.simpleAddress) 에서의 추억이 담긴 캡슐을 보관하였습니다. """ + + closedDateLabel.text = "밀봉시간 \(item.closedDateString)" - descriptionLabel.asFontColor( - targetStringList: [item.memoryDateString, item.simpleAddress], - size: FrameResource.fontSize140, - color: .themeGray400 - ) - - thumbnailImageView.imageView.kr.setImage(with: item.thumbnailImageURL, placeholder: .empty, scale: FrameResource.closedImageScale) + applyUnopenableEffect(superview: thumbnailImageView) - applyUnOpenableEffect() - } - - func addSubViews() { - [thumbnailImageView, descriptionLabel, closeButton].forEach { - addSubview($0) - } - } - - func makeConstraints() { - thumbnailImageView.snp.makeConstraints { - $0.centerX.equalToSuperview() - $0.centerY.equalToSuperview().multipliedBy(AnimationResource.fromOriginY) - $0.width.equalTo(UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio) - $0.height.equalTo(UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio * FrameResource.capsuleThumbnailHWRatio) - } - - descriptionLabel.snp.makeConstraints { - $0.centerX.equalToSuperview() - $0.top.equalTo(self.snp.centerY).multipliedBy(0.7) - .offset(FrameResource.capsuleThumbnailHeight / 2 + AnimationResource.capsuleMoveHeight) - $0.bottom.equalTo(closeButton.snp.top).offset(-FrameResource.spacing200).priority(999) - } - - closeButton.snp.makeConstraints { - $0.leading.equalToSuperview().offset(FrameResource.horizontalPadding) - $0.trailing.equalToSuperview().offset(-FrameResource.horizontalPadding) - $0.bottom.equalTo(safeAreaLayoutGuide.snp.bottom).offset(-FrameResource.spacing200) - $0.height.equalTo(FrameResource.buttonHeight) - } - } - - func animate() { - UIView.animate(withDuration: AnimationResource.capsuleMoveDuration, animations: { - self.layoutIfNeeded() - self.thumbnailImageView.center.y = (self.frame.height * AnimationResource.destinationHeightRatio) - }, completion: { _ in - UIView.animate(withDuration: AnimationResource.capsuleMoveDuration, - delay: 0, - options: [.repeat, .autoreverse] - ) { - self.thumbnailImageView.transform = .init(translationX: 0, y: AnimationResource.capsuleMoveHeight) - } - }) + super.configure(item: item) } } + +// final class CapsuleCloseView: UIView, BaseView, UnOpenable { +// struct Item { +// let closedDateString: String +// let memoryDateString: String +// let simpleAddress: String +// let thumbnailImageURL: String +// } +// +// var thumbnailImageView = ThumbnailImageView( +// frame: .zero, +// width: UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio +// ) +// +// let blurEffectView = CapsuleBlurEffectView() +// +// var lockImageView = { +// let lockImageView = UIImageView() +// lockImageView.image = .lock +// lockImageView.tintColor = .themeGray200 +// return lockImageView +// }() +// +// var closedDateLabel = { +// let dateLabel = ThemeLabel(text: nil, size: FrameResource.fontSize80, color: .themeGray200) +// dateLabel.textAlignment = .center +// return dateLabel +// }() +// +// var descriptionLabel = { +// let label = ThemeLabel(size: FrameResource.fontSize140, color: .themeGray300) +// label.numberOfLines = 3 +// label.textAlignment = .center +// return label +// }() +// +// let closeButton = ThemeButton(title: "완료") +// +// // MARK: - Lifecycle +// +// override init(frame: CGRect) { +// super.init(frame: frame) +// configure() +// addSubViews() +// makeConstraints() +// } +// +// @available(*, unavailable) +// required init?(coder: NSCoder) { +// fatalError("init(coder:) has not been implemented") +// } +// +// // MARK: - Methods +// +// func configure() { +// backgroundColor = .themeBackground +// } +// +// func configure(item: Item) { +// closedDateLabel.text = "밀봉시간: \(item.closedDateString)" +// +// descriptionLabel.text = """ +// \(item.memoryDateString) +// \(item.simpleAddress) 에서의 +// 추억이 담긴 캡슐을 보관하였습니다. +// """ +// +// descriptionLabel.asFontColor( +// targetStringList: [item.memoryDateString, item.simpleAddress], +// size: FrameResource.fontSize140, +// color: .themeGray400 +// ) +// +// thumbnailImageView.imageView.kr.setImage(with: item.thumbnailImageURL, placeholder: .empty, scale: FrameResource.closedImageScale) +// +// applyUnOpenableEffect() +// } +// +// func addSubViews() { +// [thumbnailImageView, descriptionLabel, closeButton].forEach { +// addSubview($0) +// } +// } +// +// func makeConstraints() { +// thumbnailImageView.snp.makeConstraints { +// $0.centerX.equalToSuperview() +// $0.centerY.equalToSuperview().multipliedBy(AnimationResource.fromOriginY) +// $0.width.equalTo(UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio) +// $0.height.equalTo(UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio * FrameResource.capsuleThumbnailHWRatio) +// } +// +// descriptionLabel.snp.makeConstraints { +// $0.centerX.equalToSuperview() +// $0.top.equalTo(self.snp.centerY).multipliedBy(0.7) +// .offset(FrameResource.capsuleThumbnailHeight / 2 + AnimationResource.capsuleMoveHeight) +// $0.bottom.equalTo(closeButton.snp.top).offset(-FrameResource.spacing200).priority(999) +// } +// +// closeButton.snp.makeConstraints { +// $0.leading.equalToSuperview().offset(FrameResource.horizontalPadding) +// $0.trailing.equalToSuperview().offset(-FrameResource.horizontalPadding) +// $0.bottom.equalTo(safeAreaLayoutGuide.snp.bottom).offset(-FrameResource.spacing200) +// $0.height.equalTo(FrameResource.buttonHeight) +// } +// } +// +// func animate() { +// UIView.animate(withDuration: AnimationResource.capsuleMoveDuration, animations: { +// self.layoutIfNeeded() +// self.thumbnailImageView.center.y = (self.frame.height * AnimationResource.destinationHeightRatio) +// }, completion: { _ in +// UIView.animate(withDuration: AnimationResource.capsuleMoveDuration, +// delay: 0, +// options: [.repeat, .autoreverse] +// ) { +// self.thumbnailImageView.transform = .init(translationX: 0, y: AnimationResource.capsuleMoveHeight) +// } +// }) +// } +// } diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseViewController.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseViewController.swift index cbab39b..d4ed364 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseViewController.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseViewController.swift @@ -30,7 +30,7 @@ final class CapsuleCloseViewController: UIViewController, BaseViewController { } func bind() { - mainView.closeButton.rx.tap + mainView.bottomButton.rx.tap .withUnretained(self) .bind(onNext: { owner, _ in owner.viewModel?.input.tapClose.onNext(()) @@ -43,10 +43,10 @@ final class CapsuleCloseViewController: UIViewController, BaseViewController { .subscribe(onNext: { owner, capsule in owner.mainView.configure(item: CapsuleCloseView.Item( + thumbnailImageURL: capsule.images[safe: 0] ?? "", closedDateString: capsule.closedDate.dateTimeString, memoryDateString: capsule.memoryDate.dateString, - simpleAddress: capsule.simpleAddress, - thumbnailImageURL: capsule.images[safe: 0] ?? "" + simpleAddress: capsule.simpleAddress ) ) }) diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleCreate/Components/AddImageCell.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleCreate/Components/AddImageCell.swift index f536e71..96ced61 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleCreate/Components/AddImageCell.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleCreate/Components/AddImageCell.swift @@ -12,6 +12,7 @@ final class AddImageCell: UICollectionViewCell { let imageView: UIImageView = { let imageView = UIImageView() imageView.contentMode = .scaleAspectFill + imageView.clipsToBounds = true return imageView }() diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCell.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCell.swift index 2964ceb..3dac7a7 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCell.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCell.swift @@ -9,7 +9,7 @@ import SnapKit import UIKit final class ListCapsuleCell: UICollectionViewCell, UnOpenable { - lazy var thumbnailImageView = ThemeThumbnailImageView(frame: .zero, width: FrameResource.listCapsuleCellWidth) + lazy var thumbnailImageView = ThumbnailImageView(frame: .zero, width: FrameResource.listCapsuleCellWidth) lazy var descriptionLabel = { let label = ThemeLabel(text: nil, size: FrameResource.fontSize80, color: .themeBlack) @@ -18,7 +18,7 @@ final class ListCapsuleCell: UICollectionViewCell, UnOpenable { return label }() - var blurEffectView = CapsuleBlurEffectView() + var blurEffectView = CapsuleBlurEffectView(width: FrameResource.listCapsuleCellWidth) lazy var lockImageView = { let lockImageView = UIImageView() @@ -27,7 +27,7 @@ final class ListCapsuleCell: UICollectionViewCell, UnOpenable { return lockImageView }() - lazy var dateLabel = { + lazy var closedDateLabel = { let dateLabel = ThemeLabel(text: nil, size: FrameResource.fontSize80, color: .themeGray200) dateLabel.textAlignment = .center return dateLabel @@ -77,9 +77,9 @@ final class ListCapsuleCell: UICollectionViewCell, UnOpenable { thumbnailImageView.imageView.kr.setImage(with: thumbnailURL, placeholder: .empty, scale: FrameResource.openableImageScale) } descriptionLabel.text = "\(capsuleCellItem.memoryDate.dateString)\n\(capsuleCellItem.address)에서" - dateLabel.text = "밀봉시간:\(capsuleCellItem.closedDate.dateString)" + closedDateLabel.text = "밀봉시간:\(capsuleCellItem.closedDate.dateString)" if !capsuleCellItem.isOpenable() { - applyUnOpenableEffect() +// applyUnOpenableEffect() } } } diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/UnOpenable.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/UnOpenable.swift index 8f21f2c..7045967 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/UnOpenable.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/UnOpenable.swift @@ -9,32 +9,35 @@ import SnapKit import UIKit protocol UnOpenable: UIView { - var thumbnailImageView: ThemeThumbnailImageView { get } +// var thumbnailImageView: ThumbnailImageView { get } var blurEffectView: CapsuleBlurEffectView { get } var lockImageView: UIImageView { get } - var dateLabel: ThemeLabel {get} - func applyUnOpenableEffect() + var closedDateLabel: ThemeLabel { get } + +// func applyUnOpenableEffect() + func applyUnopenableEffect(superview: UIView) } extension UnOpenable { - func applyUnOpenableEffect() { - [blurEffectView, lockImageView, dateLabel].forEach { [weak self] in - self?.thumbnailImageView.imageView.addSubview($0) + func applyUnopenableEffect(superview: UIView) { + [blurEffectView, lockImageView, closedDateLabel].forEach { + superview.addSubview($0) } - + blurEffectView.snp.makeConstraints { $0.center.equalToSuperview() $0.width.height.equalToSuperview() } - + lockImageView.snp.makeConstraints { $0.center.equalToSuperview() - $0.width.height.equalTo(thumbnailImageView.snp.width).multipliedBy(0.3) + $0.width.height.equalTo(superview.snp.width).multipliedBy(0.3) } - - dateLabel.snp.makeConstraints { + + closedDateLabel.snp.makeConstraints { $0.centerX.equalToSuperview() $0.top.equalTo(lockImageView.snp.bottom).offset(FrameResource.verticalPadding) } } + } diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/Components/HomeCapsuleCell.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/Components/HomeCapsuleCell.swift index ede5a25..abcdde0 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/Components/HomeCapsuleCell.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/Components/HomeCapsuleCell.swift @@ -11,7 +11,7 @@ import UIKit final class HomeCapsuleCell: UICollectionViewCell, UnOpenable { var uuid: String? - var thumbnailImageView = ThemeThumbnailImageView(frame: .zero, width: FrameResource.homeCapsuleCellWidth) + var thumbnailImageView = ThumbnailImageView(frame: .zero, width: FrameResource.homeCapsuleCellWidth) var titleLabel = { let label = ThemeLabel(text: "가장 오래된 캡슐", size: FrameResource.fontSize120, color: .themeColor200) @@ -27,13 +27,13 @@ final class HomeCapsuleCell: UICollectionViewCell, UnOpenable { return label }() - var dateLabel = { + var closedDateLabel = { let dateLabel = ThemeLabel(text: nil, size: FrameResource.fontSize100, color: .themeGray200) dateLabel.textAlignment = .center return dateLabel }() - var blurEffectView = CapsuleBlurEffectView() + var blurEffectView = CapsuleBlurEffectView(width: FrameResource.homeCapsuleCellWidth) var lockImageView = { let lockImageView = UIImageView() @@ -92,12 +92,12 @@ final class HomeCapsuleCell: UICollectionViewCell, UnOpenable { if let thumbnailURL = capsuleCellModel.thumbnailImageURL { thumbnailImageView.imageView.kr.setImage(with: thumbnailURL, placeholder: .empty, scale: FrameResource.openableImageScale) } - dateLabel.text = "밀봉시간:\(capsuleCellModel.closedDate.dateString)" + closedDateLabel.text = "밀봉시간:\(capsuleCellModel.closedDate.dateString)" titleLabel.text = capsuleCellModel.type.title descriptionLabel.text = capsuleCellModel.description() if !capsuleCellModel.isOpenable() { - applyUnOpenableEffect() +// applyUnOpenableEffect() } } } From e9386f7429d8d2eea584b620b7bc79e9349ec512 Mon Sep 17 00:00:00 2001 From: trumanfromkorea Date: Thu, 15 Dec 2022 13:46:34 +0900 Subject: [PATCH 3/6] =?UTF-8?q?[refactor]=20=EC=BA=A1=EC=8A=90=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20OpenView=20=EC=A0=81=EC=9A=A9=20(?= =?UTF-8?q?#110)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CapsuleOpen/CapsuleOpenView.swift | 97 +++----------- .../CapsuleOpenViewController.swift | 15 ++- .../CapsuleClose/CapsuleCloseView.swift | 122 ------------------ 3 files changed, 31 insertions(+), 203 deletions(-) diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenView.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenView.swift index a1549e5..adc517c 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenView.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenView.swift @@ -9,19 +9,7 @@ import AVFoundation import SnapKit import UIKit -final class CapsuleOpenView: UIView, BaseView, UnOpenable { - var thumbnailImageView = ThumbnailImageView( - frame: .zero, - width: UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio - ) - - var descriptionLabel = { - let label = ThemeLabel(text: nil, size: FrameResource.fontSize140, color: .themeGray300) - label.numberOfLines = 3 - label.textAlignment = .center - return label - }() - +final class CapsuleOpenView: CapsuleThumbnailView, BaseView, UnOpenable { let blurEffectView = CapsuleBlurEffectView(width: UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio) var lockImageView = { @@ -32,18 +20,17 @@ final class CapsuleOpenView: UIView, BaseView, UnOpenable { }() var closedDateLabel = { - let dateLabel = ThemeLabel(text: nil, size: FrameResource.fontSize80, color: .themeGray200) + let dateLabel = ThemeLabel(size: FrameResource.fontSize80, color: .themeGray200) dateLabel.textAlignment = .center + dateLabel.numberOfLines = 0 + return dateLabel }() - var openButton = ThemeButton(title: "열기") - // MARK: - Lifecycle override init(frame: CGRect) { super.init(frame: frame) - configure() addSubViews() makeConstraints() @@ -56,90 +43,44 @@ final class CapsuleOpenView: UIView, BaseView, UnOpenable { // MARK: - Methods - func configure() { - backgroundColor = .themeBackground - } - - func configure(capsuleCellItem: ListCapsuleCellItem) { - if let thumbnailURL = capsuleCellItem.thumbnailImageURL { - thumbnailImageView.imageView.kr.setImage(with: thumbnailURL, placeholder: .empty, scale: FrameResource.openableImageScale) - } + func configure(item: Item, isOpenable: Bool) { + bottomButton.setTitle("열기", for: .normal) descriptionLabel.text = """ - \(capsuleCellItem.memoryDate.dateString) - \(capsuleCellItem.address) 에서의 - 추억을 담은 캡슐 + \(item.memoryDateString) + \(item.simpleAddress) 에서의 + 추억이 담긴 캡슐을 보관하였습니다. """ - descriptionLabel.asFontColor( - targetStringList: [capsuleCellItem.memoryDate.dateString, capsuleCellItem.address], - size: FrameResource.fontSize140, - color: .themeGray400 - ) - closedDateLabel.text = capsuleCellItem.closedDate.dateTimeString - if !capsuleCellItem.isOpenable() { - openButton.isEnabled = false -// applyUnOpenableEffect() - } - } - func addSubViews() { - [thumbnailImageView, descriptionLabel, openButton].forEach { - addSubview($0) - } - } - - func makeConstraints() { - thumbnailImageView.snp.makeConstraints { - $0.centerX.equalToSuperview() - $0.centerY.equalToSuperview().multipliedBy(AnimationResource.fromOriginY) - $0.width.equalTo(UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio) - $0.height.equalTo(UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio * FrameResource.capsuleThumbnailHWRatio) - } + closedDateLabel.text = "밀봉시간 \(item.closedDateString)" - descriptionLabel.snp.makeConstraints { - $0.centerX.equalToSuperview() - $0.top.equalTo(self.snp.centerY).multipliedBy(0.7) - .offset(FrameResource.capsuleThumbnailHeight / 2 + AnimationResource.capsuleMoveHeight) - $0.bottom.equalTo(openButton.snp.top).offset(-FrameResource.spacing200).priority(999) + if !isOpenable { + applyUnopenableEffect(superview: thumbnailImageView) } - openButton.snp.makeConstraints { - $0.leading.equalToSuperview().offset(FrameResource.horizontalPadding) - $0.trailing.equalToSuperview().offset(-FrameResource.horizontalPadding) - $0.bottom.equalTo(safeAreaLayoutGuide.snp.bottom).offset(-FrameResource.spacing200) - $0.height.equalTo(FrameResource.buttonHeight) - } - } - - func animate() { - UIView.animate(withDuration: AnimationResource.capsuleMoveDuration, animations: { - self.layoutIfNeeded() - self.thumbnailImageView.center.y = (self.frame.height * AnimationResource.destinationHeightRatio) - }, completion: { _ in - UIView.animate(withDuration: AnimationResource.capsuleMoveDuration, - delay: 0, - options: [.repeat, .autoreverse] - ) { - self.thumbnailImageView.transform = .init(translationX: 0, y: AnimationResource.capsuleMoveHeight) - } - }) + super.configure(item: item) } func shakeAnimate() { AudioServicesPlaySystemSound(kSystemSoundID_Vibrate) - let keyPath = "shake" + + let keyPath = "position" + let animation = CABasicAnimation(keyPath: keyPath) animation.duration = AnimationResource.capsuleShakeDuration animation.repeatCount = AnimationResource.capsuleShakeRepeat animation.autoreverses = true + animation.fromValue = CGPoint( x: thumbnailImageView.center.x - AnimationResource.capsuleShakeWidth, y: thumbnailImageView.center.y ) + animation.toValue = CGPoint( x: thumbnailImageView.center.x + AnimationResource.capsuleShakeWidth, y: thumbnailImageView.center.y ) + thumbnailImageView.layer.add(animation, forKey: keyPath) } } diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenViewController.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenViewController.swift index afb4a79..6bc3040 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenViewController.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenViewController.swift @@ -17,8 +17,17 @@ final class CapsuleOpenViewController: UIViewController, BaseViewController { override func viewDidLoad() { super.viewDidLoad() view = capsuleOpenView - if let capsuleCellItem = viewModel?.capsuleCellItem { - capsuleOpenView.configure(capsuleCellItem: capsuleCellItem) + if let item = viewModel?.capsuleCellItem { +// capsuleOpenView.configure(capsuleCellItem: capsuleCellItem) + capsuleOpenView.configure( + item: CapsuleThumbnailView.Item( + thumbnailImageURL: item.thumbnailImageURL ?? "", + closedDateString: item.closedDate.dateTimeString, + memoryDateString: item.memoryDate.dateString, + simpleAddress: item.address + ), + isOpenable: item.isOpenable() + ) } bind() } @@ -39,7 +48,7 @@ final class CapsuleOpenViewController: UIViewController, BaseViewController { } func bind() { - capsuleOpenView.openButton.rx.tap + capsuleOpenView.bottomButton.rx.tap .withUnretained(self) .bind { owner, _ in owner.handleOpenButtonTap() diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseView.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseView.swift index 5c8b5a3..51ceaf5 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseView.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseView.swift @@ -5,7 +5,6 @@ // Created by young june Park on 2022/11/15. // -import AVFoundation import SnapKit import UIKit @@ -59,124 +58,3 @@ final class CapsuleCloseView: CapsuleThumbnailView, BaseView, UnOpenable { super.configure(item: item) } } - -// final class CapsuleCloseView: UIView, BaseView, UnOpenable { -// struct Item { -// let closedDateString: String -// let memoryDateString: String -// let simpleAddress: String -// let thumbnailImageURL: String -// } -// -// var thumbnailImageView = ThumbnailImageView( -// frame: .zero, -// width: UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio -// ) -// -// let blurEffectView = CapsuleBlurEffectView() -// -// var lockImageView = { -// let lockImageView = UIImageView() -// lockImageView.image = .lock -// lockImageView.tintColor = .themeGray200 -// return lockImageView -// }() -// -// var closedDateLabel = { -// let dateLabel = ThemeLabel(text: nil, size: FrameResource.fontSize80, color: .themeGray200) -// dateLabel.textAlignment = .center -// return dateLabel -// }() -// -// var descriptionLabel = { -// let label = ThemeLabel(size: FrameResource.fontSize140, color: .themeGray300) -// label.numberOfLines = 3 -// label.textAlignment = .center -// return label -// }() -// -// let closeButton = ThemeButton(title: "완료") -// -// // MARK: - Lifecycle -// -// override init(frame: CGRect) { -// super.init(frame: frame) -// configure() -// addSubViews() -// makeConstraints() -// } -// -// @available(*, unavailable) -// required init?(coder: NSCoder) { -// fatalError("init(coder:) has not been implemented") -// } -// -// // MARK: - Methods -// -// func configure() { -// backgroundColor = .themeBackground -// } -// -// func configure(item: Item) { -// closedDateLabel.text = "밀봉시간: \(item.closedDateString)" -// -// descriptionLabel.text = """ -// \(item.memoryDateString) -// \(item.simpleAddress) 에서의 -// 추억이 담긴 캡슐을 보관하였습니다. -// """ -// -// descriptionLabel.asFontColor( -// targetStringList: [item.memoryDateString, item.simpleAddress], -// size: FrameResource.fontSize140, -// color: .themeGray400 -// ) -// -// thumbnailImageView.imageView.kr.setImage(with: item.thumbnailImageURL, placeholder: .empty, scale: FrameResource.closedImageScale) -// -// applyUnOpenableEffect() -// } -// -// func addSubViews() { -// [thumbnailImageView, descriptionLabel, closeButton].forEach { -// addSubview($0) -// } -// } -// -// func makeConstraints() { -// thumbnailImageView.snp.makeConstraints { -// $0.centerX.equalToSuperview() -// $0.centerY.equalToSuperview().multipliedBy(AnimationResource.fromOriginY) -// $0.width.equalTo(UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio) -// $0.height.equalTo(UIScreen.main.bounds.width * FrameResource.capsuleThumbnailWidthRatio * FrameResource.capsuleThumbnailHWRatio) -// } -// -// descriptionLabel.snp.makeConstraints { -// $0.centerX.equalToSuperview() -// $0.top.equalTo(self.snp.centerY).multipliedBy(0.7) -// .offset(FrameResource.capsuleThumbnailHeight / 2 + AnimationResource.capsuleMoveHeight) -// $0.bottom.equalTo(closeButton.snp.top).offset(-FrameResource.spacing200).priority(999) -// } -// -// closeButton.snp.makeConstraints { -// $0.leading.equalToSuperview().offset(FrameResource.horizontalPadding) -// $0.trailing.equalToSuperview().offset(-FrameResource.horizontalPadding) -// $0.bottom.equalTo(safeAreaLayoutGuide.snp.bottom).offset(-FrameResource.spacing200) -// $0.height.equalTo(FrameResource.buttonHeight) -// } -// } -// -// func animate() { -// UIView.animate(withDuration: AnimationResource.capsuleMoveDuration, animations: { -// self.layoutIfNeeded() -// self.thumbnailImageView.center.y = (self.frame.height * AnimationResource.destinationHeightRatio) -// }, completion: { _ in -// UIView.animate(withDuration: AnimationResource.capsuleMoveDuration, -// delay: 0, -// options: [.repeat, .autoreverse] -// ) { -// self.thumbnailImageView.transform = .init(translationX: 0, y: AnimationResource.capsuleMoveHeight) -// } -// }) -// } -// } From 24bf235695c9a2b07b93d86122250e38a6b93b9a Mon Sep 17 00:00:00 2001 From: trumanfromkorea Date: Thu, 15 Dec 2022 22:12:11 +0900 Subject: [PATCH 4/6] =?UTF-8?q?[fix]=20=EB=B6=88=ED=95=84=EC=9A=94=20optio?= =?UTF-8?q?nal=20=EC=A0=9C=EA=B1=B0=20(#110)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Theme/ThemeButton.swift | 2 +- .../CapsuleClose/CapsuleCloseView.swift | 6 ++--- .../CapsuleList/CapsuleListViewModel.swift | 22 ++++++++++--------- .../Components/ListCapsuleCell.swift | 21 ++++++++++-------- .../Components/ListCapsuleCellItem.swift | 2 +- .../CapsuleList/Components/UnOpenable.swift | 10 +++++++-- .../CapsuleMap/CapsuleMapCoordinator.swift | 2 +- .../Scene/TabBar/Home/HomeCoordinator.swift | 2 +- 8 files changed, 39 insertions(+), 28 deletions(-) diff --git a/SpaceCapsule/SpaceCapsule/Components/Theme/ThemeButton.swift b/SpaceCapsule/SpaceCapsule/Components/Theme/ThemeButton.swift index 366d749..3b7b369 100644 --- a/SpaceCapsule/SpaceCapsule/Components/Theme/ThemeButton.swift +++ b/SpaceCapsule/SpaceCapsule/Components/Theme/ThemeButton.swift @@ -14,7 +14,7 @@ final class ThemeButton: UIButton { } } - convenience init(title: String = "") { + convenience init(title: String = " ") { self.init() setTitle(title, for: .normal) diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseView.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseView.swift index 51ceaf5..fe4c37b 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseView.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAdd/CapsuleClose/CapsuleCloseView.swift @@ -22,7 +22,7 @@ final class CapsuleCloseView: CapsuleThumbnailView, BaseView, UnOpenable { let dateLabel = ThemeLabel(size: FrameResource.fontSize80, color: .themeGray200) dateLabel.textAlignment = .center dateLabel.numberOfLines = 0 - + return dateLabel }() @@ -44,13 +44,13 @@ final class CapsuleCloseView: CapsuleThumbnailView, BaseView, UnOpenable { override func configure(item: Item) { bottomButton.setTitle("완료", for: .normal) - + descriptionLabel.text = """ \(item.memoryDateString) \(item.simpleAddress) 에서의 추억이 담긴 캡슐을 보관하였습니다. """ - + closedDateLabel.text = "밀봉시간 \(item.closedDateString)" applyUnopenableEffect(superview: thumbnailImageView) diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/CapsuleListViewModel.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/CapsuleListViewModel.swift index f4690f6..f144613 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/CapsuleListViewModel.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/CapsuleListViewModel.swift @@ -36,7 +36,7 @@ final class CapsuleListViewModel: BaseViewModel { }) .disposed(by: disposeBag) } - + func refreshCapsule() { AppDataManager.shared.fetchCapsules() } @@ -46,16 +46,18 @@ final class CapsuleListViewModel: BaseViewModel { .withUnretained(self) .subscribe( onNext: { owner, capsuleList in + let capsuleCellItems = capsuleList.map { capsule in - ListCapsuleCellItem(uuid: capsule.uuid, - thumbnailImageURL: capsule.images.first, - address: capsule.simpleAddress, - closedDate: capsule.closedDate, - memoryDate: capsule.memoryDate, - coordinate: CLLocationCoordinate2D( - latitude: capsule.geopoint.latitude, - longitude: capsule.geopoint.longitude - ) + ListCapsuleCellItem( + uuid: capsule.uuid, + thumbnailImageURL: capsule.images.first ?? "", + address: capsule.simpleAddress, + closedDate: capsule.closedDate, + memoryDate: capsule.memoryDate, + coordinate: CLLocationCoordinate2D( + latitude: capsule.geopoint.latitude, + longitude: capsule.geopoint.longitude + ) ) } owner.sort(capsuleCellItems: capsuleCellItems, by: owner.input.sortPolicy.value) diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCell.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCell.swift index 3dac7a7..01c352b 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCell.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCell.swift @@ -28,14 +28,14 @@ final class ListCapsuleCell: UICollectionViewCell, UnOpenable { }() lazy var closedDateLabel = { - let dateLabel = ThemeLabel(text: nil, size: FrameResource.fontSize80, color: .themeGray200) + let dateLabel = ThemeLabel(size: FrameResource.fontSize80, color: .themeGray200) dateLabel.textAlignment = .center return dateLabel }() override init(frame: CGRect) { super.init(frame: frame) - + addSubviews() makeConstraints() } @@ -47,9 +47,8 @@ final class ListCapsuleCell: UICollectionViewCell, UnOpenable { override func prepareForReuse() { super.prepareForReuse() - thumbnailImageView.imageView.subviews.forEach { - $0.removeFromSuperview() - } + + removeUnopenableEffect(superview: thumbnailImageView) } func addSubviews() { @@ -73,13 +72,17 @@ final class ListCapsuleCell: UICollectionViewCell, UnOpenable { } func configure(capsuleCellItem: ListCapsuleCellItem) { - if let thumbnailURL = capsuleCellItem.thumbnailImageURL { - thumbnailImageView.imageView.kr.setImage(with: thumbnailURL, placeholder: .empty, scale: FrameResource.openableImageScale) - } + thumbnailImageView.imageView.kr.setImage( + with: capsuleCellItem.thumbnailImageURL, + placeholder: .empty, + scale: FrameResource.openableImageScale + ) + descriptionLabel.text = "\(capsuleCellItem.memoryDate.dateString)\n\(capsuleCellItem.address)에서" closedDateLabel.text = "밀봉시간:\(capsuleCellItem.closedDate.dateString)" + if !capsuleCellItem.isOpenable() { -// applyUnOpenableEffect() + applyUnopenableEffect(superview: thumbnailImageView) } } } diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCellItem.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCellItem.swift index 9ecda09..39fb241 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCellItem.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCellItem.swift @@ -10,7 +10,7 @@ import UIKit struct ListCapsuleCellItem: Hashable, Equatable { let uuid: String - let thumbnailImageURL: String? + let thumbnailImageURL: String let address: String let closedDate: Date let memoryDate: Date diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/UnOpenable.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/UnOpenable.swift index 7045967..2d09edf 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/UnOpenable.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/UnOpenable.swift @@ -9,13 +9,12 @@ import SnapKit import UIKit protocol UnOpenable: UIView { -// var thumbnailImageView: ThumbnailImageView { get } var blurEffectView: CapsuleBlurEffectView { get } var lockImageView: UIImageView { get } var closedDateLabel: ThemeLabel { get } -// func applyUnOpenableEffect() func applyUnopenableEffect(superview: UIView) + func removeUnopenableEffect(superview: UIView) } extension UnOpenable { @@ -40,4 +39,11 @@ extension UnOpenable { } } + func removeUnopenableEffect(superview: UIView) { + superview.subviews.forEach { + if $0 is CapsuleBlurEffectView { + $0.removeFromSuperview() + } + } + } } diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleMap/CapsuleMapCoordinator.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleMap/CapsuleMapCoordinator.swift index 2715ddb..aff3908 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleMap/CapsuleMapCoordinator.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleMap/CapsuleMapCoordinator.swift @@ -32,7 +32,7 @@ final class CapsuleMapCoordinator: Coordinator { if let capsule = AppDataManager.shared.capsule(uuid: uuid) { let capsuleCellItem = ListCapsuleCellItem( uuid: capsule.uuid, - thumbnailImageURL: capsule.images.first, + thumbnailImageURL: capsule.images.first ?? "", address: capsule.simpleAddress, closedDate: capsule.closedDate, memoryDate: capsule.memoryDate, diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/HomeCoordinator.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/HomeCoordinator.swift index 93104f3..0e481d1 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/HomeCoordinator.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/HomeCoordinator.swift @@ -32,7 +32,7 @@ final class HomeCoordinator: Coordinator { if let capsule = AppDataManager.shared.capsule(uuid: uuid) { let capsuleCellItem = ListCapsuleCellItem( uuid: capsule.uuid, - thumbnailImageURL: capsule.images.first, + thumbnailImageURL: capsule.images.first ?? "", address: capsule.address, closedDate: capsule.closedDate, memoryDate: capsule.memoryDate, From c59cf643e65ffd759979da6402858628853a512d Mon Sep 17 00:00:00 2001 From: trumanfromkorea Date: Thu, 15 Dec 2022 22:23:04 +0900 Subject: [PATCH 5/6] =?UTF-8?q?[refactor]=20=EB=B6=88=ED=95=84=EC=9A=94=20?= =?UTF-8?q?=EB=A9=94=EC=86=8C=EB=93=9C=20->=20computed=20property=20(#110)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CapsuleOpenViewController.swift | 4 +- .../Components/ListCapsuleCell.swift | 2 +- .../Components/ListCapsuleCellItem.swift | 16 ++++--- .../Home/Components/HomeCapsuleCell.swift | 48 ++++++++++--------- .../Home/Components/HomeCapsuleCellItem.swift | 43 ++++++++--------- .../Scene/TabBar/Home/HomeViewModel.swift | 2 +- 6 files changed, 58 insertions(+), 57 deletions(-) diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenViewController.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenViewController.swift index 6bc3040..a6c9c19 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenViewController.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleAccess/CapsuleOpen/CapsuleOpenViewController.swift @@ -26,7 +26,7 @@ final class CapsuleOpenViewController: UIViewController, BaseViewController { memoryDateString: item.memoryDate.dateString, simpleAddress: item.address ), - isOpenable: item.isOpenable() + isOpenable: item.isOpenable ) } bind() @@ -60,7 +60,7 @@ final class CapsuleOpenViewController: UIViewController, BaseViewController { guard let capsuleCellItem = viewModel?.capsuleCellItem else { return } - if capsuleCellItem.isOpenable() { + if capsuleCellItem.isOpenable { capsuleOpenView.shakeAnimate() viewModel?.input.tapOpen.onNext(()) } diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCell.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCell.swift index 01c352b..cca1d2d 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCell.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCell.swift @@ -81,7 +81,7 @@ final class ListCapsuleCell: UICollectionViewCell, UnOpenable { descriptionLabel.text = "\(capsuleCellItem.memoryDate.dateString)\n\(capsuleCellItem.address)에서" closedDateLabel.text = "밀봉시간:\(capsuleCellItem.closedDate.dateString)" - if !capsuleCellItem.isOpenable() { + if !capsuleCellItem.isOpenable { applyUnopenableEffect(superview: thumbnailImageView) } } diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCellItem.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCellItem.swift index 39fb241..b4a7a85 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCellItem.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/CapsuleList/Components/ListCapsuleCellItem.swift @@ -8,7 +8,7 @@ import CoreLocation import UIKit -struct ListCapsuleCellItem: Hashable, Equatable { +struct ListCapsuleCellItem { let uuid: String let thumbnailImageURL: String let address: String @@ -16,10 +16,16 @@ struct ListCapsuleCellItem: Hashable, Equatable { let memoryDate: Date let coordinate: CLLocationCoordinate2D - func isOpenable() -> Bool { - return LocationManager.shared.isOpenable(capsuleCoordinate: coordinate) ? true : false + var isOpenable: Bool { + LocationManager.shared.isOpenable(capsuleCoordinate: coordinate) } + func distance() -> Double { + return LocationManager.shared.distance(capsuleCoordinate: coordinate) + } +} + +extension ListCapsuleCellItem: Hashable { static func == (lhs: Self, rhs: Self) -> Bool { return lhs.uuid == rhs.uuid } @@ -27,8 +33,4 @@ struct ListCapsuleCellItem: Hashable, Equatable { func hash(into hasher: inout Hasher) { hasher.combine(uuid) } - - func distance() -> Double { - return LocationManager.shared.distance(capsuleCoordinate: coordinate) - } } diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/Components/HomeCapsuleCell.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/Components/HomeCapsuleCell.swift index abcdde0..02d68fd 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/Components/HomeCapsuleCell.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/Components/HomeCapsuleCell.swift @@ -8,9 +8,9 @@ import SnapKit import UIKit -final class HomeCapsuleCell: UICollectionViewCell, UnOpenable { +final class HomeCapsuleCell: UICollectionViewCell, UnOpenable { var uuid: String? - + var thumbnailImageView = ThumbnailImageView(frame: .zero, width: FrameResource.homeCapsuleCellWidth) var titleLabel = { @@ -19,32 +19,32 @@ final class HomeCapsuleCell: UICollectionViewCell, UnOpenable { label.textAlignment = .center return label }() - + var descriptionLabel = { let label = ThemeLabel(text: "2017.10.23 서울시 성동구\nD+1784", size: FrameResource.fontSize100, color: .themeGray300) label.numberOfLines = 3 label.textAlignment = .center return label }() - + var closedDateLabel = { let dateLabel = ThemeLabel(text: nil, size: FrameResource.fontSize100, color: .themeGray200) dateLabel.textAlignment = .center return dateLabel }() - + var blurEffectView = CapsuleBlurEffectView(width: FrameResource.homeCapsuleCellWidth) - + var lockImageView = { let lockImageView = UIImageView() lockImageView.image = .lock lockImageView.tintColor = .themeGray200 return lockImageView }() - + override init(frame: CGRect) { super.init(frame: frame) - + addSubviews() makeConstraints() } @@ -53,14 +53,13 @@ final class HomeCapsuleCell: UICollectionViewCell, UnOpenable { required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - + override func prepareForReuse() { super.prepareForReuse() - thumbnailImageView.imageView.subviews.forEach { - $0.removeFromSuperview() - } + + removeUnopenableEffect(superview: thumbnailImageView) } - + func addSubviews() { [thumbnailImageView, titleLabel, descriptionLabel].forEach { self.contentView.addSubview($0) @@ -74,12 +73,12 @@ final class HomeCapsuleCell: UICollectionViewCell, UnOpenable { $0.width.equalTo(FrameResource.homeCapsuleCellWidth) $0.height.equalTo(FrameResource.homeCapsuleCellThumbnailHeight) } - + titleLabel.snp.makeConstraints { $0.top.equalTo(thumbnailImageView.snp.bottom).offset(FrameResource.verticalPadding * 2) $0.centerX.equalToSuperview() } - + descriptionLabel.snp.makeConstraints { $0.top.equalTo(titleLabel.snp.bottom).offset(FrameResource.verticalPadding) $0.centerX.equalToSuperview() @@ -88,16 +87,19 @@ final class HomeCapsuleCell: UICollectionViewCell, UnOpenable { func configure(capsuleCellModel: HomeCapsuleCellItem) { uuid = capsuleCellModel.uuid - - if let thumbnailURL = capsuleCellModel.thumbnailImageURL { - thumbnailImageView.imageView.kr.setImage(with: thumbnailURL, placeholder: .empty, scale: FrameResource.openableImageScale) - } + + thumbnailImageView.imageView.kr.setImage( + with: capsuleCellModel.thumbnailImageURL, + placeholder: .empty, + scale: FrameResource.openableImageScale + ) + closedDateLabel.text = "밀봉시간:\(capsuleCellModel.closedDate.dateString)" titleLabel.text = capsuleCellModel.type.title - descriptionLabel.text = capsuleCellModel.description() - - if !capsuleCellModel.isOpenable() { -// applyUnOpenableEffect() + descriptionLabel.text = capsuleCellModel.description + + if !capsuleCellModel.isOpenable { + applyUnopenableEffect(superview: thumbnailImageView) } } } diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/Components/HomeCapsuleCellItem.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/Components/HomeCapsuleCellItem.swift index 68fa421..ae10565 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/Components/HomeCapsuleCellItem.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/Components/HomeCapsuleCellItem.swift @@ -5,8 +5,8 @@ // Created by 김민중 on 2022/11/29. // -import UIKit import CoreLocation +import UIKit enum CapsuleType: CaseIterable { case closedOldest @@ -17,7 +17,7 @@ enum CapsuleType: CaseIterable { case farthest case leastOpened case mostOpened - + var title: String { switch self { case .closedOldest: @@ -40,33 +40,21 @@ enum CapsuleType: CaseIterable { } } -struct HomeCapsuleCellItem: Hashable, Equatable { +struct HomeCapsuleCellItem { let uuid: String - let thumbnailImageURL: String? + let thumbnailImageURL: String let address: String let closedDate: Date let memoryDate: Date let openCount: Int let coordinate: CLLocationCoordinate2D let type: CapsuleType - - func isOpenable() -> Bool { - return LocationManager.shared.isOpenable(capsuleCoordinate: coordinate) ? true : false - } - - static func == (lhs: Self, rhs: Self) -> Bool { - return lhs.uuid == rhs.uuid - } - - func hash(into hasher: inout Hasher) { - hasher.combine(uuid) - } - - func distance() -> Double { - return LocationManager.shared.distance(capsuleCoordinate: coordinate) + + var isOpenable: Bool { + LocationManager.shared.isOpenable(capsuleCoordinate: coordinate) } - - func description() -> String { + + var description: String { switch type { case .closedOldest, .closedNewest: // TODO: D+Day 계산하는 방법 수정해야 할 듯 @@ -76,7 +64,6 @@ struct HomeCapsuleCellItem: Hashable, Equatable { return "\(memoryDate.dotDateString) \(address)에서" } case .memoryOldest, .memoryNewest: -// return "추억일자 : \(memoryDate.dateString)" if let dDay = Calendar.current.dateComponents([.day], from: memoryDate, to: Date()).day { return "\(memoryDate.dotDateString) \(address)에서\nD+\(dDay)" } else { @@ -85,7 +72,7 @@ struct HomeCapsuleCellItem: Hashable, Equatable { case .nearest, .farthest: let distance = LocationManager.shared.distance(capsuleCoordinate: coordinate) if distance > 1000 { - return "\(memoryDate.dotDateString) \(address)에서\n약 \(String(format: "%.2f", (distance / 1000.0)))km" + return "\(memoryDate.dotDateString) \(address)에서\n약 \(String(format: "%.2f", distance / 1000.0))km" } else { return "\(memoryDate.dotDateString) \(address)에서\n약 \(String(format: "%.2f", distance))m" } @@ -94,3 +81,13 @@ struct HomeCapsuleCellItem: Hashable, Equatable { } } } + +extension HomeCapsuleCellItem: Hashable { + static func == (lhs: Self, rhs: Self) -> Bool { + return lhs.uuid == rhs.uuid + } + + func hash(into hasher: inout Hasher) { + hasher.combine(uuid) + } +} diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/HomeViewModel.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/HomeViewModel.swift index ff9bab2..afafa36 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/HomeViewModel.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/HomeViewModel.swift @@ -117,7 +117,7 @@ final class HomeViewModel: BaseViewModel { } return HomeCapsuleCellItem( uuid: capsule.uuid, - thumbnailImageURL: capsule.images.first, + thumbnailImageURL: capsule.images.first ?? "", address: capsule.simpleAddress, closedDate: capsule.closedDate, memoryDate: capsule.memoryDate, From 90798b153a518db3442c5ef764587897a7800ef5 Mon Sep 17 00:00:00 2001 From: trumanfromkorea Date: Thu, 15 Dec 2022 22:37:38 +0900 Subject: [PATCH 6/6] =?UTF-8?q?[refactor]=20=ED=83=80=EC=9E=85=20=EB=94=B0?= =?UTF-8?q?=EB=9D=BC=20=EC=BA=A1=EC=8A=90=20=EA=B5=AC=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=9D=B4=EB=8F=99=20(#110)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Manager/LocationManager.swift | 2 + .../Home/Components/HomeCapsuleCellItem.swift | 38 +++++++ .../Scene/TabBar/Home/HomeViewModel.swift | 99 ++----------------- 3 files changed, 46 insertions(+), 93 deletions(-) diff --git a/SpaceCapsule/SpaceCapsule/Manager/LocationManager.swift b/SpaceCapsule/SpaceCapsule/Manager/LocationManager.swift index 43b858f..81a0a0c 100644 --- a/SpaceCapsule/SpaceCapsule/Manager/LocationManager.swift +++ b/SpaceCapsule/SpaceCapsule/Manager/LocationManager.swift @@ -93,8 +93,10 @@ final class LocationManager { guard let currentCoordinate = coordinate else { return 0.0 } + let currentLocation = location(currentCoordinate) let capsuleLocation = location(capsuleCoordinate) + return currentLocation.distance(from: capsuleLocation) } diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/Components/HomeCapsuleCellItem.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/Components/HomeCapsuleCellItem.swift index ae10565..249b4e2 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/Components/HomeCapsuleCellItem.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/Components/HomeCapsuleCellItem.swift @@ -38,6 +38,44 @@ enum CapsuleType: CaseIterable { return "열어본 횟수가 가장 많은 캡슐" } } + + func capsule(from capsules: [Capsule]) -> Capsule? { + switch self { + case .closedOldest: + return capsules.min { $0.closedDate < $1.closedDate } + + case .closedNewest: + return capsules.min { $0.closedDate > $1.closedDate } + + case .memoryOldest: + return capsules.min { $0.memoryDate < $1.memoryDate } + + case .memoryNewest: + return capsules.min { $0.memoryDate > $1.memoryDate } + + case .leastOpened: + return capsules.min { $0.openCount < $1.openCount } + + case .mostOpened: + return capsules.min { $0.openCount > $1.openCount } + + case .nearest: + return capsules.min { + let first = LocationManager.shared.distance(capsuleCoordinate: $0.geopoint.coordinate) + let second = LocationManager.shared.distance(capsuleCoordinate: $1.geopoint.coordinate) + + return first < second + } + + case .farthest: + return capsules.min { + let first = LocationManager.shared.distance(capsuleCoordinate: $0.geopoint.coordinate) + let second = LocationManager.shared.distance(capsuleCoordinate: $1.geopoint.coordinate) + + return first > second + } + } + } } struct HomeCapsuleCellItem { diff --git a/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/HomeViewModel.swift b/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/HomeViewModel.swift index afafa36..86a55dd 100644 --- a/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/HomeViewModel.swift +++ b/SpaceCapsule/SpaceCapsule/Scene/TabBar/Home/HomeViewModel.swift @@ -39,7 +39,7 @@ final class HomeViewModel: BaseViewModel { owner.coordinator?.tabBarAppearance(isHidden: false) }) .disposed(by: disposeBag) - + input.capsules .withUnretained(self) .subscribe( @@ -50,7 +50,7 @@ final class HomeViewModel: BaseViewModel { } owner.output.featuredCapsuleCellItems.accept( CapsuleType.allCases.shuffled() - .map { owner.getHomeCapsuleCellItem(capsules: capsuleList, type: $0) } + .map { owner.homeCapsuleCellItem(capsules: capsuleList, type: $0) } .compactMap({ $0 }) ) @@ -82,39 +82,11 @@ final class HomeViewModel: BaseViewModel { return "\(nickname)님이 생성한 공간캡슐 \(capsuleCount)개" } - func getHomeCapsuleCellItem(capsules: [Capsule], type: CapsuleType) -> HomeCapsuleCellItem? { - switch type { - case .closedOldest: - let capsule = getClosedOldest(capsules: capsules) - return makeHomeCapsuleCellItem(capsule: capsule, type: type) - case .closedNewest: - let capsule = getClosedNewest(capsules: capsules) - return makeHomeCapsuleCellItem(capsule: capsule, type: type) - case .memoryOldest: - let capsule = getMemoryOldest(capsules: capsules) - return makeHomeCapsuleCellItem(capsule: capsule, type: type) - case .memoryNewest: - let capsule = getMemoryNewest(capsules: capsules) - return makeHomeCapsuleCellItem(capsule: capsule, type: type) - case .nearest: - let capsule = getNearest(capsules: capsules) - return makeHomeCapsuleCellItem(capsule: capsule, type: type) - case .farthest: - let capsule = getFarthest(capsules: capsules) - return makeHomeCapsuleCellItem(capsule: capsule, type: type) - case .leastOpened: - let capsule = getLeastOpened(capsules: capsules) - return makeHomeCapsuleCellItem(capsule: capsule, type: type) - case .mostOpened: - let capsule = getMostOpened(capsules: capsules) - return makeHomeCapsuleCellItem(capsule: capsule, type: type) - } - } - - func makeHomeCapsuleCellItem(capsule: Capsule?, type: CapsuleType) -> HomeCapsuleCellItem? { - guard let capsule else { + func homeCapsuleCellItem(capsules: [Capsule], type: CapsuleType) -> HomeCapsuleCellItem? { + guard let capsule = type.capsule(from: capsules) else { return nil } + return HomeCapsuleCellItem( uuid: capsule.uuid, thumbnailImageURL: capsule.images.first ?? "", @@ -122,67 +94,8 @@ final class HomeViewModel: BaseViewModel { closedDate: capsule.closedDate, memoryDate: capsule.memoryDate, openCount: capsule.openCount, - coordinate: CLLocationCoordinate2D( - latitude: capsule.geopoint.latitude, - longitude: capsule.geopoint.longitude - ), + coordinate: capsule.geopoint.coordinate, type: type ) } - - func getClosedOldest(capsules: [Capsule]) -> Capsule? { - return capsules.min { $0.closedDate < $1.closedDate } - } - - func getClosedNewest(capsules: [Capsule]) -> Capsule? { - return capsules.max { $0.closedDate < $1.closedDate } - } - - func getMemoryOldest(capsules: [Capsule]) -> Capsule? { - return capsules.min { $0.memoryDate < $1.memoryDate } - } - - func getMemoryNewest(capsules: [Capsule]) -> Capsule? { - return capsules.max { $0.memoryDate < $1.memoryDate } - } - - func getNearest(capsules: [Capsule]) -> Capsule? { - return capsules.min { first, second in - let firstLocation = CLLocationCoordinate2D( - latitude: first.geopoint.latitude, - longitude: first.geopoint.longitude - ) - let secondLocation = CLLocationCoordinate2D( - latitude: second.geopoint.latitude, - longitude: second.geopoint.longitude - ) - let firstDistance = LocationManager.shared.distance(capsuleCoordinate: firstLocation) - let secondDistance = LocationManager.shared.distance(capsuleCoordinate: secondLocation) - return firstDistance < secondDistance - } - } - - func getFarthest(capsules: [Capsule]) -> Capsule? { - return capsules.max { first, second in - let firstLocation = CLLocationCoordinate2D( - latitude: first.geopoint.latitude, - longitude: first.geopoint.longitude - ) - let secondLocation = CLLocationCoordinate2D( - latitude: second.geopoint.latitude, - longitude: second.geopoint.longitude - ) - let firstDistance = LocationManager.shared.distance(capsuleCoordinate: firstLocation) - let secondDistance = LocationManager.shared.distance(capsuleCoordinate: secondLocation) - return firstDistance < secondDistance - } - } - - func getLeastOpened(capsules: [Capsule]) -> Capsule? { - return capsules.min(by: { $0.openCount < $1.openCount }) - } - - func getMostOpened(capsules: [Capsule]) -> Capsule? { - return capsules.min(by: { $0.openCount > $1.openCount }) - } }