diff --git a/AVIRO.xcodeproj/project.pbxproj b/AVIRO.xcodeproj/project.pbxproj index 2f63c99c..ad9f3eaf 100644 --- a/AVIRO.xcodeproj/project.pbxproj +++ b/AVIRO.xcodeproj/project.pbxproj @@ -109,6 +109,7 @@ C541521D2AC125E100F39826 /* TutorialTopLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C541521C2AC125E100F39826 /* TutorialTopLabel.swift */; }; C54386762B33F05500BD2CAF /* ReviewPushView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C54386752B33F05500BD2CAF /* ReviewPushView.swift */; }; C54386792B3432FE00BD2CAF /* ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C54386782B3432FE00BD2CAF /* ViewModel.swift */; }; + C54733D32BE20EF4004E961C /* SearchUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = C54733D22BE20EF4004E961C /* SearchUtility.swift */; }; C5476B4D2B2F1F1F00F5FC6E /* AVIROTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5476B4C2B2F1F1F00F5FC6E /* AVIROTests.swift */; }; C5476B612B3028FA00F5FC6E /* ChallengeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5476B602B3028FA00F5FC6E /* ChallengeViewController.swift */; }; C5476B682B303BE800F5FC6E /* MyInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5476B672B303BE800F5FC6E /* MyInfoView.swift */; }; @@ -240,6 +241,7 @@ C5E306E72A6FB4ED00C11CF7 /* MenuField.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5E306E62A6FB4ED00C11CF7 /* MenuField.swift */; }; C5E430B32A5DADBE00CB67EC /* SecondRegistrationPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5E430B22A5DADBE00CB67EC /* SecondRegistrationPresenter.swift */; }; C5E430B52A5DAE9800CB67EC /* SecondRegistrationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5E430B42A5DAE9800CB67EC /* SecondRegistrationViewController.swift */; }; + C5E797652C1EEE85000E7929 /* PlaceDeleteRequestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5E797642C1EEE85000E7929 /* PlaceDeleteRequestView.swift */; }; C5E7B7A92A4D3CDF00CA2090 /* AVIROUser+DTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5E7B7A82A4D3CDF00CA2090 /* AVIROUser+DTO.swift */; }; C5EB50EA2A1C705900B29CC1 /* SettingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5EB50E92A1C705900B29CC1 /* SettingViewController.swift */; }; C5EB51082A209F6900B29CC1 /* HomeSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5EB51072A209F6900B29CC1 /* HomeSearchViewController.swift */; }; @@ -388,6 +390,7 @@ C54386752B33F05500BD2CAF /* ReviewPushView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReviewPushView.swift; sourceTree = ""; }; C54386782B3432FE00BD2CAF /* ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModel.swift; sourceTree = ""; }; C54657862ABF2D82003A0BCB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + C54733D22BE20EF4004E961C /* SearchUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchUtility.swift; sourceTree = ""; }; C5476B4A2B2F1F1F00F5FC6E /* AVIROTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AVIROTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; C5476B4C2B2F1F1F00F5FC6E /* AVIROTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVIROTests.swift; sourceTree = ""; }; C5476B602B3028FA00F5FC6E /* ChallengeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChallengeViewController.swift; sourceTree = ""; }; @@ -521,6 +524,7 @@ C5E306E62A6FB4ED00C11CF7 /* MenuField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuField.swift; sourceTree = ""; }; C5E430B22A5DADBE00CB67EC /* SecondRegistrationPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecondRegistrationPresenter.swift; sourceTree = ""; }; C5E430B42A5DAE9800CB67EC /* SecondRegistrationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecondRegistrationViewController.swift; sourceTree = ""; }; + C5E797642C1EEE85000E7929 /* PlaceDeleteRequestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaceDeleteRequestView.swift; sourceTree = ""; }; C5E7B7A82A4D3CDF00CA2090 /* AVIROUser+DTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AVIROUser+DTO.swift"; sourceTree = ""; }; C5EB50E92A1C705900B29CC1 /* SettingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingViewController.swift; sourceTree = ""; }; C5EB51072A209F6900B29CC1 /* HomeSearchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeSearchViewController.swift; sourceTree = ""; }; @@ -1464,6 +1468,7 @@ C5A201B12A98502500A54381 /* TimeUtility.swift */, C5C20BAB2AD504D500855BBB /* AmplitudeUtility.swift */, C5F33DFC2ADED19000A29FB9 /* SystemUtility.swift */, + C54733D22BE20EF4004E961C /* SearchUtility.swift */, ); path = Utility; sourceTree = ""; @@ -1683,6 +1688,7 @@ C5C2907A2A85E51B00ED5DCE /* PlaceReviewsView.swift */, C5166E4A2A939442003495AA /* SubView */, C5C961902A8D9EA10016E2F8 /* TableView */, + C5E797642C1EEE85000E7929 /* PlaceDeleteRequestView.swift */, ); path = SubView; sourceTree = ""; @@ -2396,6 +2402,7 @@ C58EC7CE2AB1B57100401FF7 /* AVIROEditOperationTime+DTO.swift in Sources */, C50DB7542A9B838F0078B501 /* ChangeableAddressPresenter.swift in Sources */, C5DCBC9D2B91D9F5003502BA /* MyPlaceListViewController.swift in Sources */, + C5E797652C1EEE85000E7929 /* PlaceDeleteRequestView.swift in Sources */, C58EC7D42AB1B5C400401FF7 /* AVIROEditURL+DTO.swift in Sources */, C50F6B022A6BC8E400E942F5 /* EnrollField.swift in Sources */, C552D5342ABE8CA500933D8A /* AVIRODeleteAPI.swift in Sources */, @@ -2435,6 +2442,7 @@ C50E6F6F2A8F10B500703B9E /* UILabel+Extension.swift in Sources */, C52066352A7F3FAE0038ECCD /* HistoryTableViewCell.swift in Sources */, C5C90EB72AA7078300AB3668 /* EditOperationHoursModel.swift in Sources */, + C54733D32BE20EF4004E961C /* SearchUtility.swift in Sources */, C528E4BA2A5F9A3E002BD72E /* ThridRegistrationViewController.swift in Sources */, C528E4BC2A5F9AB6002BD72E /* ThridRegistrationPresenter.swift in Sources */, C51000612ABAE61F00F65C1F /* ReportReviewModel.swift in Sources */, @@ -2669,7 +2677,7 @@ CODE_SIGN_ENTITLEMENTS = AVIRO/AVIRO.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = C4K2HXA435; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = AVIRO/App/Info.plist; @@ -2687,7 +2695,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.2.4; + MARKETING_VERSION = 1.2.5; PRODUCT_BUNDLE_IDENTIFIER = SeonghunJeon.VeganRestaurant; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -2706,7 +2714,7 @@ CODE_SIGN_ENTITLEMENTS = AVIRO/AVIRO.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = C4K2HXA435; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = AVIRO/App/Info.plist; @@ -2724,7 +2732,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.2.4; + MARKETING_VERSION = 1.2.5; PRODUCT_BUNDLE_IDENTIFIER = SeonghunJeon.VeganRestaurant; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/AVIRO.xcodeproj/xcshareddata/xcschemes/AVIRO.xcscheme b/AVIRO.xcodeproj/xcshareddata/xcschemes/AVIRO.xcscheme index f23ca29a..b0b3e87a 100644 --- a/AVIRO.xcodeproj/xcshareddata/xcschemes/AVIRO.xcscheme +++ b/AVIRO.xcodeproj/xcshareddata/xcschemes/AVIRO.xcscheme @@ -68,11 +68,6 @@ value = "disable" isEnabled = "YES"> - - - NSPrivacyTracking - NSPrivacyTrackingDomains + NSPrivacyTracking + NSPrivacyCollectedDataTypes - + + + NSPrivacyCollectedDataType + + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + + + + NSPrivacyAccessedAPITypes diff --git a/AVIRO/Custom/Constants/Enum+.swift b/AVIRO/Custom/Constants/Enum+.swift index d78ea85c..d4c4326d 100644 --- a/AVIRO/Custom/Constants/Enum+.swift +++ b/AVIRO/Custom/Constants/Enum+.swift @@ -17,6 +17,8 @@ enum APP: String { // MARK: UserDefaults Key enum UDKey: String { case tutorial + case tutorialHome + case tutorialChallenge case hideUntil case timeForUpdate } diff --git a/AVIRO/Custom/Constants/UIImage+Extension.swift b/AVIRO/Custom/Constants/UIImage+Extension.swift index 2d83cde8..435c3e4c 100644 --- a/AVIRO/Custom/Constants/UIImage+Extension.swift +++ b/AVIRO/Custom/Constants/UIImage+Extension.swift @@ -48,13 +48,13 @@ extension UIImage { static let someIconClicked = UIImage(named: "SomeMapClicked")! static let requestIconClicked = UIImage(named: "RequestMapClicked")! - static let allIconStar = UIImage(named: "AllMapStar")! - static let someIconStar = UIImage(named: "SomeMapStar")! - static let requestIconStar = UIImage(named: "RequestMapStar")! + static let allIconStar = UIImage(named: "All_Default_Fav")! + static let someIconStar = UIImage(named: "Some_Default_Fav")! + static let requestIconStar = UIImage(named: "Request_Default_Fav")! - static let allIconStarClicked = UIImage(named: "AllMapStarClicked")! - static let someIconStarClicked = UIImage(named: "SomeMapStarClicked")! - static let requestIconStarClicked = UIImage(named: "RequestMapStarClicked")! + static let allIconStarClicked = UIImage(named: "All_Clicked_Fav")! + static let someIconStarClicked = UIImage(named: "Some_Clicked_Fav")! + static let requestIconStarClicked = UIImage(named: "Request_Clicked_Fav")! static let allOptionButton = UIImage(named: "AllOption")! static let someOptionButton = UIImage(named: "SomeOption")! @@ -114,13 +114,7 @@ extension UIImage { static let defaultCategoryBread = UIImage(named: "Default_btn_Bread")! static let defaultCategoryCoffee = UIImage(named: "Default_btn_Coffee")! static let defaultCategoryRestaurant = UIImage(named: "Default_btn_Restaurant")! - - // Off Category - static let offCategoryBar = UIImage(named: "Off_btn_Bar")! - static let offCategoryBread = UIImage(named: "Off_btn_Bread")! - static let offCategoryCoffee = UIImage(named: "Off_btn_Coffee")! - static let offCategoryRestaurant = UIImage(named: "Off_btn_Restaurant")! - + // On Category static let onCategoryBar = UIImage(named: "On_btn_Bar")! static let onCategoryBread = UIImage(named: "On_btn_Bread")! @@ -203,6 +197,10 @@ extension UIImage { static let btn_pencil = UIImage(named: "Btn_pencil")! static let btn_plus_square = UIImage(named: "Btn_plus_square")! + static let speechBubble1 = UIImage(named: "SpeechBubble1") + static let speechBubble2 = UIImage(named: "SpeechBubble2") + static let speechBubble3 = UIImage(named: "SpeechBubble3") + // MARK: Challenge static let challengeInfoGreen = UIImage(named: "Challenge_Info_Green")! static let challengeInfoYellow = UIImage(named: "Challenge_Info_Yellow")! diff --git a/AVIRO/Custom/SubClass/UIButton/PlaceView/EditInfoButton.swift b/AVIRO/Custom/SubClass/UIButton/PlaceView/EditInfoButton.swift index 242a4f0e..a2c14608 100644 --- a/AVIRO/Custom/SubClass/UIButton/PlaceView/EditInfoButton.swift +++ b/AVIRO/Custom/SubClass/UIButton/PlaceView/EditInfoButton.swift @@ -22,7 +22,10 @@ final class EditInfoButton: UIButton { self.setTitleColor(.keywordBlue, for: .normal) self.titleLabel?.font = CFont.font.medium14 - self.setImage(UIImage.editInfo, for: .normal) + self.setImage( + UIImage.editInfo.withRenderingMode(.alwaysTemplate), + for: .normal + ) self.backgroundColor = .gray7 diff --git a/AVIRO/Custom/Utility/SearchUtility.swift b/AVIRO/Custom/Utility/SearchUtility.swift new file mode 100644 index 00000000..eba6ce7f --- /dev/null +++ b/AVIRO/Custom/Utility/SearchUtility.swift @@ -0,0 +1,27 @@ +// +// SearchUtility.swift +// AVIRO +// +// Created by 전성훈 on 5/1/24. +// + +import Foundation + +extension RandomAccessCollection where Element == MarkerModel, Index == Int { + func binarySearchByPlaceId(for placeId: String, in range: Range? = nil) -> Index? { + let range = range ?? startIndex.. placeId { + return binarySearchByPlaceId(for: placeId, in: range.lowerBound.. Bool { + return lhs.placeId < rhs.placeId + } +} diff --git a/AVIRO/Model/LocalDataModel/MarkerModelCache.swift b/AVIRO/Model/LocalDataModel/MarkerModelCache.swift index cac6c739..1e9e105c 100644 --- a/AVIRO/Model/LocalDataModel/MarkerModelCache.swift +++ b/AVIRO/Model/LocalDataModel/MarkerModelCache.swift @@ -108,7 +108,6 @@ final class MarkerModelCache: MarkerModelCacheProtocol { let latLng = NMGLatLng(lat: changedPositionLat, lng: changedPositionLng) model.marker.position = latLng - } } } diff --git a/AVIRO/Scene/Base/TabBar/AVIROTabBarController.swift b/AVIRO/Scene/Base/TabBar/AVIROTabBarController.swift index 573e2d64..9afc04ed 100644 --- a/AVIRO/Scene/Base/TabBar/AVIROTabBarController.swift +++ b/AVIRO/Scene/Base/TabBar/AVIROTabBarController.swift @@ -190,6 +190,7 @@ final class AVIROTabBarController: UIViewController, TabBarFromSubVCDelegate { self.view.backgroundColor = .clear setupButtons() + checkWellcomeShow() } @@ -242,8 +243,13 @@ final class AVIROTabBarController: UIViewController, TabBarFromSubVCDelegate { redDotView.topAnchor.constraint(equalTo: imageView.topAnchor, constant: -3) ]) } + // MARK: - Wellcome VC private func checkWellcomeShow() { + guard UserDefaults.standard.bool( + forKey: UDKey.tutorialHome.rawValue + ) else { return } + guard let compareDate = UserDefaults.standard.object( forKey: UDKey.hideUntil.rawValue ) as? Date else { @@ -296,6 +302,10 @@ final class AVIROTabBarController: UIViewController, TabBarFromSubVCDelegate { welcomeViewController = nil } + func activeCheckWellcome() { + checkWellcomeShow() + } + // MARK: - TabBar Click After private func updateView() { deleteView() diff --git a/AVIRO/Scene/Base/TabBar/AVIROTabBarSettingDelegate.swift b/AVIRO/Scene/Base/TabBar/AVIROTabBarSettingDelegate.swift index 28555c3c..70eb7770 100644 --- a/AVIRO/Scene/Base/TabBar/AVIROTabBarSettingDelegate.swift +++ b/AVIRO/Scene/Base/TabBar/AVIROTabBarSettingDelegate.swift @@ -14,4 +14,5 @@ protocol TabBarFromSubVCDelegate: AnyObject { func setSelectedIndex(_ index: Int, withData data: [String: Any]) func activeBlurEffectView(with active: Bool) + func activeCheckWellcome() } diff --git a/AVIRO/Scene/Feature/Challenge/Setting/ViewController/SettingViewController.swift b/AVIRO/Scene/Feature/Challenge/Setting/ViewController/SettingViewController.swift index 9a79335a..79266efa 100644 --- a/AVIRO/Scene/Feature/Challenge/Setting/ViewController/SettingViewController.swift +++ b/AVIRO/Scene/Feature/Challenge/Setting/ViewController/SettingViewController.swift @@ -32,7 +32,8 @@ enum SettingsSection: Int, CaseIterable { return [ .editNickname, .inquiries, - .instagram + .instagram, + .tutorialRestart ] case .information: return [ @@ -53,8 +54,9 @@ enum SettingsSection: Int, CaseIterable { enum SettingsRow: String { case editNickname = "닉네임 수정하기" - case inquiries = "문의사항" - case instagram = "인스타그램" + case inquiries = "어비로에 건의하기" + case instagram = "어비로 인스타그램 놀러가기" + case tutorialRestart = "튜토리얼 다시하기" case termsOfService = "서비스 이용약관" case privacyPolicy = "개인정보 수집 및 이용" @@ -68,6 +70,7 @@ enum SettingsRow: String { final class SettingViewController: UIViewController { private lazy var presenter = SettingViewPresenter(viewController: self) + weak var tabBarDelegate: TabBarFromSubVCDelegate? private lazy var indicatorView: UIActivityIndicatorView = { let indicatorView = UIActivityIndicatorView() @@ -162,7 +165,8 @@ extension SettingViewController: MyPageViewProtocol { whenTappedInquiries() case .instagram: whenTappedInstagram() - + case .tutorialRestart: + whenTappedTutorialRestart() case .termsOfService: whenTappedTermsOfService() case .privacyPolicy: @@ -200,6 +204,20 @@ extension SettingViewController: MyPageViewProtocol { UIApplication.shared.open(aviro) } + private func whenTappedTutorialRestart() { + UserDefaults.standard.set( + false, + forKey: UDKey.tutorialHome.rawValue + ) + UserDefaults.standard.set( + false, + forKey: UDKey.tutorialChallenge.rawValue + ) + + tabBarDelegate?.selectedIndex = 0 + self.dismiss(animated: false) + } + private func whenTappedTermsOfService() { if let url = URL(string: Policy.termsOfService.rawValue) { showWebView(with: url) diff --git a/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeUserInfoView/ChallengeLevelView.swift b/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeUserInfoView/ChallengeLevelView.swift index 75a80056..f8e8bc06 100644 --- a/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeUserInfoView/ChallengeLevelView.swift +++ b/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeUserInfoView/ChallengeLevelView.swift @@ -50,7 +50,7 @@ final class ChallengeLevelView: UIView { return label }() - + override init(frame: CGRect) { super.init(frame: frame) @@ -93,6 +93,7 @@ final class ChallengeLevelView: UIView { self.backgroundColor = .gray6 self.layer.cornerRadius = 12 + updateLevelPoint(with: ("0", "30")) } @@ -142,6 +143,6 @@ final class ChallengeLevelView: UIView { let currentProgress = Float(levelPoint.now)! / Float(levelPoint.gool)! - levelProgress.setProgress(currentProgress, animated: true) + levelProgress.setProgress(currentProgress, animated: false) } } diff --git a/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeUserInfoView/ChallengeUserInfoView.swift b/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeUserInfoView/ChallengeUserInfoView.swift index fc055076..50703bb6 100644 --- a/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeUserInfoView/ChallengeUserInfoView.swift +++ b/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeUserInfoView/ChallengeUserInfoView.swift @@ -25,7 +25,7 @@ final class ChallengeUserInfoView: UIView { imageView.layer.cornerRadius = 150/2 imageView.backgroundColor = .gray7 imageView.contentMode = .scaleAspectFill - imageView.layer.borderWidth = 5 + imageView.layer.borderWidth = 2 imageView.layer.borderColor = UIColor.challengeImageBorder.cgColor return imageView @@ -48,6 +48,9 @@ final class ChallengeUserInfoView: UIView { return view }() + private lazy var blurEffectViewForTutorial = BlurEffectView() + private lazy var speechBubbleViewForCharacterExplain = UIImageView(image: .speechBubble3) + override init(frame: CGRect) { super.init(frame: frame) @@ -63,8 +66,10 @@ final class ChallengeUserInfoView: UIView { [ nameLabel, levelView, + blurEffectViewForTutorial, treeImageView, - indicatorView + indicatorView, + speechBubbleViewForCharacterExplain ].forEach { $0.translatesAutoresizingMaskIntoConstraints = false self.addSubview($0) @@ -76,8 +81,8 @@ final class ChallengeUserInfoView: UIView { treeImageView.topAnchor.constraint(equalTo: nameLabel.bottomAnchor, constant: 24), treeImageView.centerXAnchor.constraint(equalTo: self.centerXAnchor), - treeImageView.widthAnchor.constraint(equalToConstant: 150), - treeImageView.heightAnchor.constraint(equalToConstant: 150), + treeImageView.widthAnchor.constraint(equalToConstant: 155), + treeImageView.heightAnchor.constraint(equalToConstant: 155), levelView.topAnchor.constraint(equalTo: treeImageView.topAnchor, constant: 84), levelView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 15), @@ -85,14 +90,32 @@ final class ChallengeUserInfoView: UIView { levelView.bottomAnchor.constraint(equalTo: self.bottomAnchor), indicatorView.centerXAnchor.constraint(equalTo: treeImageView.centerXAnchor), - indicatorView.centerYAnchor.constraint(equalTo: treeImageView.centerYAnchor) + indicatorView.centerYAnchor.constraint(equalTo: treeImageView.centerYAnchor), + + blurEffectViewForTutorial.topAnchor.constraint(equalTo: self.topAnchor), + blurEffectViewForTutorial.leadingAnchor.constraint(equalTo: self.leadingAnchor), + blurEffectViewForTutorial.trailingAnchor.constraint(equalTo: self.trailingAnchor), + blurEffectViewForTutorial.bottomAnchor.constraint(equalTo: self.bottomAnchor), + + speechBubbleViewForCharacterExplain.topAnchor.constraint( + equalTo: treeImageView.bottomAnchor, + constant: 8 + ), + speechBubbleViewForCharacterExplain.centerXAnchor.constraint(equalTo: self.centerXAnchor) ]) + + blurEffectViewForTutorial.isHidden = false } private func setupAttribute() { self.backgroundColor = .gray7 } + func blurEffectHidden(_ isHidden: Bool) { + blurEffectViewForTutorial.isHidden = isHidden + speechBubbleViewForCharacterExplain.isHidden = isHidden + } + func startIndicator() { indicatorView.isHidden = false } diff --git a/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeViewController.swift b/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeViewController.swift index 31922716..6188eff9 100644 --- a/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeViewController.swift +++ b/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeViewController.swift @@ -53,6 +53,11 @@ final class ChallengeViewController: UIViewController { return refreshControl }() + private lazy var blurEffectContentViewForTutorial = BlurEffectView() + private lazy var blurEffectTopViewForTutorial = BlurEffectView() + private lazy var emptyEffectView = UIView() + private lazy var tutorialGesture = UITapGestureRecognizer() + static func create(with viewModel: ChallengeViewModel) -> ChallengeViewController { let vc = ChallengeViewController() @@ -69,10 +74,18 @@ final class ChallengeViewController: UIViewController { dataBinding() } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + checkTutorialChallenge() + } private func setupLayout() { [ - scrollView + scrollView, + blurEffectTopViewForTutorial, + emptyEffectView ].forEach { $0.translatesAutoresizingMaskIntoConstraints = false view.addSubview($0) @@ -90,13 +103,24 @@ final class ChallengeViewController: UIViewController { ), scrollView.bottomAnchor.constraint( equalTo: self.view.safeAreaLayoutGuide.bottomAnchor - ) + ), + + blurEffectTopViewForTutorial.topAnchor.constraint(equalTo: self.view.topAnchor), + blurEffectTopViewForTutorial.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), + blurEffectTopViewForTutorial.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), + blurEffectTopViewForTutorial.bottomAnchor.constraint(equalTo: scrollView.topAnchor), + + emptyEffectView.topAnchor.constraint(equalTo: self.view.topAnchor), + emptyEffectView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), + emptyEffectView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), + emptyEffectView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor) ]) [ challengeTitleView, - challengeUserInfoView, - myInfoView + myInfoView, + blurEffectContentViewForTutorial, + challengeUserInfoView ].forEach { $0.translatesAutoresizingMaskIntoConstraints = false scrollView.addSubview($0) @@ -145,7 +169,12 @@ final class ChallengeViewController: UIViewController { myInfoView.bottomAnchor.constraint( equalTo: scrollView.contentLayoutGuide.bottomAnchor, constant: -32 - ) + ), + + blurEffectContentViewForTutorial.topAnchor.constraint(equalTo: self.view.topAnchor), + blurEffectContentViewForTutorial.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), + blurEffectContentViewForTutorial.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), + blurEffectContentViewForTutorial.bottomAnchor.constraint(equalTo: self.view.bottomAnchor) ]) } @@ -178,6 +207,15 @@ final class ChallengeViewController: UIViewController { myInfoView.tappedMyInfo = { [weak self] myInfoType in self?.userInfoListTapped.onNext(myInfoType) } + + emptyEffectView.addGestureRecognizer(tutorialGesture) + tutorialGesture.addTarget(self, action: #selector(tappedTutorial(_:))) + + emptyEffectView.backgroundColor = .clear + emptyEffectView.isHidden = true + blurEffectTopViewForTutorial.isHidden = true + blurEffectContentViewForTutorial.isHidden = true + challengeUserInfoView.blurEffectHidden(true) } private func dataBinding() { @@ -291,6 +329,7 @@ final class ChallengeViewController: UIViewController { func pushSettingViewController() { let vc = SettingViewController() + vc.tabBarDelegate = tabBarDelegate navigationController?.pushViewController(vc, animated: true) } @@ -328,6 +367,34 @@ final class ChallengeViewController: UIViewController { navigationController?.pushViewController(vc, animated: true) } } + + private func checkTutorialChallenge() { + guard !UserDefaults.standard.bool(forKey: UDKey.tutorialChallenge.rawValue) else { return } + + activeTutorial() + } + + private func activeTutorial() { + emptyEffectView.isHidden = false + blurEffectTopViewForTutorial.isHidden = false + blurEffectContentViewForTutorial.isHidden = false + challengeUserInfoView.blurEffectHidden(false) + + tabBarDelegate?.activeBlurEffectView(with: true) + } + + @objc private func tappedTutorial(_ gesture: UITapGestureRecognizer) { + emptyEffectView.isHidden = true + blurEffectTopViewForTutorial.isHidden = true + blurEffectContentViewForTutorial.isHidden = true + challengeUserInfoView.blurEffectHidden(true) + tabBarDelegate?.activeBlurEffectView(with: false) + + UserDefaults.standard.set( + true, + forKey: UDKey.tutorialChallenge.rawValue + ) + } } extension Reactive where Base: ChallengeViewController { diff --git a/AVIRO/Scene/Feature/Home/ReviewWriteView/ViewController/SubViews/ChallengeNameStickerView.swift b/AVIRO/Scene/Feature/Home/ReviewWriteView/ViewController/SubViews/ChallengeNameStickerView.swift index ac584a2b..e8bd4d00 100644 --- a/AVIRO/Scene/Feature/Home/ReviewWriteView/ViewController/SubViews/ChallengeNameStickerView.swift +++ b/AVIRO/Scene/Feature/Home/ReviewWriteView/ViewController/SubViews/ChallengeNameStickerView.swift @@ -23,7 +23,7 @@ final class ChallengeNameStickerView: UIView { return label }() - private let arrowView = { + private let arrowView: ArrowView = { let view = ArrowView() view.backgroundColor = .clear diff --git a/AVIRO/Scene/Feature/Home/ViewController/HomeViewController.swift b/AVIRO/Scene/Feature/Home/ViewController/HomeViewController.swift index 427f25b9..6b303d6d 100644 --- a/AVIRO/Scene/Feature/Home/ViewController/HomeViewController.swift +++ b/AVIRO/Scene/Feature/Home/ViewController/HomeViewController.swift @@ -90,7 +90,17 @@ final class HomeViewController: UIViewController { return map }() - private var selectedCategoriesPlaceHolder: [String] = [] + private var selectedCategoriesPlaceHolder: [String] = [] { + didSet { + if selectedCategoriesPlaceHolder.count > 0 { + // 배열에 있는 모든 항목을 콤마로 구분하여 placeholder에 설정합니다. + searchTextField.placeholder = selectedCategoriesPlaceHolder.joined(separator: ", ") + } else { + // 모든 type의 선택이 false일 때 + searchTextField.placeholder = Text.searchPlaceHolder.rawValue + } + } + } private lazy var searchTextField: MainField = { let field = MainField() @@ -224,6 +234,12 @@ final class HomeViewController: UIViewController { private lazy var blurEffectView = BlurEffectView() + private lazy var blurEffectViewForTutorial = BlurEffectView() + private lazy var speechBubbleViewForColorExplain = UIImageView(image: .speechBubble1) + private lazy var speechBubbleViewForCategoryExplain = UIImageView(image: .speechBubble2) + private lazy var emptyEffectView = UIView() + private lazy var tutorialGesture = UITapGestureRecognizer() + private(set) var placeViewTopConstraint: NSLayoutConstraint? private(set) var searchTextFieldTopConstraint: NSLayoutConstraint? @@ -254,6 +270,8 @@ final class HomeViewController: UIViewController { super.viewWillAppear(animated) presenter.viewWillAppear() + + checkTutorialHome() } override func viewDidAppear(_ animated: Bool) { @@ -277,15 +295,19 @@ extension HomeViewController: HomeViewProtocol { loadLocationButton, starButton, searchTextField, - categoryCollectionView, placeView, flagButton, downBackButton, + blurEffectViewForTutorial, + speechBubbleViewForColorExplain, + speechBubbleViewForCategoryExplain, + categoryCollectionView, blurEffectView, recommendPlaceAlertView, levelUpAlertView, isFecthingLabel, - isFectchingindicatorView + isFectchingindicatorView, + emptyEffectView ].forEach { $0.translatesAutoresizingMaskIntoConstraints = false view.addSubview($0) @@ -386,9 +408,34 @@ extension HomeViewController: HomeViewProtocol { isFectchingindicatorView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor), isFecthingLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor), - isFecthingLabel.topAnchor.constraint(equalTo: isFectchingindicatorView.bottomAnchor, constant: 16) + isFecthingLabel.topAnchor.constraint(equalTo: isFectchingindicatorView.bottomAnchor, constant: 16), + + blurEffectViewForTutorial.topAnchor.constraint(equalTo: self.view.topAnchor), + blurEffectViewForTutorial.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), + blurEffectViewForTutorial.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), + blurEffectViewForTutorial.bottomAnchor.constraint(equalTo: self.view.bottomAnchor), + + speechBubbleViewForColorExplain.bottomAnchor.constraint( + equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, + constant: -16 + ), + speechBubbleViewForColorExplain.leadingAnchor.constraint( + equalTo: self.view.safeAreaLayoutGuide.leadingAnchor, + constant: 10 + ), + + speechBubbleViewForCategoryExplain.topAnchor.constraint( + equalTo: categoryCollectionView.bottomAnchor, + constant: 10 + ), + speechBubbleViewForCategoryExplain.centerXAnchor.constraint(equalTo: self.view.centerXAnchor), + + emptyEffectView.topAnchor.constraint(equalTo: self.view.topAnchor), + emptyEffectView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), + emptyEffectView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), + emptyEffectView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor) ]) - + searchTextFieldTopConstraint = searchTextField.topAnchor.constraint( equalTo: view.safeAreaLayoutGuide.topAnchor, constant: Layout.Margin.regular.rawValue @@ -399,13 +446,73 @@ extension HomeViewController: HomeViewProtocol { equalTo: self.view.safeAreaLayoutGuide.bottomAnchor ) placeViewTopConstraint?.isActive = true + } + + func setupAttribute() { + view.backgroundColor = .gray7 recommendPlaceAlertView.isHidden = true levelUpAlertView.isHidden = true + + speechBubbleViewForColorExplain.isHidden = true + speechBubbleViewForCategoryExplain.isHidden = true + emptyEffectView.isHidden = true + emptyEffectView.backgroundColor = .clear + emptyEffectView.addGestureRecognizer(tutorialGesture) + tutorialGesture.addTarget(self, action: #selector(tappedTutorial(_:))) } - func setupAttribute() { - view.backgroundColor = .gray7 + private func checkTutorialHome() { + guard !UserDefaults.standard.bool(forKey: UDKey.tutorialHome.rawValue) else { return } + + activeTutorialMode() + } + + private func activeTutorialMode() { + emptyEffectView.isHidden = false + blurEffectViewForTutorial.isHidden = false + speechBubbleViewForColorExplain.isHidden = false + speechBubbleViewForCategoryExplain.isHidden = false + + presenter.categoryType = [ + ("취소", false), + ("식당", false), + ("카페", true), + ("술집", true), + ("빵집", false) + ] + categoryCollectionView.reloadData() + + updateSearchTextField(with: "카페") + updateSearchTextField(with: "술집") + + tabBarDelegate?.activeBlurEffectView(with: true) + } + + @objc private func tappedTutorial(_ gesture: UITapGestureRecognizer) { + emptyEffectView.isHidden = true + blurEffectViewForTutorial.isHidden = true + speechBubbleViewForColorExplain.isHidden = true + speechBubbleViewForCategoryExplain.isHidden = true + + presenter.categoryType = [ + ("식당", false), + ("카페", false), + ("술집", false), + ("빵집", false) + ] + + categoryCollectionView.reloadData() + + updateSearchTextField(with: "취소") + + UserDefaults.standard.set( + true, + forKey: UDKey.tutorialHome.rawValue + ) + + tabBarDelegate?.activeBlurEffectView(with: false) + tabBarDelegate?.activeCheckWellcome() } func setupGesture() { @@ -1095,6 +1202,10 @@ extension HomeViewController { placeView.pushReviewWriteView = { [weak self] in self?.presenter.pushReviewWriteView() } + + placeView.deleteRequestButtonTapped = { [weak self] in + self?.presenter.checkReportPlaceDuplecated() + } } } @@ -1401,7 +1512,7 @@ extension HomeViewController: UICollectionViewDataSource { cell.whenCategoryButtonTapped = { [weak self] (selectedType, selectedState) in self?.updateSearchTextField(with: selectedType) - self?.presenter.whenUpdateType = (selectedType, selectedState) + self?.presenter.whenCategoryUpdateType = (selectedType, selectedState) } return cell @@ -1418,14 +1529,6 @@ extension HomeViewController: UICollectionViewDataSource { } else { selectedCategoriesPlaceHolder.append(type) } - - if selectedCategoriesPlaceHolder.count > 0 { - // 배열에 있는 모든 항목을 콤마로 구분하여 placeholder에 설정합니다. - searchTextField.placeholder = selectedCategoriesPlaceHolder.joined(separator: ", ") - } else { - // 모든 type의 선택이 false일 때 - searchTextField.placeholder = Text.searchPlaceHolder.rawValue - } } } diff --git a/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/PlaceView.swift b/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/PlaceView.swift index adc7530f..605443ed 100644 --- a/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/PlaceView.swift +++ b/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/PlaceView.swift @@ -73,6 +73,7 @@ final class PlaceView: UIView { var whenBeforeEditMyReview: ((String, String) -> Void)? var pushReviewWriteView: (() -> Void)? + var deleteRequestButtonTapped: (() -> Void)? override init(frame: CGRect) { super.init(frame: frame) @@ -241,6 +242,10 @@ final class PlaceView: UIView { segmentedControlView.pushReviewWriteView = { [weak self] in self?.pushReviewWriteView?() } + + segmentedControlView.deleteRequestButtonTapped = { [weak self] in + self?.deleteRequestButtonTapped?() + } } // func keyboardWillShow(notification: NSNotification, height: CGFloat) { diff --git a/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/SubView/PlaceSegmentedControlView.swift b/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/SubView/PlaceSegmentedControlView.swift index 80eae9d7..6a83b46b 100644 --- a/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/SubView/PlaceSegmentedControlView.swift +++ b/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/SubView/PlaceSegmentedControlView.swift @@ -81,6 +81,9 @@ final class PlaceSegmentedControlView: UIView { var pushReviewWriteView: (() -> Void)? + // delete request + var deleteRequestButtonTapped: (() -> Void)? + override init(frame: CGRect) { super.init(frame: frame) @@ -191,15 +194,7 @@ final class PlaceSegmentedControlView: UIView { whenActiveSegmentedChanged() } - -// func keyboardWillShow(notification: NSNotification, height: CGFloat) { -// reviewView.keyboardWillShow(notification: notification, height: height) -// } -// -// func keyboardWillHide() { -// reviewView.keyboardWillHide() -// } -// + func allDataBinding(placeId: String, infoModel: AVIROPlaceInfo?, menuModel: AVIROPlaceMenus?, @@ -388,6 +383,10 @@ final class PlaceSegmentedControlView: UIView { // self?.reviewView.autoStartWriteComment() } + homeView.deleteRequestButtonTapped = { [weak self] in + self?.deleteRequestButtonTapped?() + } + reviewView.whenUploadReview = { [weak self] postReviewModel in self?.reviewsCount += 1 self?.homeView.updateReview(postReviewModel) diff --git a/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/SubView/SegmentedControlSubView/PlaceHomeView.swift b/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/SubView/SegmentedControlSubView/PlaceHomeView.swift index a14bacdf..e0fb8979 100644 --- a/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/SubView/SegmentedControlSubView/PlaceHomeView.swift +++ b/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/SubView/SegmentedControlSubView/PlaceHomeView.swift @@ -13,6 +13,7 @@ final class PlaceHomeView: UIView { private lazy var placeMenuView = PlaceMenuView() private lazy var placeReviewWriteView = PlaceReviewWriteView() private lazy var placeReviewsView = PlaceReviewsView() + private lazy var placeDeleteRequestView = PlaceDeleteRequestView() private var viewHeightConstraint: NSLayoutConstraint? @@ -32,6 +33,9 @@ final class PlaceHomeView: UIView { var showMoreReviewsAndWriteComment: (() -> Void)? var reportReview: ((AVIROReportReviewModel) -> Void)? var whenBeforeEditMyReview: ((String, String) -> Void)? + + // delete 클로저 + var deleteRequestButtonTapped: (() -> Void)? override init(frame: CGRect) { super.init(frame: frame) @@ -62,9 +66,10 @@ final class PlaceHomeView: UIView { [ placeInfoView, - placeMenuView, placeReviewWriteView, - placeReviewsView + placeMenuView, + placeReviewsView, + placeDeleteRequestView ].forEach { $0.translatesAutoresizingMaskIntoConstraints = false self.addSubview($0) @@ -75,17 +80,21 @@ final class PlaceHomeView: UIView { placeInfoView.leadingAnchor.constraint(equalTo: self.leadingAnchor), placeInfoView.trailingAnchor.constraint(equalTo: self.trailingAnchor), - placeMenuView.topAnchor.constraint(equalTo: placeInfoView.bottomAnchor, constant: 15), - placeMenuView.leadingAnchor.constraint(equalTo: self.leadingAnchor), - placeMenuView.trailingAnchor.constraint(equalTo: self.trailingAnchor), - - placeReviewWriteView.topAnchor.constraint(equalTo: placeMenuView.bottomAnchor, constant: 15), + placeReviewWriteView.topAnchor.constraint(equalTo: placeInfoView.bottomAnchor, constant: 15), placeReviewWriteView.leadingAnchor.constraint(equalTo: self.leadingAnchor), placeReviewWriteView.trailingAnchor.constraint(equalTo: self.trailingAnchor), - placeReviewsView.topAnchor.constraint(equalTo: placeReviewWriteView.bottomAnchor, constant: 15), + placeMenuView.topAnchor.constraint(equalTo: placeReviewWriteView.bottomAnchor, constant: 15), + placeMenuView.leadingAnchor.constraint(equalTo: self.leadingAnchor), + placeMenuView.trailingAnchor.constraint(equalTo: self.trailingAnchor), + + placeReviewsView.topAnchor.constraint(equalTo: placeMenuView.bottomAnchor, constant: 15), placeReviewsView.leadingAnchor.constraint(equalTo: self.leadingAnchor), - placeReviewsView.trailingAnchor.constraint(equalTo: self.trailingAnchor) + placeReviewsView.trailingAnchor.constraint(equalTo: self.trailingAnchor), + + placeDeleteRequestView.topAnchor.constraint(equalTo: placeReviewsView.bottomAnchor, constant: 15), + placeDeleteRequestView.leadingAnchor.constraint(equalTo: self.leadingAnchor), + placeDeleteRequestView.trailingAnchor.constraint(equalTo: self.trailingAnchor) ]) } @@ -94,11 +103,12 @@ final class PlaceHomeView: UIView { let menuHeight = placeMenuView.frame.height let reviewWriteHeight = placeReviewWriteView.frame.height let reviewsHeight = placeReviewsView.frame.height + let deleteRequestViewHeight = placeDeleteRequestView.frame.height + + // 15 15 15 15 + let inset: CGFloat = 60 - // 15 15 15 - let inset: CGFloat = 45 - - let totalHeight = infoHeight + menuHeight + reviewWriteHeight + reviewsHeight + inset + let totalHeight = infoHeight + menuHeight + reviewWriteHeight + reviewsHeight + inset + deleteRequestViewHeight viewHeightConstraint?.constant = totalHeight } @@ -177,5 +187,10 @@ final class PlaceHomeView: UIView { placeReviewsView.whenBeforeEditMyReview = { [weak self] (commentId, content) in self?.whenBeforeEditMyReview?(commentId, content) } + + // Place Delete Request View + placeDeleteRequestView.deleteRequestButtonTapped = { [weak self] in + self?.deleteRequestButtonTapped?() + } } } diff --git a/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/SubView/SegmentedControlSubView/SubView/PlaceDeleteRequestView.swift b/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/SubView/SegmentedControlSubView/SubView/PlaceDeleteRequestView.swift new file mode 100644 index 00000000..a26a2b11 --- /dev/null +++ b/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/SubView/SegmentedControlSubView/SubView/PlaceDeleteRequestView.swift @@ -0,0 +1,67 @@ +// +// PlaceDeleteRequestView.swift +// AVIRO +// +// Created by 전성훈 on 6/16/24. +// + +import UIKit + +final class PlaceDeleteRequestView: UIView { + private lazy var deleteRequestButton: EditInfoButton = { + let button = EditInfoButton() + + button.setButton("가게 삭제 요청하기") + button.tintColor = .warning + button.setTitleColor(.warning, for: .normal) + button.addTarget( + self, + action: #selector(editButtonTapped(_:)), + for: .touchUpInside + ) + + return button + }() + + private var viewHeightConstraint: NSLayoutConstraint? + var deleteRequestButtonTapped: (() -> Void)? + + override init(frame: CGRect) { + super.init(frame: frame) + + setupLayout() + setupAttribute() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + } + + private func setupLayout() { + [ + deleteRequestButton + ].forEach { + $0.translatesAutoresizingMaskIntoConstraints = false + self.addSubview($0) + } + + viewHeightConstraint = self.heightAnchor.constraint(equalToConstant: 60) + viewHeightConstraint?.isActive = true + + NSLayoutConstraint.activate([ + deleteRequestButton.widthAnchor.constraint(equalToConstant: 130), + deleteRequestButton.heightAnchor.constraint(equalToConstant: 20), + deleteRequestButton.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 16), + deleteRequestButton.topAnchor.constraint(equalTo: self.topAnchor, constant: 20), + deleteRequestButton.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -20) + ]) + } + + private func setupAttribute() { + self.backgroundColor = .gray7 + } + + @objc private func editButtonTapped(_ sender: UIButton) { + deleteRequestButtonTapped?() + } +} diff --git a/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/SubView/SegmentedControlSubView/SubView/PlaceReviewsView.swift b/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/SubView/SegmentedControlSubView/SubView/PlaceReviewsView.swift index c087443f..145bb172 100644 --- a/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/SubView/SegmentedControlSubView/SubView/PlaceReviewsView.swift +++ b/AVIRO/Scene/Feature/Home/ViewController/PlaceDetailView/SubView/SegmentedControlSubView/SubView/PlaceReviewsView.swift @@ -92,13 +92,7 @@ final class PlaceReviewsView: UIView { private var cellHeights: [IndexPath: CGFloat] = [:] - private var reviewsArray = [AVIROReviewRawData]() { - didSet { - reviewsArray.forEach { - print($0.content) - } - } - } + private var reviewsArray = [AVIROReviewRawData]() private var whenReviewView = false diff --git a/AVIRO/Scene/Feature/Home/ViewPresenter/HomeViewPresenter.swift b/AVIRO/Scene/Feature/Home/ViewPresenter/HomeViewPresenter.swift index b3e89983..e366d60f 100644 --- a/AVIRO/Scene/Feature/Home/ViewPresenter/HomeViewPresenter.swift +++ b/AVIRO/Scene/Feature/Home/ViewPresenter/HomeViewPresenter.swift @@ -109,9 +109,9 @@ final class HomeViewPresenter: NSObject { ] // TODO: - 문서화 & 리팩토링 필요 - var whenUpdateType = ("", false) { + var whenCategoryUpdateType = ("", false) { didSet { - if whenUpdateType.0 == "취소" { + if whenCategoryUpdateType.0 == "취소" { for index in 1..