Sample : iOS Custom Alert
CustomAlert_ios
1.contentViewController 를 이용한 Alert 커스텀
| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 | override func viewDidLoad() {
    super.viewDidLoad()
        
    //기본 알림창 버튼
    let defaultAlertbtn = UIButton(type: .system)
    defaultAlertbtn.frame = CGRect(x: 0 , y: 100, width: 100, height: 30)
    defaultAlertbtn.center.x = self.view.frame.width/2
    defaultAlertbtn.setTitle("커스텀 알림", for: .normal)
    defaultAlertbtn.addTarget(self, action: #selector(defaultAlert(_:)), for: .touchUpInside)
        
    self.view.addSubview(defaultAlertbtn)
}
    
@objc func defaultAlert(_ sender: Any){
    //알림창을 정의
    let alert = UIAlertController(title: nil, message: nil, preferredStyle: .alert)
        
    //버튼을 정의
    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
    let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
        
    //알림창에 버튼 추가
    alert.addAction(cancelAction)
    alert.addAction(okAction)
        
    //알림창에 들어갈 뷰 컨트롤러
    let v = UIViewController()
    v.view.backgroundColor = UIColor.gray
    //알림창에 뷰 컨트롤러를 등록
    alert.setValue(v, forKey: "contentViewController")
        
    //알림창 화면에 표시
    self.present(alert, animated: false)
}
 | 
     
 
2.MapKit 활용한 Alert 띄우기
| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 | @objc func mapAlert(_ sender: Any){
    //경고창 객체를 생성하고, ok 및 cancel 버튼을 추가한다.
    let alert = UIAlertController(title: nil, message: "여기가 맞습니까?", preferredStyle: .alert)
        
    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
    let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
        
    alert.addAction(cancelAction)
    alert.addAction(okAction)
            
    //컨텐츠 뷰 영역에 들어갈 뷰 컨트롤러를 생성하고, 알림창에 등록한다.
    let contentVC = UIViewController()
        
    //뷰 컨트롤러에 맵킷 뷰를 추가한다.
    let mapKitView = MKMapView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
    contentVC.view = mapKitView
    contentVC.preferredContentSize.height = 200
        
    //맵킷 설정
    //1.위치 정보를 설정한다. 위/경도를 사용한다.
    let pos = CLLocationCoordinate2D(latitude: 37.514322, longitude: 126.894623)
        
    //2.지도에서 보여줄 넓이.축척/ 숫자가 작을수록 좁은 범위를 확대시켜서 보여준다.
    let span = MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005)
        
    //3.지도 영역을 정의
    let region = MKCoordinateRegion(center: pos, span: span)
        
    //4.지도 뷰에 표시
    mapKitView.region = region
    mapKitView.regionThatFits(region)
        
    //5.위치를 핀으로 표시
    let point = MKPointAnnotation()
    point.coordinate = pos
    mapKitView.addAnnotation(point)
        
    //뷰 컨트롤러를 알림창의 컨텐츠 뷰 컨트롤러 속성에 등록한다.
    alert.setValue(contentVC, forKey: "contentViewController")
        
    self.present(alert, animated: false)
}
 | 
     
 
  - 코드 분리 (MapKitViewController.swift)
    | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 | class MapKitViewController : UIViewController{
  override func viewDidLoad() {
      super.viewDidLoad()
      // 뷰 컨트롤러에 맵킷 뷰를 추가한다.
      let mapKitView = MKMapView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
      self.view = mapKitView
      self.preferredContentSize.height = 200
        
      //표시할 위치
      let pos = CLLocationCoordinate2D(latitude: 37, longitude: 126)
        
      let span = MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005)
        
      //3.지도 영역을 정의
      let region = MKCoordinateRegion(center: pos, span: span)
        
      //4.지도 뷰에 표시
      mapKitView.region = region
      mapKitView.regionThatFits(region)
        
      //5.위치를 핀으로 표시
      let point = MKPointAnnotation()
      point.coordinate = pos
      mapKitView.addAnnotation(point)
  }
}
 |  
 
 
- MapAlertViewController 수정
    | 1
2
 | //let contentVC = UIViewController() 코드 삭제
let contentVC = MapKitViewController()
 |  
 
 
3.이미지 추가 Alert 띄우기
| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 | class ImageViewController : UIViewController{
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //1.이미지와 이미지 뷰 객체를 생성
        let icon = UIImage(named: "rating5")
        let iconV = UIImageView(image: icon)
        
        //2. 이미지 뷰의 영역과 위치를 지정
        iconV.frame = CGRect(x: 0, y: 0, width: (icon?.size.width)!, height: (icon?.size.height)!)
        
        //3. 루트 뷰에 이미지뷰를 추가
        self.view.addSubview(iconV)
        
        //4. 외부에서 참조할 뷰 컨트롤러 사이즈를 이미지 크기와 동일하게 설정
        self.preferredContentSize = CGSize(width: (icon?.size.width)!, height: (icon?.size.height)!+10)
        
    }
}
 | 
  - MapAlertViewController
    | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
 | @objc func imageAlert(_ sender: Any){
  let alert = UIAlertController(title: nil, message: "이번 글의 평점은 다음과 같습니다.", preferredStyle: .alert)
        
  let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
  let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
        
  alert.addAction(okAction)
  alert.addAction(cancelAction)
        
  let contentVC = ImageViewController()
  alert.setValue(contentVC, forKey: "contentViewController")
        
  self.present(alert, animated: false)
}
 |  
 
 
4.UISlider() 이용한 Alert 띄우기
| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 | class ControlViewController : UIViewController{
    //슬라이더 객체 정의
    let slider = UISlider()
    
    var sliderValue : Float{
        return self.slider.value
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //슬라이더의 최소값 / 최대값 설정
        self.slider.minimumValue = 0
        self.slider.maximumValue = 100
        
        //슬라이더의 영역과 크기를 정의하고 루트 뷰에 추가한다.
        self.slider.frame = CGRect(x: 0, y: 0, width: 170, height: 30)
        self.view.addSubview(self.slider)
        
        //뷰 컨트롤러의 콘텐츠 사이즈를 지정한다.
        self.preferredContentSize = CGSize(width: self.slider.frame.width, height: self.slider.frame.height + 10)   
    }
}
 | 
  - MapAlertViewController
    | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
 | @objc func sliderAlert(_ sender : Any){
  //콘텐츠 뷰 영역에 들어갈 뷰 컨트롤러를 생성
  let contentVC = ControlViewController()
        
  //경고창 객체를 생성
  let alert = UIAlertController(title: nil, message: "글의 평점을 입력해주세요", preferredStyle: .alert)
        
  alert.setValue(contentVC, forKey: "contentViewController")
        
  let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
  alert.addAction(okAction)
        
  self.present(alert, animated: false)
}
 |  
 
 
5.TableView 이용한 Alert 띄우기
| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 | class ListViewController : UITableViewController{
    
    var delegate: MapAlertViewController?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.preferredContentSize.height = 220
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 7
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        cell.textLabel!.text = "\(indexPath.row) 번째 옵션"
        cell.textLabel!.font = UIFont.systemFont(ofSize: 13)
        return cell
    }
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.delegate?.didSelectRowAt(indexPath: indexPath)
    }
}
 | 
MapAlertViewController
| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 | @objc func listAlert(_ sender: Any){
    let contentVC = ListViewController()
        
    let alert = UIAlertController(title: nil, message: nil, preferredStyle: .alert)
        
    alert.setValue(contentVC, forKey: "contentViewController")
        
    let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
    alert.addAction(okAction)
        
    //델리게이트 객체를 자신으로 지정
    contentVC.delegate = self
        
    self.present(alert, animated: false)
}
 | 
Delegate Pattern 사용
- MapAlertViewController 에 함수추가
| 1
2
3
 | func didSelectRowAt(indexPath: IndexPath){
    print(">>>선택된 행은\(indexPath.row)")
}
 | 
- ListViewController 에 MapAlertViewController 타입의 변수 선언
| 1
 | var delegate: MapAlertViewController?
 | 
- ListViewController 에 테이블 뷰의 델리게이트 메소드 오버라이드
| 1
2
3
 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    self.delegate?.didSelectRowAt(indexPath: indexPath)
}
 | 
- MapAlertViewController 에 델리게이트 메소드 호출 등록
| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 | @objc func listAlert(_ sender: Any){
    let contentVC = ListViewController()
    let alert = UIAlertController(title: nil, message: nil, preferredStyle: .alert)
        
    alert.setValue(contentVC, forKey: "contentViewController")
        
    let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
    alert.addAction(okAction)
        
    //델리게이트 객체를 자신으로 지정
    contentVC.delegate = self
        
    self.present(alert, animated: false)
}
 |