[iOS 정면돌파] 05. 커스텀 팝업 다이얼로그

H43RO·2021년 8월 17일
7

iOS 정면돌파

목록 보기
5/5
post-thumbnail

오늘은 커스텀 팝업을 만드는 방법과, 함수형 프로그래밍 기법을 통해 이벤트 콜백 메소드에 Completion Closure 를 주입하는 방법에 대해서 알아보았다.

Goal : 다이얼로그의 확인 버튼을 누르면, 웹뷰에 내 블로그 보여지게 하기

1. 스토리 보드 구성

Main.storyboard

Dialog.storybaord

이 때, 배경은 투명도가 있는 검은색으로 지정해준다 (오버레이 디밍 효과 연출을 위한 것)
다이얼로그 바깥 스코프를 클릭했을 때 이벤트를 처리하기 위한 꼼수(?) 다.

2. 다이얼로그 뷰 컴포넌트 꾸며주기

CustomDialogViewController.swift

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

3. 다이얼로그 뷰 바깥 범위를 클릭했을 때 이벤트 처리

CustomDialogViewController.swift

@IBAction func onBackgroundButtonClicked(_ sender: UIButton) {
    print("CustomDialogViewController - onBackgroundButtonClicked() called")
    self.dismiss(animated: true, completion: nil)
}  // 다이얼로그 사라짐

4. 메인 화면에서 버튼 누를 때 다이얼로그 생성하는 동작 구현

이 때, 필자가 상수명을 storyBoard 로 했는데 이는 가급적 피하는게 좋을 것 같았다. 같은 스코프에 'storyBoard' 라는 놈이 하나 더 있어서 instantiateViewController() 하는 과정에서 자꾸 알 수 없는 에러가 발생하곤 했다. 알고보니 다른 녀석이었다.. 30분은 삽질했다.

ViewController.swift

@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)  // 생성
}

5. Completion Closure 생성

ViewController 에서, CustomDialogViewController 를 생성할 때 CompletionClosure 를 주입해줄 것이다. 이렇게 하면 onConfirmButtonClicked() 호출 시 주입한 클로저 동작을 수행하게 되는 것이다.

CustomDialogViewController.swift

var confirmButtonCompletionClosure: (() -> Void)?
.
.
.
@IBAction func onConfirmButtonClicked(_ sender: UIButton) {
    print("CustomDialogViewController - onConfirmButtonClicked() called")
    
    // Completion 블럭 호출
    if let confirmButtonCompletionClosure = confirmButtonCompletionClosure {
        confirmButtonCompletionClosure()
        
	// 클로저 수행 완료 시 다이얼로그 닫음
        self.dismiss(animated: true, completion: nil)
    }
}

6. Completion Closure 주입

WebView 에 지정한 URL 의 컨텐츠를 뿌려주는 동작을 클로저로 넘겨준다.

ViewController.swift

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

여기까지 구현하면, 팝업 다이얼로그의 확인 버튼을 눌렀을 때 메인 페이지에 필자의 블로그가 등장한다.

7. 결과

profile
어려울수록 기본에 미치고 열광하라

0개의 댓글