오늘은 커스텀 팝업을 만드는 방법과, 함수형 프로그래밍 기법을 통해 이벤트 콜백 메소드에 Completion Closure 를 주입하는 방법에 대해서 알아보았다.
Goal : 다이얼로그의 확인 버튼을 누르면, 웹뷰에 내 블로그 보여지게 하기
이 때, 배경은 투명도가 있는 검은색으로 지정해준다 (오버레이 디밍 효과 연출을 위한 것)
다이얼로그 바깥 스코프를 클릭했을 때 이벤트를 처리하기 위한 꼼수(?) 다.
@IBOutlet var contentView: UIView!
@IBOutlet var confirmButton: UIButton!
@IBOutlet var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
print("CustomDialogViewController - viewDidLoad()")
contentView.layer.cornerRadius = 30
confirmButton.layer.cornerRadius = 10
imageView.layer.cornerRadius = 10
}
@IBAction func onBackgroundButtonClicked(_ sender: UIButton) {
print("CustomDialogViewController - onBackgroundButtonClicked() called")
self.dismiss(animated: true, completion: nil)
} // 다이얼로그 사라짐
이 때, 필자가 상수명을 storyBoard 로 했는데 이는 가급적 피하는게 좋을 것 같았다. 같은 스코프에 'storyBoard' 라는 놈이 하나 더 있어서 instantiateViewController() 하는 과정에서 자꾸 알 수 없는 에러가 발생하곤 했다. 알고보니 다른 녀석이었다..
30분은 삽질했다.
@IBAction func onCreateDialogButtonClicked(_ sender: UIButton) {
print("ViewController - onCreateDialogButtonClicked() Called")
// 다이얼로그의 스토리보드 가져오기
let storyBoard = UIStoryboard.init(name: "Dialog", bundle: nil)
// 다이얼로그의 스토리보드를 통해 뷰 컨트롤러 가져오기 (Identifier 지정 필수)
let customDialogVC = storyBoard.instantiateViewController(withIdentifier: "CUSTOM_DIALOG") as! CustomDialogViewController
// 뷰 컨트롤러가 보여지는 스타일
customDialogVC.modalPresentationStyle = .overCurrentContext
// 뷰 컨트롤러가 사라지는 스타일)
customDialogVC.modalTransitionStyle = .crossDissolve
self.present(customDialogVC, animated: true, completion: nil) // 생성
}
ViewController 에서, CustomDialogViewController 를 생성할 때 CompletionClosure 를 주입해줄 것이다. 이렇게 하면 onConfirmButtonClicked() 호출 시 주입한 클로저 동작을 수행하게 되는 것이다.
var confirmButtonCompletionClosure: (() -> Void)?
.
.
.
@IBAction func onConfirmButtonClicked(_ sender: UIButton) {
print("CustomDialogViewController - onConfirmButtonClicked() called")
// Completion 블럭 호출
if let confirmButtonCompletionClosure = confirmButtonCompletionClosure {
confirmButtonCompletionClosure()
// 클로저 수행 완료 시 다이얼로그 닫음
self.dismiss(animated: true, completion: nil)
}
}
WebView 에 지정한 URL 의 컨텐츠를 뿌려주는 동작을 클로저로 넘겨준다.
@IBAction func onCreateDialogButtonClicked(_ sender: UIButton) {
print("ViewController - onCreateDialogButtonClicked() Called")
// 스토리보드 가져오기
let storyBoard = UIStoryboard.init(name: "Dialog", bundle: nil)
// 스토리보드를 통해 뷰 컨트롤러 가져오기
let customDialogVC = storyBoard.instantiateViewController(withIdentifier: "CUSTOM_DIALOG") as! CustomDialogViewController
// 뷰 컨트롤러가 보여지는 스타일
customDialogVC.modalPresentationStyle = .overCurrentContext
// 뷰 컨트롤러가 사라지는 스타일)
customDialogVC.modalTransitionStyle = .crossDissolve
customDialogVC.confirmButtonCompletionClosure = {
print("Completion Block called() !")
let myBlogUrl = URL(string: "https://velog.io/@haero_kim")
self.webView.load(URLRequest(url: myBlogUrl!))
}
self.present(customDialogVC, animated: true, completion: nil)
}
여기까지 구현하면, 팝업 다이얼로그의 확인 버튼을 눌렀을 때 메인 페이지에 필자의 블로그가 등장한다.