본문 바로가기
아이폰 개발/ios 개념&튜토리얼

ios 델리게이트란 - delegate 예제

by 인생여희 2021. 1. 7.

ios 델리게이트란 - delegate 예제

 

ios 개발을 하다 보면 delegate 패턴이라는 이야기를 들어보았을 것이다. ios delegate 를 구글 창에 검색해보면 정리된 많은 블로그를 볼 수 있다. 설명을 잘해놓은 글은 많은데 쉬운 예제는 없어보여서, 이번 포스팅에서는 ios 델리게이트 패턴 예제를 포스팅 해보려고 한다.

 

복잡한 ios 델리게이트 패턴을 기억하기 쉽게 한 문장으로 정리하면 무엇이라 할 수 있을까?

 

 

"내 클래스에서 다른 클래스에 시키고 싶은 행위(함수)를 내 클래스에 선언만 해놓고, 다른 클래스에서 함수(행위)를 구현하게 하고 내 클래스에서 다른 클래스에서 구현해 놓은 함수를 호출하는 것."

 

간단하게 요약하면 아래와 같다.

 

1.내 클래스에서 다른 클래스에 시키고 싶은.. 즉, 다른 클래스에 이러 이러한 기능이 있으면 좋겠다.. 싶은 함수를 내 클래스에 선언한다.

2.내 클래스에서 델리게이트 프로퍼티 설정.

3.다른 클래스에서 내 클래스에 선언한 델리게이트 채택하고 델리게이트 설정 및 함수(프로토콜)를 구현

4.내 클래스에서 델리게이트 호출 하면 다른 클래스에서 구현해놓은 함수가 호출됨.

 

 

ios delegate 예제

 

우리가 구현해볼 예제는 아래와 같다. 먼저 메인 뷰에서 버튼 show a view 를 클릭하면 AView(다른 클래스)가 뜬다. 그 후 5초 뒤, BView(내 클래스)가 뜬다. BView에는 닫는 버튼이 있다.

 

문제는 AView에는 닫는 버튼이 없다! 그럼 어떻게 AView를 닫을 수 있을까?

 

어떻게 보다 누가 AView를 닫아야 는가가 더 정확한 질문이다.

 

위에서 ios delegate를 뭐라고 했나? 내 클래스에서 다른 클래스에 시키고 싶은 행위 선언하고 다른 클래스에서 구현시키기 라고 했다.

 

지금 다른 클래스 (AView)에 닫아 주는 행위를 시키고 싶다. 어디서? 내클래스 (BView)에서.

 

그럼 함수는 어디다 선언한다고 했나? 내 클래스에 선언한다. 즉, BView에 AView에 시킬 함수를 내 클래스에 선언한다.

그리고 내 클래스 (BView)에 delegate property를 작성해 준다.

 

 마지막으로 다른 클래스 (AView)에서 BView에서 선언한 프로토콜을 채택하고, BView의 delegate를 self으로 설정해주고, 함수를 구현해주면 delegate 처리는 끝이 난다.

 

 

ios delegate 예제

 

 

예제 소스

 

먼제 메인 화면에서 버튼을 클릭하면 AView(다른 클래스)를 열어준다.

 

ViewController.m

 

- (IBAction)showAview:(id)sender {
    
    NSLog(@"ViewController - showAview : AView 호출");
    AView *aView = [[AView alloc]init];
    [self presentViewController:aView animated:NO completion:nil];
    
}

 

 

그 다음으로 내 클래스 BView 먼저 보자. 아래 소스 처럼 프로토콜을 선언하고 사용할 함수를 작성해 준다. 그리고 프로퍼티를 작성해준다. 

 

BView.h

 

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

//부모창을 닫아 주기 위한 비공식 프로토콜 (델리게이트)
@protocol ParentViewClose <NSObject>
-(void) doClose;
@end

@interface BView : UIViewController

//부모창을 닫아주기 위한 델리게이트 프로퍼티
@property (nonatomic , weak) id <ParentViewClose> parentViewCloseDelegate;

@end

NS_ASSUME_NONNULL_END

 

BView.m

 

BView에는 닫기 버튼이 있다고 했다. 아래와 같이 작성해 준다.

 

#import "BView.h"

@interface BView ()

@end

@implementation BView

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}

- (IBAction)btnClose:(id)sender {
    
    NSLog(@"BView - btnClose 메소드  BView 닫기");
    
    [self dismissViewControllerAnimated:NO completion:^{
       
        //parentViewCloseDelegate 는 이 델리게이트를 채택한 객체이다.
        //이 델리게이트를 채택하고, 구현한 메소드를 호출해준다.
        [self.parentViewCloseDelegate doClose];
        
    }];
}


@end

 

마지막으로 BView.h에서 선언한 프로토콜을 채택하고, 델리게이트를 설정하고, 델리게이트 함수를 구현하는 작업은 AView에서 해준다. 

예제 소스는 아래와 같다.

 

AView.m

 

#import "AView.h"

//부모뷰 임포트
#import "BView.h"

//ParentViewClose 프로토콜 채택
@interface AView ()<ParentViewClose>

@end

@implementation AView

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //5초 뒤 BView 열기
    [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(openBView) userInfo:nil repeats:NO];
    
}

//B 뷰 열기
-(void)openBView{
    
    NSLog(@"AView - openBView : BView 호출");
    
    //BView 객체 생성
    BView *bview = [[BView alloc]init];
    
    //델리게이트 설정
    bview.parentViewCloseDelegate = self;
    
    [self presentViewController:bview animated:NO completion:nil];
    
}

//BView에서 선언한 메소드
#pragma ParentViewClose delegate 메소드
- (void)doClose {
    
    NSLog(@"AView - delegate 메소드 doClose : 닫기");
    
    //닫기
    [self dismissViewControllerAnimated:NO completion:nil];
}

@end

 

 

실행

 

xcode에서 시뮬레이터로 실행해보자. 먼저 main에서 show AView 를 클릭하면 AView가 열리고, 5초뒤에, BView가 열린다. 그리고 BView의 close 버튼을 누르면, BView가 닫히고, 그 다음 자동으로 AView가 성공적으로 닫히는 것을 볼 수 있다.

 

 

 

DelegateTest 2.zip
0.07MB