스파르타 코딩 클럽 - iOS 스타터 6기/본 캠프

43. 스파르타 코딩 클럽 - 킥보드 대여 앱 만들기 (5)

seongpil Heo 2025. 5. 1. 23:08

  🧑‍💻  숙련 주차 팀 프로젝트

오늘은 팀 프로젝트 5일 차이다.

오늘 할 작업은 3가지이다.

 

첫째 등록 화면에서 사용자가 터치한 부분에 임시 마커를 등록하고,

사용자가 터치한 부분의 위도와 경도를 받아와서 등록하기 버튼을 누르면 임시 마커가 사라지고,

킥보드 마커가 등록되게 하는 것

 

둘째 등록화면에서 등록된 마커를 클릭하면 삭제를 할 수 있는 Alert 창을 띄우고 삭제 버튼을 클릭하면

선택한 마커를 지도에서 삭제한다.

 

셋째 프로젝트 README 작성하기이다.


  📍  임시 마커 등록하기

[ 1. AddViewController에 NMFMapViewTouchDelegate 채택 ]

// 지도 터치 이벤트를 위한 NMFMapViewTouchDelegate 채택
class AddViewController: UIViewController, NMFMapViewTouchDelegate {
	
    // 임시 마커 변수 인스턴스 생성
    let tempMarker = NMFMarker()
}

 

[2. 지도를 클릭하면 호출되는 델리게이트 메서드 구현 ]

// 지도를 클릭하면 호출되는 델리게이트 메서드
func mapView(_ mapView: NMFMapView, didTapMap latlng: NMGLatLng, point: CGPoint) {
    
    // 사용자가 클릭한 부분의 위도와 경도 받아오기
    let lat = latlng.lat
    let lon = latlng.lng

    print("지도 클릭 : 위도 \(lat), 경도 \(lon)")

	// 받아온 위도와 경도를 textField에 입력하기
    xTextField.text = "\(lat)"
    yTextField.text = "\(lon)"

	// 받아온 위도와 경도 위치에 임시 마커 등록하기
    tempMarker.position = NMGLatLng(lat: lat, lng: lon)
    tempMarker.iconImage = NMFOverlayImage(name: "tempMarkerImage")
    
    // 포인터 위치를 조절
    tempMarker.anchor = CGPoint(x: -1, y: -1)
    
    // mapView에 등록
    tempMarker.mapView = mapView
}

 

[ 3. 등록하기 버튼을 누르면 임시 마커를 삭제 ]

private func displayKickBoardMarkers(on mapView: NMFMapView, with data: [KickBoardModel]) {
        
        // 임시 마커를 mapView에서 삭제
        tempMarker.mapView = nil
        
        ...
    }

 

[ 4. 시뮬레이터 실행 화면 ]


  ❌  등록된 마커 삭제하기

[ 1. 마커 클릭 이벤트 핸들러 구현 ]

// 지도에 마커를 추가하는 함수
private func displayKickBoardMarkers(on mapView: NMFMapView, with data: [KickBoardModel]) {
    tempMarker.mapView = nil
    for marker in markers {
        marker.mapView = nil
    }
    markers.removeAll()

    // 받아온 킥보드 데이터를 이용하여 마커 생성
    for kickBoard in data {
        let marker = NMFMarker()
        marker.position = NMGLatLng(lat: kickBoard.lat, lng: kickBoard.lon)
        marker.iconImage = NMFOverlayImage(name: "markerImage")
        marker.mapView = mapView

		// 마커 클릭 이벤트 핸들러
        marker.touchHandler = { [weak self] (overlay: NMFOverlay) -> Bool in
            guard let self = self else { return false }

            
    }
}

 

 

[ 2. 이벤트 핸들러 안에 Alert를 사용하여 삭제하는 로직 구현 ]

// 마커들을 담을 배열 선언
var markers: [NMFMarker] = []

// 지도에 마커를 추가하는 함수
private func displayKickBoardMarkers(on mapView: NMFMapView, with data: [KickBoardModel]) {

    // 임시 마커 삭제
    tempMarker.mapView = nil

    // 이전 마커 초기화 하기
    for marker in markers {
        marker.mapView = nil
    }

    // markers 배열 초기화
    markers.removeAll()

    // 받아온 킥보드 데이터를 이용하여 마커 생성
    for kickBoard in data {
        let marker = NMFMarker()
        marker.position = NMGLatLng(lat: kickBoard.lat, lng: kickBoard.lon)
        marker.iconImage = NMFOverlayImage(name: "markerImage")
        marker.mapView = mapView

        // 마커 터치 이벤트 핸들러
        marker.touchHandler = { [weak self] (overlay: NMFOverlay) -> Bool in
            guard let self = self else { return false }

            // 터치 이벤트에서 클릭된 마커의 정보를 가져온다.
            let alert = UIAlertController(
                title: "킥보드 정보",
                message: "\(kickBoard.id)번 킥보드\n위도: \(kickBoard.lat)\n경도: \(kickBoard.lon)",
                preferredStyle: .alert
            )

            // 삭제 버튼
            let deleteAction = UIAlertAction(title: "삭제", style: .destructive) { _ in
                // 코어데이터에서 deleteData 메서드를 실행해서 선택된 킥보드의 id 값으로 삭제 처리
                self.coredata.deleteData(id: kickBoard.id)
                // 삭제 후 데이터 재 로드
                self.readData()
                // 로드 후 마커 다시 지도에 보여주기
                self.displayKickBoardMarkers(on: self.mapView, with: self.kickBoardData)

                // 삭제 후 뜨는 알러트
                let completionAlert = UIAlertController(
                    title: "삭제 완료",
                    message: "\(kickBoard.id)번 킥보드가 삭제되었습니다.",
                    preferredStyle: .alert
                )
                completionAlert.addAction(UIAlertAction(title: "확인", style: .default))
                self.present(completionAlert, animated: true)
            }

            // 취소 버튼
            let cancleAction = UIAlertAction(title: "취소", style: .default)

            alert.addAction(cancleAction)
            alert.addAction(deleteAction)

            self.present(alert, animated: true)

            return true
        }

    // markers 배열에 추가
    markers.append(marker)
    }
}

 

[ 3. 시뮬레이터 실행 화면 ]


  📝  READ ME 작성하기

 

 

SwiftKickBoard/README.md at dev · heopill/SwiftKickBoard

Sparta Team 2 Repository. Contribute to heopill/SwiftKickBoard development by creating an account on GitHub.

github.com

 

내가 작성한 READ ME 궁금하면 링크가서 봐주세요