Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Check/modal/infobox/ico/line.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Marker/UnTapMarker/search/ico/solid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Marker/search/ico/solid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
80 changes: 48 additions & 32 deletions Poppool/Poppool.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,6 @@
4EE5A3D32D40E4A600A2469A /* MapGuideReactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EE5A3D22D40E4A600A2469A /* MapGuideReactor.swift */; };
4EEA1D8F2D352012003E7DE9 /* ImageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EEA1D8E2D352012003E7DE9 /* ImageCell.swift */; };
4EEA1D912D352027003E7DE9 /* ExtendedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EEA1D902D352027003E7DE9 /* ExtendedImage.swift */; };
4EEA1D952D358B23003E7DE9 /* PopUpStoreRegisterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EEA1D942D358B23003E7DE9 /* PopUpStoreRegisterView.swift */; };
4EECA3932D5676C900A07CCA /* MapGuideViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E9790C42D40E13500210499 /* MapGuideViewController.swift */; };
4EECA3942D56770B00A07CCA /* MapPopUpStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E685EBB2D12CEB6001EF91C /* MapPopUpStore.swift */; };
4EED9BAC2D22730400B288E7 /* FilterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EED9BAB2D22730400B288E7 /* FilterType.swift */; };
BD226D512CF6DB290038C984 /* PPReturnHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD226D502CF6DB290038C984 /* PPReturnHeaderView.swift */; };
Expand Down Expand Up @@ -921,8 +919,6 @@
4EE5A3D22D40E4A600A2469A /* MapGuideReactor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapGuideReactor.swift; sourceTree = "<group>"; };
4EEA1D8E2D352012003E7DE9 /* ImageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageCell.swift; sourceTree = "<group>"; };
4EEA1D902D352027003E7DE9 /* ExtendedImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtendedImage.swift; sourceTree = "<group>"; };
4EEA1D922D358839003E7DE9 /* PopUpStoreRegisterReactor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopUpStoreRegisterReactor.swift; sourceTree = "<group>"; };
4EEA1D942D358B23003E7DE9 /* PopUpStoreRegisterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopUpStoreRegisterView.swift; sourceTree = "<group>"; };
4EED9BAB2D22730400B288E7 /* FilterType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterType.swift; sourceTree = "<group>"; };
BD226D502CF6DB290038C984 /* PPReturnHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PPReturnHeaderView.swift; sourceTree = "<group>"; };
BD91034E2CF6149D00BBCCAE /* AuthAPIEndPoint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthAPIEndPoint.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2711,7 +2707,7 @@
path = UseCase;
sourceTree = "<group>";
};
4E685EBD2D12CEB6001EF91C /* MapAPI */ = {
4E685EBD2D12CEB6001EF91C /* MapDomain */ = {
isa = PBXGroup;
children = (
4E685EB72D12CEB6001EF91C /* Repository */,
Expand All @@ -2720,7 +2716,7 @@
4E685EBB2D12CEB6001EF91C /* MapPopUpStore.swift */,
4E685EBC2D12CEB6001EF91C /* MapPopUpStoreDTO.swift */,
);
path = MapAPI;
path = MapDomain;
sourceTree = "<group>";
};
4E685EC02D12CEB6001EF91C /* MapPopupCardView */ = {
Expand All @@ -2747,22 +2743,10 @@
4E685ECD2D12CEB6001EF91C /* Map */ = {
isa = PBXGroup;
children = (
4EED9BAA2D2272F500B288E7 /* Common */,
4EC23F432D6F7E6D00558673 /* MapView */,
4E685EB52D12CEB6001EF91C /* FillterSheetView */,
4E685EBD2D12CEB6001EF91C /* MapAPI */,
4E685EC02D12CEB6001EF91C /* MapPopupCardView */,
4E685EC52D12CEB6001EF91C /* StoreListView */,
4E685EC62D12CEB6001EF91C /* MapFilterChips.swift */,
4E8AA29C2D59A2340029DF75 /* MarkerTooltipView.swift */,
4E685EC72D12CEB6001EF91C /* MapMarker.swift */,
4E685EC82D12CEB6001EF91C /* MapReactor.swift */,
4E685EC92D12CEB6001EF91C /* MapSearchInput.swift */,
4E685ECB2D12CEB6001EF91C /* MapView.swift */,
4E685ECC2D12CEB6001EF91C /* MapViewController.swift */,
4E6C07052D4B6E56008A962A /* RegionDefinitions.swift */,
4E6C07072D4B6E74008A962A /* ClusteringModels.swift */,
4E9A465F2D55D1270010578A /* MapUtilities.swift */,
4E6C07092D4B6E81008A962A /* ClusteringManager.swift */,
4EED9BAA2D2272F500B288E7 /* Common */,
4EE5A3D12D40E3B100A2469A /* FindMap */,
);
path = Map;
Expand All @@ -2777,21 +2761,36 @@
4E755B242D2B9C6C00ADFB21 /* AdminView.swift */,
4E755B262D2B9C7C00ADFB21 /* AdminStoreCell.swift */,
4E755B282D2BA65A00ADFB21 /* AdminReactor.swift */,
4E9405302D6F7C790002B590 /* AdminRegister */,
4E94052F2D6F7C670002B590 /* AdminBottomSheet */,
4EEA1D8E2D352012003E7DE9 /* ImageCell.swift */,
4EDDEFB22D2D284B00CFAFA5 /* Common */,
);
path = Admin;
sourceTree = "<group>";
};
4E94052F2D6F7C670002B590 /* AdminBottomSheet */ = {
isa = PBXGroup;
children = (
4E9C12772D2BC7A0006744D6 /* AdminBottomSheetView.swift */,
4E9C12792D2BC811006744D6 /* AdminBottomSheetViewController.swift */,
4E6CA4842D34D6ED0034D09A /* AdminBottomSheetReactor.swift */,
);
path = AdminBottomSheet;
sourceTree = "<group>";
};
4E9405302D6F7C790002B590 /* AdminRegister */ = {
isa = PBXGroup;
children = (
4E9C12802D2BE0A6006744D6 /* PopUpStoreRegisterViewController.swift */,
4EEA1D942D358B23003E7DE9 /* PopUpStoreRegisterView.swift */,
4EEA1D922D358839003E7DE9 /* PopUpStoreRegisterReactor.swift */,
4EEA1D8E2D352012003E7DE9 /* ImageCell.swift */,
4EDDEFB22D2D284B00CFAFA5 /* Common */,
);
path = Admin;
path = AdminRegister;
sourceTree = "<group>";
};
4E9C127B2D2BCFE4006744D6 /* Data */ = {
isa = PBXGroup;
children = (
4E685EBD2D12CEB6001EF91C /* MapDomain */,
4E9C127E2D2BD012006744D6 /* Remote */,
4E9C127D2D2BD007006744D6 /* Repository */,
4E9C127C2D2BCFF1006744D6 /* DTO */,
Expand Down Expand Up @@ -2832,16 +2831,31 @@
path = Domain;
sourceTree = "<group>";
};
4EA2C93B2D424D2600F4D97C /* New Group */ = {
4EA2C93B2D424D2600F4D97C /* MapGuideView */ = {
isa = PBXGroup;
children = (
4E6A066F2D42A96100B2A658 /* FullScreenMapViewController.swift */,
4EA2C93C2D424D3300F4D97C /* MapDirectionRepository.swift */,
4EA2C93E2D424D7400F4D97C /* MapDirectionUseCase.swift */,
4EA2C9402D424D8400F4D97C /* GetPopUpDirectionResponseDTO.swift */,
4E9790C42D40E13500210499 /* MapGuideViewController.swift */,
4EE5A3D22D40E4A600A2469A /* MapGuideReactor.swift */,
4EA2C9422D424DF900F4D97C /* FindDirectionEndPoint.swift */,
);
path = "New Group";
path = MapGuideView;
sourceTree = "<group>";
};
4EC23F432D6F7E6D00558673 /* MapView */ = {
isa = PBXGroup;
children = (
4E8AA29C2D59A2340029DF75 /* MarkerTooltipView.swift */,
4E685EC72D12CEB6001EF91C /* MapMarker.swift */,
4E685EC82D12CEB6001EF91C /* MapReactor.swift */,
4E685EC92D12CEB6001EF91C /* MapSearchInput.swift */,
4E685ECB2D12CEB6001EF91C /* MapView.swift */,
4E685ECC2D12CEB6001EF91C /* MapViewController.swift */,
);
path = MapView;
sourceTree = "<group>";
};
4EDDEFB22D2D284B00CFAFA5 /* Common */ = {
Expand All @@ -2856,9 +2870,7 @@
4EE5A3D12D40E3B100A2469A /* FindMap */ = {
isa = PBXGroup;
children = (
4EA2C93B2D424D2600F4D97C /* New Group */,
4E9790C42D40E13500210499 /* MapGuideViewController.swift */,
4EE5A3D22D40E4A600A2469A /* MapGuideReactor.swift */,
4EA2C93B2D424D2600F4D97C /* MapGuideView */,
);
path = FindMap;
sourceTree = "<group>";
Expand All @@ -2869,7 +2881,13 @@
4EAB809C2D3F78AA0041AF30 /* GMSMapViewDelegateProxy.swift */,
4EAB809E2D3F8EF50041AF30 /* ViewportBounds.swift */,
4EED9BAB2D22730400B288E7 /* FilterType.swift */,
4E6C07052D4B6E56008A962A /* RegionDefinitions.swift */,
4E685EC62D12CEB6001EF91C /* MapFilterChips.swift */,
4E9A465F2D55D1270010578A /* MapUtilities.swift */,
4E6C07092D4B6E81008A962A /* ClusteringManager.swift */,
4E6C07072D4B6E74008A962A /* ClusteringModels.swift */,
4EDE57022D5E70650014D924 /* LocationPermissionBottomSheet.swift */,
4E685EC02D12CEB6001EF91C /* MapPopupCardView */,
);
path = Common;
sourceTree = "<group>";
Expand Down Expand Up @@ -3321,7 +3339,6 @@
08B191B82CF6092F0057BC04 /* AuthServiceable.swift in Sources */,
0841BAB82CFAC41300049E31 /* SectionBackGroundDecorationView.swift in Sources */,
086F89F52D2269E300CA4FC9 /* MyPageReactor.swift in Sources */,
4EEA1D952D358B23003E7DE9 /* PopUpStoreRegisterView.swift in Sources */,
089952682D046CD80022AEF9 /* SearchResultReactor.swift in Sources */,
BDCA41C52CF35AC0005EECF6 /* TestViewController.swift in Sources */,
086DD9402D01EEEB00B97D3B /* SearchCountTitleSection.swift in Sources */,
Expand Down Expand Up @@ -3669,7 +3686,6 @@
files = (
BDCA41E42CF35AC1005EECF6 /* PoppoolUITestsLaunchTests.swift in Sources */,
4E9A465E2D50B2DB0010578A /* AdminStoreCell.swift in Sources */,
4EECA3932D5676C900A07CCA /* MapGuideViewController.swift in Sources */,
BDCA41E22CF35AC1005EECF6 /* PoppoolUITests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ enum MapZoomLevel {
case ..<7:
return .country
case 7..<10:
return .city
case 10..<11:
return .district
return .city
case 10..<12: // 구 레벨 범위 확장 (10~12)
return .district
default:
return .detailed
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@ final class MapPopupCarouselView: UICollectionView {

private var popupCards: [MapPopUpStore] = []
private var currentIndex: Int = 0
var currentVisibleIndex: Int {

let centerX = self.contentOffset.x + self.bounds.width / 2

for i in 0..<self.numberOfItems(inSection: 0) {
guard let cell = self.cellForItem(at: IndexPath(item: i, section: 0)) else { continue }

if cell.frame.minX <= centerX && centerX <= cell.frame.maxX {
return i
}
}

// 없으면 첫 번째 인덱스 반환
return 0
}

// MARK: - Initialization
override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,27 +139,45 @@ final class BalloonBackgroundView: UIView {

override func draw(_ rect: CGRect) {
super.draw(rect)
let arrowWidth: CGFloat = 16
// let arrowHeight: CGFloat = 10

let arrowWidth: CGFloat = 12 // 화살표 너비 조정
let arrowHeight: CGFloat = 8 // 화살표 높이 조정

// 화살표의 시작 x좌표 계산
let arrowX = bounds.width * arrowPosition - (arrowWidth / 2)

// 경로 그리기
let path = UIBezierPath()
path.move(to: CGPoint(x: arrowX, y: arrowHeight))
path.addLine(to: CGPoint(x: arrowX + (arrowWidth / 2), y: 0))
path.addLine(to: CGPoint(x: arrowX + arrowWidth, y: arrowHeight))
let containerRect = CGRect(x: 0, y: arrowHeight, width: bounds.width, height: bounds.height - arrowHeight)
path.addLine(to: CGPoint(x: containerRect.maxX, y: containerRect.minY))
path.addLine(to: CGPoint(x: containerRect.maxX, y: containerRect.maxY))
path.addLine(to: CGPoint(x: containerRect.minX, y: containerRect.maxY))
path.addLine(to: CGPoint(x: containerRect.minX, y: containerRect.minY))

// 1. 화살표 그리기
path.move(to: CGPoint(x: arrowX, y: arrowHeight)) // 왼쪽 아래
path.addLine(to: CGPoint(x: arrowX + (arrowWidth / 2), y: 0)) // 상단 중앙
path.addLine(to: CGPoint(x: arrowX + arrowWidth, y: arrowHeight)) // 오른쪽 아래

// 2. 말풍선 본체 그리기
let balloonRect = CGRect(x: 0, y: arrowHeight,
width: bounds.width,
height: bounds.height - arrowHeight)

path.addLine(to: CGPoint(x: balloonRect.maxX, y: balloonRect.minY)) // 오른쪽 상단
path.addLine(to: CGPoint(x: balloonRect.maxX, y: balloonRect.maxY)) // 오른쪽 하단
path.addLine(to: CGPoint(x: balloonRect.minX, y: balloonRect.maxY)) // 왼쪽 하단
path.addLine(to: CGPoint(x: balloonRect.minX, y: balloonRect.minY)) // 왼쪽 상단

path.close()

UIColor.g50.setFill()
path.fill()
self.layer.shadowColor = UIColor.black.cgColor
self.layer.shadowOpacity = 0.1
self.layer.shadowOffset = CGSize(width: 0, height: 2)
self.layer.shadowRadius = 4

// 그림자 설정
// layer.shadowPath = path.cgPath
// layer.shadowColor = UIColor.black.cgColor
// layer.shadowOpacity = 0.1
// layer.shadowOffset = CGSize(width: 0, height: 2)
// layer.shadowRadius = 4
}


// MARK: - Public

/// configure 메서드
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ final class FilterBottomSheetView: UIView {
private var balloonHeightConstraint: Constraint?

// MARK: - Initialization

override init(frame: CGRect) {
super.init(frame: frame)
setupLayout()
Expand Down Expand Up @@ -383,13 +384,32 @@ final class FilterBottomSheetView: UIView {


func updateBalloonPosition(for button: UIButton) {
let buttonFrame = button.convert(button.bounds, to: self)
let buttonCenterX = buttonFrame.midX
let totalWidth = bounds.width
// window 좌표계로 변환
guard let window = button.window else { return }

balloonBackgroundView.arrowPosition = buttonCenterX / totalWidth
balloonBackgroundView.setNeedsDisplay()
// 1. 버튼과 말풍선의 window 기준 프레임 구하기
let buttonFrameInWindow = button.convert(button.bounds, to: window)
let balloonFrameInWindow = balloonBackgroundView.convert(balloonBackgroundView.bounds, to: window)

// 2. 버튼 중앙점의 x좌표
let buttonCenterX = buttonFrameInWindow.midX

// 3. 말풍선 기준으로 상대적 위치 계산
let relativeX = buttonCenterX - balloonFrameInWindow.minX

// 4. 말풍선 너비 기준으로 비율 계산 (0.0 ~ 1.0)
let position = relativeX / balloonBackgroundView.bounds.width

// 5. 경계값 처리 (화살표가 말풍선 영역을 벗어나지 않도록)
let minPosition: CGFloat = 0.1 // 왼쪽 여백
let maxPosition: CGFloat = 0.9 // 오른쪽 여백
let clampedPosition = min(maxPosition, max(minPosition, position))

// 6. 위치 업데이트 및 다시 그리기
balloonBackgroundView.arrowPosition = clampedPosition
balloonBackgroundView.setNeedsDisplay()
}

private func updateBalloonPositionAccurately(for button: PPButton) {
let buttonFrameInBalloon = button.convert(button.bounds, to: balloonBackgroundView)
let arrowPosition = buttonFrameInBalloon.midX / balloonBackgroundView.bounds.width
Expand All @@ -414,19 +434,15 @@ extension FilterBottomSheetView {
}
extension FilterBottomSheetView: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {

// 선택된 버튼 찾기
guard let selectedButton = locationContentView.subviews.first(where: { view in
guard let button = view as? PPButton else { return false }
return button.backgroundColor == .blu500
}) as? PPButton else {
return
}) as? PPButton else { return }

// 스크롤 중에도 실시간으로 위치 업데이트
DispatchQueue.main.async { [weak self] in
self?.updateBalloonPosition(for: selectedButton)
}

let buttonFrame = selectedButton.convert(selectedButton.bounds, to: balloonBackgroundView)

let arrowPosition = buttonFrame.midX / balloonBackgroundView.bounds.width

balloonBackgroundView.arrowPosition = arrowPosition
balloonBackgroundView.setNeedsDisplay()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ final class FullScreenMapViewController: MapViewController {
}

override func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {
// 지도 빈 공간 탭은 무시 (요구사항에 따라 추가 처리 가능)
// 지도 빈 공간 탭은 무시
}

private func findMarkerForStore(for store: MapPopUpStore) -> GMSMarker? {
Expand Down
Loading