iOS 개발 노트
🪴클로저를 사용해 이전 화면에 데이터 전달하기 본문
델리게이트 패턴이 아닌 클로저를 사용해서 이전 화면에 데이터를 전달해보도록 하겠습니다.
먼저 스토리보드를 이용해 다음과 같이 환경을 구성했습니다.
두번째 화면의 텍스트뷰에 입력한 문자열 데이터를, 첫번째 화면의 텍스트뷰에 전달해볼 것 입니다.
- firstVC와 secondVC에는 각각 텍스트뷰와 버튼이 존재함
- firstVC에서 버튼을 누르면 secondVC를 모달 방식으로 띄울 것
- secondVC에서 버튼을 누르면 이전화면인 firstVC으로 돌아갈 것
firstVC에서 버튼의 액션함수 안에 secondVC를 모달로 띄우기 위해 present(_:animated:) 메서드를 호출해줍니다.
secondVC에서 버튼의 액션함수 안에 dismiss(animated:) 메서드를 호출하여 이전 화면으로 돌아갈 수 있게 해줍니다.
secondVC에서 클로저를 담는 변수를 선언 및 초기화 해줍니다.
입력 파라미터에는 문자열을 전달하기 위해 String 타입으로 정의했고, {(sender) in} 을 대입한 것은 초기화를 위해 임시적인 함수를 저장해둔 것으로 보면 됩니다.
//함수 즉, 클로저를 담아둘 변수
var closureUseForDataSend: (_ text: String) -> Void = {(sender) in}
참고로 초기화는 하고싶지 않다면 임시적인 함수를 저장해둘 필요없이 다음과 같이 옵셔널 타입으로 선언하면 됩니다.
var closureUseForDataSend: ((_ text: String) -> Void)?
그리고 이전 화면으로 돌아가기 전에 변수를 호출해주도록 합니다.
변수를 호출하게 되면 변수 안에 저장된 클로저가 실행됩니다. 입력 파라미터에는 텍스트뷰의 문자열을 전달해주도록 합시다.
@IBAction func buttonTapped(_ sender: UIButton) {
//클로저가 담아져 있는 변수를 호출! -> 클로저를 실행한다.
//TextView의 텍스트 내용을 전달
closureUseForDataSend(secondTextView.text)
//이전 화면으로 돌아가기
dismiss(animated: true)
}
이제 firstVC으로 돌아가서 변수 호출 시 실행될 클로저를 저장해주도록 합니다. 변수를 호출하게 되면 결국 self?.firstTextView.text = sender 구문이 실행되게 되는 것 입니다.
@IBAction func buttonTapped(_ sender: UIButton) {
let secondVC = storyboard?.instantiateViewController(withIdentifier: "SecondVC") as! SecondViewController
//두번째 뷰 컨트롤러에 있는 변수에 실행하고 싶은 클로저 저장하기
secondVC.closureUseForDataSend = {[weak self] (sender) in
//sender에는 두번째 뷰 컨트롤러에 있는 텍스트뷰의 문자열을 입력받으므로, 그대로 전달해주기
self?.firstTextView.text = sender
}
present(secondVC, animated: true)
}
최종 동작을 확인해보면 다음과 같이, 두번째 뷰 컨트롤러의 텍스트뷰 문자열이 이전 화면의 뷰 컨트롤러에 전달되는 것을 볼 수 있습니다.
'iOS' 카테고리의 다른 글
🪴ImageView의 ContentMode (0) | 2023.06.14 |
---|---|
🪴StackView의 Alignment/Distribution/Spacing (0) | 2023.06.08 |