[UIStoryboardSegue] prepare(), performSegue() : segue 를 이용해 뷰컨트롤러간 데이터 전달하기

jane·2021년 11월 3일
0

iOS

목록 보기
7/32

UIStoryboardSegue

Segue 를 부르는 방법 두가지

  • prepare(for:sender:)
    : 스토리보드에서 뷰컨간에 segue를 연결하고 나서 버튼이 있는 시작 뷰컨에 이 메서드를 정의하면, segue가 런타임에 불러질때 자동으로 이 메서드가 불러진다. 이 메서드를 통해 곧 보여질 뷰컨에 데이터를 전달할 수 있다.
  • performSegue(withIdentifier:sender:)
    : 이 메서드로 segue를 코드로 초기화할수도 있다.

prepare(for:sender:)

스토리보드에서 VC1의 재고수정버튼을 VC2(재고수정화면)의 네비게이션컨트롤러와 연결 후에 이 prepare 메서드를 VC1에 추가해준다.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.destination is StockModifyNavController {
        let stockModifyNC = segue.destination as? StockModifyNavController
        let stockModifyVC = stockModifyNC?.children.first as? StockModifyViewController
        stockModifyVC?.loadViewIfNeeded()
        stockModifyVC?.changeStockLabel()
    }
}

위에꺼 축약 ver(완전동일)

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
	if let stockModifyNC = segue.destination as? StockModifyNavController {
          let stockModifyVC = stockModifyNC.children.first as? StockModifyViewController
          stockModifyVC?.loadViewIfNeeded()
          stockModifyVC?.changeStockLabel()
    }
}

코드에 대한 설명

  • if segue.destination is StockModifyNavController
    segue의 목적지를 확인한다.
    왜? 모든 segue들이 전부다 prepare(for:sender:) 을 통과하기때문에 목적지를 확인해서 내가 커스텀하고싶은 segue가 맞는지 확인하는 작업이 필요하다.

  • as? StockModifyViewController
    뷰컨트롤러의 메서드를 사용하기위해 다운캐스팅해준다.

  • stockModifyVC?.changeStockLabel()
    그럼 이제 메서드에 접근할 수 있다.

놀라운 점은 이렇게 선언만 해놓고 어디서 이 메서드를 실행하지 않아도 자동으로 실행된다..(헉)
알아서 모든 segue 가 이걸 거쳐가나보다,,

그래서 이렇게만 하면 화면전환시 데이터를 전달할 수 있다..!

추가)
뷰컨의 테이블뷰의 셀과 두번째 뷰컨을 segue로 연결했을 때, 셀을 클릭하면 해당 셀의 상세화면으로 넘어가게 구현하는 상황

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        guard let cell = sender as? KoreanArtWorkTableViewCell else { return }
       
        if let destinationVC = segue.destination as? aaaViewController {
            let id = tableView.indexPath(for: cell)?.row
            destinationVC.id = id
        }
        
    }
코드 설명
  화면 전환시 어떤 데이터를 표시할지 알려주기 -> 배열의 인덱스 넘겨주기
  - prepare(for:, sender) 메서드 사용하여 segue 방식으로 전환
  - tableView.indexPath(for:) 로 cell의 indexPath를 구함(-> 이걸로 배열로 이루어진 데이터를 가져오기 위해서)
  - 두번째 뷰컨을 불러와서 두번째 뷰컨의 프로퍼티에 cell의 indexPath 할당

performSegue(withIdentifier:sender:)

그런데 나는 여기에 추가로,
VC1에서 얼럿창이 나온 경우에 VC2로 화면전환을 해줄 때도 이 prepare 메서드를 써주고싶은데,
얼럿창의 버튼은 VC2의 네비게이션컨트롤러와 직접 연결이 되지 않으니 prepare 메서드를 직접 호출해야 할 것 같은데 어떻게하지?

UIAlertAction 인스턴스를 초기화시 매개변수인 handler로 performSegue 클로저를 넘겨준다. 얼럿 액션이 일어나고 나서 해야할 일을 정의해주는 것이다.

func performSegue(withIdentifier identifier: String, sender: Any?) 메서드를 handler로 넘겨주기.

  • identifier: Segue의 storyboardID 를 써준다.
    func showFailedOrderAlert(fruitAndQuantity: [Fruit: Int]) {
        let message = "\(DataFormatConverter().convert(using: fruitAndQuantity))가 모자라요. 재고를 수정할까요?"
        
        let alert = UIAlertController(title: "재고 부족", message: message, preferredStyle: .alert)
        let ok = UIAlertAction(title: "재고 수정하기", style: .default) { _ in self.performSegue(withIdentifier: "stockModifySegue", sender: nil) }
        let close = UIAlertAction(title: "아니오", style: .default)
        alert.addAction(close)
        alert.addAction(ok)
        
        present(alert, animated: true, completion: nil)
    }

재고가 모자르면 주문실패 얼럿이 뜨고,
재고 수정하기 버튼을 누르면 segue가 일어나게 구현했다.


Reference

Passing Data Between View Controllers Using Segues (A → B)

UIStoryboardSegue

performSegue

UIAlertAction

profile
제가 나중에 다시 보려고 기록합니다 ✏️

0개의 댓글