2014년 4월 30일 수요일

[iOS] Unwind Segue 사용하기.

Segue를 이용해서, Unwind Segue를 사용하는 방법을 간단히 정리합니다.

iOS에서 Storyboard를 이용하여, ViewController 1(이하 VC1)에서 다른 ViewController 2 (이하 VC2)로 이동을 하게 되고, 뒤로는 Back 버튼을 이용해서, 이동하게 됩니다.
어떤 에러로 인해서, 반대로 즉 뒤로 이동해야 할 경우도 있습니다.

이런 경우, Delegate를 사용해서, VC2의 델리게이트로 설정한 VC1의 함수를 호출하여, dismissViewControllerAnimated:complation을 이용해서 화면에 표시된 VC2를 제거하여 Back을 하였습니다.

화면이동으로 Segue를 이용하듯이, Unwind Segue를 이용해서, 화면 Back으로 이동할 수 있습니다.
 그럼, segue와 unwind segue의 차이점은 뭘까요?
 차이점은 Segue는 VC1에서 VC2로 이동하면, 신규로 VC2를 생성하고 NavigationViewController의 presentaion chain에 쌓아 가면서 이동하지만, unwind segue는  기존에 화면에서 표시되었던 VC로만 이동할 수 있어서, 신규로 VC를 만들지 않습니다.
즉, A-B-C-D의 형태로 뷰컨트롤러를 화면에 표시했다면, D에서 A로 Unwind segue로 이동하면서, 중간 VC들을 삭제하게 되는 것입니다.

이용방법

1. back으로 이동할 ViewController1에 함수를 설정합니다.

source code
- (IBAction) exitFromSecondViewController:(UIStoryboardSegue *)segue
{
    //Back으로 올때 호출되는 함수
    // segue를 통해서, 어느 뷰컨트롤러에서 오는 것인지 구분할 수 있다.
    NSLog(@"back from : %@", [segue.sourceViewController class]);
}

이름은 무엇이든 상관없고, 변수로 UIStoryboardSegue를 받아야 하고, 전 프로젝트에 걸쳐, 구분이 되도록 해야 합니다.
 주의 할 것은 VC 1에 위 함수를 추가해야 됩니다. 즉, VC 1으로 이동하고 난 후에 위 함수가 호출이 되는 것입니다.

2. VC2에서 unwind segue를 설정합니다.

Storyboard에서 VC2에서 아래와 같이 VC아이콘에서 exit 아이콘으로 Ctrl+드래그를 선택합니다.
Ctrl+드래그를 합니다.

VC1에 추가하였던 함수가 표시되고, 그것을 선택합니다.
위와 같이 unwind segue를 추가하고, identification을 "UnwindingSegueID"로 설정합니다.

3. Unwind Segue를 호출 합니다.

source code
- (IBAction)backButton:(id)sender //Back버튼은 VC2 화면에 추가된 버튼입니다.
{
    [self performSegueWithIdentifier:@"UnwindingSegueID" sender:self];
}

[추가] 만약, 여러 VC2에서 VC3를 호출하였고, VC3에서 VC1으로 이동하면 어떻게 될까요?

아래와 같이 설정을 하고 테스트를 하면,

VC1 - VC2 - VC3까지 Segue를 통해서 호출을 하면, presentation chain에 순서대로 쌓이게 됩니다.
VC3에서 VC1으로 중간에 VC2를 거치지 않고, unwind segue를 통해서 이동을 하면, VC1으로 이동하고, VC2와 VC3를 차례로 dealloc하게 됩니다.
log
 

[2339:60b] VC1 performSegueWithIdentifier called : GoSegueID
               : VC1에서 segue를 코드로 호출해서 VC2로 이동하도록 호출합니다.
[2339:60b] VC1 prepareForSegue id:GoSegueID to : DBUSecondViewController
               : VC1의 prepareForSegue함수가 호출이됩니다.

[2339:60b] VC2 prepareForSegue id:GoThirdSegueID to : DBUThirdViewController
               : VC2에서 버튼으로 바로 segue 를 호출합니다.

[2339:60b] VC3 performSegueWithIdentifier called : backToOneSegueID
               : VC3에서 unwind segue를 호출합니다.
[2339:60b] VC3 PrepareForSegue id: backToOneSegueID, to DBUViewController
               : prepareForSegue로 segue가 호출 되었음을 알려줍니다.
[2339:60b] VC1 exitFunction called in VC1 from : DBUThirdViewController
               : VC1으로 이동되고, 어디서 왔는지 sourceController를 통해서 알 수 있습니다.
[2339:60b] dealloc : <dbusecondviewcontroller: 0x8e0d670="">
               : VC2가 삭제되고..
[2339:60b] dealloc : <dbuthirdviewcontroller: 0x9947ee0="">
               : VC3가 삭제됩니다.

[참고]

Apple Tech Notes 2298
Using iOS Storyboard Segues

- Segue관련 함수는? (블로그 : [iOS] Segue 관련 함수]