iOS/UIKIT

알림창 안에 맵 넣기

밤새는 탐험가89 2024. 2. 1. 15:28

 

 

 

 

 

먼저 UIViewController 타입의 "MapAlertViewController" 파일 생성 및

메인 스토리보드의 class로 설정

 

"MapAlertViewController" 파일 내에 버튼 추가 

 

import UIKit

class MapAlertViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // 버튼 생성
        let alertBtn = UIButton(type: .system)
        
        
        // 버튼 속성 설정
        alertBtn.frame = CGRect(x: 0, y: 150, width: 100, height: 30)
        alertBtn.center.x = self.view.frame.width / 2
        alertBtn.setTitle("Map Alert", for: .normal)
        alertBtn.addTarget(self, action: #selector(mapAlert(_:)), for: .touchUpInside)
        
        self.view.addSubview(alertBtn)
    }
    
    @objc func mapAlert(_ sender: UIButton) {

    }
}

 

 

mapAlert(_: ) 메소드 내에 경고창 실행 코드 작성 및 

생성된 뷰 컨트롤러 인스턴스의 루트 뷰에 맵킷 뷰 지정

 

@objc func mapAlert(_ sender: UIButton) {
        
        // 경고창 객체 생성, OK 및 Cancel 버튼 추가
        let alert = UIAlertController(title: nil, message: "여기가 맞습니까?", preferredStyle: .alert)
        
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
        let okAction = UIAlertAction(title: "Ok", style: .default)
        
        alert.addAction(cancelAction)
        alert.addAction(okAction)
        
        
        // 추가 구문) 시작
        // 콘텐츠 뷰 영역에 들어갈 뷰 컨트롤러를 생성, 알림창 등록
        let contentVC = MapkitViewController()

        
        // 뷰 컨트롤러에 맵킷 뷰를 추가
        let mapkitView = MKMapView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
        contentVC.view = mapkitView
        
        // 높이값 지정
        // 외부(여기서는 알림창)에서 뷰 컨트롤러를 읽어들일 때 참고하는 사이즈
        contentVC.preferredContentSize.height = 200
    
        
        // 뷰 컨트롤러를 알림창의 콘텐츠 뷰 컨트롤러 속성에 등록
        alert.setValue(contentVC, forKeyPath: "contentViewController")
        
        self.present(alert, animated: false)
    }

 

 

여기서 contentVC는 알림창의 콘텐츠 뷰 컨틀로러 역할을 할 객체임

 

mapkitView의 frame 부분을 보면 x: 0, y:0, width: 0, heigth:0 인 걸 볼 수 있음

이는 cotentVC.view = mapkitView 로 선언했기 때문임 

(= 맵킷 뷰를 루트 뷰로 설정)

 

따라서 루트 뷰는 항상 화면 전체를 채우는 방식이로 크기가 자동 지정됨

 

 

 

추가로 맵킷이 지도를 상세하게 표현할 수 있도록 

축척과 핀 관련 속성 추가 

 

@objc func mapAlert(_ sender: UIButton) {

        ... 생략 ...
        // 추가 구문) 시작
        // 콘텐츠 뷰 영역에 들어갈 뷰 컨트롤러를 생성, 알림창 등록
        let contentVC = MapkitViewController()

        
        // 뷰 컨트롤러에 맵킷 뷰를 추가
        let mapkitView = MKMapView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
        contentVC.view = mapkitView
        
        // -------- 여기서부터 시작---------------
        
        // 위치 정보를 설정 (위도, 경도 사용)
        let pos = CLLocationCoordinate2D(latitude: 37.514322, longitude: 126.894623)
        
        // 지도에서 보여줄 넓이, 일종의 축척, 숫자가 작을 수록 좁은 범위를 확대시킴
        let span = MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005)
        
        // 지도 영역을 정의
        let region = MKCoordinateRegion(center: pos, span: span)
        
        // 지도 뷰에 표시
        mapkitView.region = region
        mapkitView.regionThatFits(region)
        
        // 위치를 핀으로 표시
        let point = MKPointAnnotation()
        point.coordinate = pos
        mapkitView.addAnnotation(point)
        
        
        // 높이값 지정
        // 외부(여기서는 알림창)에서 뷰 컨트롤러를 읽어들일 때 참고하는 사이즈
        contentVC.preferredContentSize.height = 200
    
        // -------- 여기까지---------------
        
        // 뷰 컨트롤러를 알림창의 콘텐츠 뷰 컨트롤러 속성에 등록
        alert.setValue(contentVC, forKeyPath: "contentViewController")
        
        self.present(alert, animated: false)
    }

 

추가로 preferredContentSize.height을 통해 

알림창이 contentVC 객체의 정보를 읽어들일 때 

표현해야 할 크기가 얼마인지 계산함