From f65e4d22b5655bce63f87a15c25c324d627f83ed Mon Sep 17 00:00:00 2001 From: Hwang Sang Hwan <137605270+Hrepay@users.noreply.github.com> Date: Tue, 1 Sep 2026 10:03:52 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[#455]=20=EC=B0=A9=ED=95=9C=EA=B0=80?= =?UTF-8?q?=EA=B2=A9=EC=97=85=EC=86=8C=20=EC=83=81=EC=84=B8=EC=9D=98=20?= =?UTF-8?q?=EC=84=9C=EB=B2=84=20=EC=A7=80=EB=8F=84=20URL=20=EC=97=B0?= =?UTF-8?q?=EB=8F=99=20=EB=B0=8F=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=EC=97=85=EC=86=8C=20=ED=94=8C=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=ED=99=80=EB=8D=94=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GoodPriceStore/GoodPriceStoreDTO.swift | 2 ++ .../GoodPriceDetailSheetViewController.swift | 30 +++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/EATSSU/App/Sources/Data/Network/DTO/GoodPriceStore/GoodPriceStoreDTO.swift b/EATSSU/App/Sources/Data/Network/DTO/GoodPriceStore/GoodPriceStoreDTO.swift index 398a7f24..5c5f48de 100644 --- a/EATSSU/App/Sources/Data/Network/DTO/GoodPriceStore/GoodPriceStoreDTO.swift +++ b/EATSSU/App/Sources/Data/Network/DTO/GoodPriceStore/GoodPriceStoreDTO.swift @@ -25,4 +25,6 @@ struct GoodPriceStoreDetailDTO: Codable { let price: Int? let roadAddress: String? let imageUrl: String? + let naverMapUrl: String? + let kakaoMapUrl: String? } diff --git a/EATSSU/App/Sources/Presentation/Map/ViewController/GoodPriceDetailSheetViewController.swift b/EATSSU/App/Sources/Presentation/Map/ViewController/GoodPriceDetailSheetViewController.swift index 794c0b80..ccbdd3cb 100644 --- a/EATSSU/App/Sources/Presentation/Map/ViewController/GoodPriceDetailSheetViewController.swift +++ b/EATSSU/App/Sources/Presentation/Map/ViewController/GoodPriceDetailSheetViewController.swift @@ -26,7 +26,7 @@ final class GoodPriceDetailSheetViewController: BaseViewController { // MARK: - Properties private let store: GoodPriceStoreDTO - private let mapAppLauncher: MapAppLauncher + private var mapAppLauncher: MapAppLauncher // MARK: - UI Components @@ -44,7 +44,7 @@ final class GoodPriceDetailSheetViewController: BaseViewController { init(store: GoodPriceStoreDTO) { self.store = store - // 착한가격업소는 서버가 지도 URL을 주지 않으므로 상호명 + 좌표 기반 검색으로 연결 + // 지도 URL은 상세 응답에만 있어, 상세 로드 전까지는 상호명 + 좌표 기반 검색으로 연결 self.mapAppLauncher = MapAppLauncher(destination: .init( name: store.storeName, latitude: store.latitude, @@ -185,7 +185,25 @@ final class GoodPriceDetailSheetViewController: BaseViewController { menuLabel.text = Self.menuText(menu: detail.mainMenu, price: detail.price) menuLabel.isHidden = menuLabel.text == nil - storeImageView.kfSetImage(url: detail.imageUrl) + // 상세 응답의 지도 URL로 런처 교체. URL이 없는 업소는 기존 검색 폴백 그대로 동작한다 + mapAppLauncher = MapAppLauncher(destination: .init( + name: detail.storeName, + latitude: store.latitude, + longitude: store.longitude, + kakaoMapUrl: Self.nonEmpty(detail.kakaoMapUrl), + naverMapUrl: Self.nonEmpty(detail.naverMapUrl) + )) + + if let imageUrl = Self.nonEmpty(detail.imageUrl) { + storeImageView.contentMode = .scaleAspectFill + storeImageView.kfSetImage(url: imageUrl) + } else { + // 이미지가 없는 업소는 카테고리 아이콘을 회색으로 중앙에 표시 + storeImageView.contentMode = .center + storeImageView.tintColor = .gray400 + storeImageView.image = MainMapViewController.goodPriceIcon(for: detail.category) + .withRenderingMode(.alwaysTemplate) + } if #available(iOS 16.0, *) { sheetPresentationController?.animateChanges { @@ -194,6 +212,12 @@ final class GoodPriceDetailSheetViewController: BaseViewController { } } + /// 빈 문자열을 nil로 정규화 + private static func nonEmpty(_ value: String?) -> String? { + guard let value = value?.trimmingCharacters(in: .whitespacesAndNewlines), !value.isEmpty else { return nil } + return value + } + /// "메뉴명 가격원" 형태로 조합. 둘 다 없으면 nil private static func menuText(menu: String?, price: Int?) -> String? { let menuPart = menu?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "" From 971d50f6a93f75da2aceed3732a62f48223e2050 Mon Sep 17 00:00:00 2001 From: Hwang Sang Hwan <137605270+Hrepay@users.noreply.github.com> Date: Tue, 1 Sep 2026 10:43:57 +0900 Subject: [PATCH 2/2] =?UTF-8?q?[#455]=20=EC=A7=80=EB=8F=84=20URL=20?= =?UTF-8?q?=EC=97=86=EB=8A=94=20=EC=97=85=EC=86=8C=EB=8A=94=20=ED=95=B4?= =?UTF-8?q?=EB=8B=B9=20=EC=A7=80=EB=8F=84=20=EB=B2=84=ED=8A=BC=20=EB=B9=84?= =?UTF-8?q?=ED=99=9C=EC=84=B1=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/Map/View/MapAppButtonBar.swift | 16 ++++++++++++++++ .../GoodPriceDetailSheetViewController.swift | 10 +++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/EATSSU/App/Sources/Presentation/Map/View/MapAppButtonBar.swift b/EATSSU/App/Sources/Presentation/Map/View/MapAppButtonBar.swift index 47c5886c..8ecb2089 100644 --- a/EATSSU/App/Sources/Presentation/Map/View/MapAppButtonBar.swift +++ b/EATSSU/App/Sources/Presentation/Map/View/MapAppButtonBar.swift @@ -79,6 +79,22 @@ final class MapAppButtonBar: BaseUIView { } } + // MARK: - State + + /// 서버에 해당 지도 링크가 없는 업소는 버튼을 비활성(흐림 + 탭 무시) 처리한다 + func setKakaoMapEnabled(_ isEnabled: Bool) { + apply(isEnabled, to: kakaoMapButton) + } + + func setNaverMapEnabled(_ isEnabled: Bool) { + apply(isEnabled, to: naverMapButton) + } + + private func apply(_ isEnabled: Bool, to button: UIButton) { + button.isEnabled = isEnabled + button.alpha = isEnabled ? 1.0 : 0.35 + } + // MARK: - Actions @objc private func kakaoMapButtonTapped() { diff --git a/EATSSU/App/Sources/Presentation/Map/ViewController/GoodPriceDetailSheetViewController.swift b/EATSSU/App/Sources/Presentation/Map/ViewController/GoodPriceDetailSheetViewController.swift index ccbdd3cb..89ee965e 100644 --- a/EATSSU/App/Sources/Presentation/Map/ViewController/GoodPriceDetailSheetViewController.swift +++ b/EATSSU/App/Sources/Presentation/Map/ViewController/GoodPriceDetailSheetViewController.swift @@ -185,14 +185,18 @@ final class GoodPriceDetailSheetViewController: BaseViewController { menuLabel.text = Self.menuText(menu: detail.mainMenu, price: detail.price) menuLabel.isHidden = menuLabel.text == nil - // 상세 응답의 지도 URL로 런처 교체. URL이 없는 업소는 기존 검색 폴백 그대로 동작한다 + // 상세 응답의 지도 URL로 런처 교체. URL이 없는 지도 버튼은 비활성 처리한다 + let kakaoMapUrl = Self.nonEmpty(detail.kakaoMapUrl) + let naverMapUrl = Self.nonEmpty(detail.naverMapUrl) mapAppLauncher = MapAppLauncher(destination: .init( name: detail.storeName, latitude: store.latitude, longitude: store.longitude, - kakaoMapUrl: Self.nonEmpty(detail.kakaoMapUrl), - naverMapUrl: Self.nonEmpty(detail.naverMapUrl) + kakaoMapUrl: kakaoMapUrl, + naverMapUrl: naverMapUrl )) + mapAppButtonBar.setKakaoMapEnabled(kakaoMapUrl != nil) + mapAppButtonBar.setNaverMapEnabled(naverMapUrl != nil) if let imageUrl = Self.nonEmpty(detail.imageUrl) { storeImageView.contentMode = .scaleAspectFill