iOS 개발을 처음 접하는 분들에게 UIAlertController의 이해와 구현은 다소 까다롭게 느껴질 수 있습니다. 이번 글에서는 사용자가 알림 창 바깥 영역을 탭했을 때 해당 알림이 자동으로 닫히도록 만드는 방법을 단계별로 살펴보겠습니다.
이번 예제에서는 표시할 메시지와 선택 가능한 액션(action)을 구성할 수 있는 UIAlertController 클래스를 사용합니다. 원하는 액션과 스타일로 알림 컨트롤러를 구성한 뒤에는 present(_:animated:completion:) 메서드를 호출해 화면에 띄우면 됩니다. UIKit은 알림과 액션 시트를 앱 콘텐츠 위에 모달(modal) 형태로 표시합니다.
더 자세한 내용은 Apple 공식 문서(UIAlertController – Apple Developer Documentation)에서 확인하실 수 있습니다.
구현 방법
1단계 — 프로젝트 생성
Xcode를 열고 Single View Application 템플릿으로 새 프로젝트를 만든 뒤, 이름을 UIAlertSample로 지정합니다.
2단계 — 버튼 추가 및 IBAction 연결
Main.storyboard에 버튼 하나를 추가하고, @IBAction을 생성해 이름을 showAlert로 지정합니다.
@IBAction func showAlert(_ sender: Any) { }이제 버튼을 탭하면 알림이 표시되고, 사용자가 알림 바깥쪽을 탭하면 알림이 닫히도록 만들 것입니다.
3단계 — UIAlertController 객체 생성
버튼 액션인 showAlert 메서드 안에서 먼저 아래와 같이 UIAlertController 객체를 생성합니다.
let uialert = UIAlertController(title: "WELCOME", message: "Welcome to my tutorials, tap outside to dismiss the alert", preferredStyle: .alert)
4단계 — 알림 표시 및 탭 제스처 등록
알림을 화면에 표시하고, 완료 콜백(completion) 안에 아래와 같이 셀렉터(selector)를 등록합니다.
self.present(uialert, animated: true, completion:{
uialert.view.superview?.isUserInteractionEnabled = true
uialert.view.superview?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.dismissOnTapOutside)))
})5단계 — 셀렉터 함수 추가
바깥 영역을 탭했을 때 호출될 함수를 작성합니다.
@objc func dismissOnTapOutside(){
self.dismiss(animated: true, completion: nil)
}6단계 — 앱 실행 및 확인
애플리케이션을 실행한 뒤 버튼을 누르고, 알림 바깥쪽을 탭했을 때 알림이 정상적으로 닫히는지 확인합니다.
동작 원리
핵심 아이디어는 간단합니다. UIAlertController가 표시되면 그 뷰의 superview(반투명 배경 영역)에 UITapGestureRecognizer를 추가하는 것입니다. 기본적으로 이 superview는 사용자 상호작용이 비활성화되어 있기 때문에, 먼저 isUserInteractionEnabled를 true로 설정한 후 탭 제스처를 등록해야 합니다. 이렇게 하면 배경 영역을 탭했을 때 dismissOnTapOutside 메서드가 호출되어 알림이 닫히게 됩니다.
전체 코드
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func showAlert(_ sender: Any) {
let uialert = UIAlertController(title: "WELCOME", message: "Welcome to my tutorials, tap outside to dismiss the alert", preferredStyle: .alert)
self.present(uialert, animated: true, completion:{
uialert.view.superview?.isUserInteractionEnabled = true
uialert.view.superview?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.dismissOnTapOutside)))
})
}
@objc func dismissOnTapOutside(){
self.dismiss(animated: true, completion: nil)
}
}