뷰에서 팝업창을 하나 만든다고 가정을 하자. 팝업창에는 여러가지 정보나 버튼이 있고 그 버튼을 누르면 팝업창을 생성한 상위 뷰에 선택한 메뉴가 보이는 구조라고 하면 이걸 어떻게 구현할까? 팝업을 생성한 뷰에서는 팝업창을 제어하기가 쉽다. 하지만 팝업창에서는 상위뷰를 제어하는게 생각처럼 쉽지는 않다. 이럴때 쓸수있는 패턴들이 있다. 대표적으로 Delegate 패턴을 시작으로 NSNotificationCenter, singletone, block, keyValue….등등 시간이 날때마다 하나씩 포스팅을 해보도록 하겠다. 오늘은 그 1부로 가장 많이 쓰인다고 생각되는 Delegate패턴을 사용하겠다. 해당 패턴은 iOS앱에서 자주 쓰이는 UITableView를 사용하려면 반드시 사용해야만 하는 패턴이다! 그래서 알게 모르게 눈에 익을것이다.
일단 델리게이트 패턴을 만드려면 새로 생성할 객체에 ‘이 객체는 델리게이트를 사용합니다’라고 헤더파일에 선언을 해줘야한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// TPDelegateViewController.h @protocol TPViewControllerDelegate; @interface TPDelegateViewController : UIViewController @property (nonatomic, weak) id<TPViewControllerDelegate> delegate; //호출할 상위 객체의 포인터가 저장되는 변수 @end @protocol TPViewControllerDelegate <NSObject> @required //필수적으로 들어가야만 되는 델리게이트 @optional //선택적으로 들어가는 델리게이트 -(void)closeDelegateViewController:(UIViewController *)vc; -(void)changeViewColor:(UIViewController *)vc; @end |
상위 뷰의 헤더에 해당 델리게이트를 사용한다고 선언해준다
1 2 3 4 5 6 7 8 9 |
// ViewController.h #import "TPDelegateViewController.h" // 중요하다 꺽쇠 < > 안에 사용 할 델리게이트 패턴을 입력해준다 2개 이상의 델리게이트를 사용하려면 ,로 구분해서 입력한다 <xxx, yyy, zzz> @interface ViewController : UIViewController<TPViewControllerDelegate>{ TPDelegateViewController *delegateViewController; __weak IBOutlet UILabel *textLabel; } @end |
델리게이트를 통해 호출되었을때 실제로 구현될 메소드를 작성한다
1 2 3 4 5 6 7 8 9 10 11 12 |
// ViewController.m #pragma mark - TPDelegate //델리게이트 패턴을 통해 호출되어 실제로 구동되는 메소드 -(void)closeDelegateViewController:(UIViewController *)vc{ NSLog(@"델리게이트 패턴 %@", vc); [delegateViewController.view removeFromSuperview]; } -(void)changeViewColor:(UIViewController *)vc{ NSLog(@"델리게이트 패턴 %@", vc); textLabel.backgroundColor = [self randomColor]; } |
마지막으로 하위뷰에서 상위뷰로 가야하는 이벤트에 알맞게 작업을 해준다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// TPDelegateViewController.m #pragma mark - IBAction - (IBAction)closeDelegateViewButtonAction:(id)sender { //연결되있는 델리게이트 객체에 해당 메소드가 있는지 확인한 후 호출한다. if ([_delegate respondsToSelector:@selector(closeDelegateViewController:)]) { [_delegate closeDelegateViewController:self]; } } - (IBAction)changeColorButtonAction:(id)sender { //연결되있는 델리게이트 객체에 해당 메소드가 있는지 확인한 후 호출한다. if ([_delegate respondsToSelector:@selector(changeViewColor:)]) { [_delegate changeViewColor:self]; } } |
해당 소스를 기준으로 작업을 하면 내가 만든 하위뷰에서 상위뷰의 라벨 색상을 바꾼 앱을 만들 수 있다. 참 쉽죠?
나는 처음 앱을 만들때 이 패턴을 이해하지 못해서 거의 일주일은 삽질을 했는데 ….이 포스팅을 보시는분은 30분만에 꺠우칠수있기를 빕니다. 혹시라도 잘 이해가 안되면 댓글 남겨주시면 최선을 다해 답변 드리겠습니다 😀