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)
}
|