program tip

상위 뷰 컨트롤러에서 모달 뷰 컨트롤러의 해제를 어떻게 감지 할 수 있습니까?

radiobox 2021. 1. 6. 07:59
반응형

상위 뷰 컨트롤러에서 모달 뷰 컨트롤러의 해제를 어떻게 감지 할 수 있습니까?


중복 가능성 :
모달 뷰 컨트롤러가 해제됨에 따라 기본 뷰 컨트롤러의 함수 호출

나는 거의 모든 것을 시도했습니다. 내가 시도한 것은 다음과 같습니다.

-(void)viewWillAppear:(BOOL)animated
{

NSLog(@"Test");

}

-(void)viewDidAppear:(BOOL)animated
{

NSLog(@"Test");

}

-(void)viewDidLoad
{

NSLog(@"Test");

}

모달 뷰 컨트롤러가 닫힐 때 부모 뷰 컨트롤러에서 작동하지 않는 이유는 무엇입니까? 이 작업을 수행하려면 어떻게해야합니까?


이 답변은 가장 중요한 3 가지 접근 방식을 설명하기 위해 재 작성 / 확장되었습니다 ( @galambalazs )

1. 블록

가장 간단한 방법은 콜백을 사용하는 것 block입니다. 해고에 관심이있는 리스너 (부모 뷰 컨트롤러) 가 하나만있는 경우에 좋습니다 . 이벤트와 함께 일부 데이터를 전달할 수도 있습니다.

에서 MainViewController.m

SecondViewController* svc = [[SecondViewController alloc] init];
svc.didDismiss = ^(NSString *data) {
    // this method gets called in MainVC when your SecondVC is dismissed
    NSLog(@"Dismissed SecondViewController");
};
[self presentViewController:svc animated:YES completion:nil];

에서 SecondViewController.h

@interface MainViewController : UIViewController
    @property (nonatomic, copy) void (^didDismiss)(NSString *data);
    // ... other properties
@end

에서 SecondViewController.m

- (IBAction)close:(id)sender 
{
    [self dismissViewControllerAnimated:YES completion:nil];

    if (self.didDismiss) 
        self.didDismiss(@"some extra data");
}

2. 위임

Delegation Apple에서 권장하는 패턴입니다.

제시된보기 컨트롤러 닫기

제시된 뷰 컨트롤러가 데이터를 제시하는 뷰 컨트롤러로 반환해야하는 경우 위임 디자인 패턴을 사용 하여 전송을 용이하게합니다. 위임을 사용하면 앱의 여러 부분에서보기 컨트롤러를 더 쉽게 재사용 할 수 있습니다. 위임을 통해 제시된 뷰 컨트롤러는 공식 프로토콜의 메서드를 구현하는 위임 객체에 대한 참조를 저장 합니다 . 결과를 수집 할 때 제시된 뷰 컨트롤러는 델리게이트에서 해당 메서드를 호출합니다. 일반적인 구현에서 제시하는 뷰 컨트롤러는 자신을 제시된 뷰 컨트롤러의 델리게이트로 만듭니다.

MainViewController

에서 MainViewController.h

@interface MainViewController : UIViewController <SecondViewControllerDelegate>
    - (void)didDismissViewController:(UIViewController*)vc;
    // ... properties
@end

MainViewController.m 어딘가에 (프레젠테이션)

SecondViewController* svc = [[SecondViewController alloc] init];
svc.delegate = self;
[self presentViewController:svc animated:YES completion:nil];

MainViewController.m의 다른 곳 (해고에 대해 들었습니다)

- (void)didDismissViewController:(UIViewController*)vc
{
    // this method gets called in MainVC when your SecondVC is dismissed
    NSLog(@"Dismissed SecondViewController");
}

SecondViewController

에서 SecondViewController.h

@protocol SecondViewControllerDelegate <NSObject>
- (void)didDismissViewController:(UIViewController*)vc;
@end

@interface SecondViewController : UIViewController
@property (nonatomic, weak) id<SecondViewControllerDelegate> delegate;
// ... other properties
@end

SecondViewController.m 어딘가에

[self.delegate didDismissViewController:self];
[self dismissViewControllerAnimated:YES completion:nil];

(참고 : didDismissViewController : 메소드가있는 프로토콜은 앱 전체에서 재사용 할 수 있습니다.)


3. 알림

또 다른 해결책은 NSNotification. 이것은 만 할 경우에 위임 것보다 쉬울 수 있습니다뿐만 아니라, 유효한 방법입니다 통지 많은 데이터를 거치지 않고 해고에 대해. 그러나 주요 사용 사례는 닫기 이벤트에 대해 여러 리스너원할 때입니다 (상위 뷰 컨트롤러 만 제외).

But make sure to always remove yourself from NSNotificationCentre after you are done! Otherwise you risk of crashing by being called for notifications even after you are deallocated. [editor's note]

In MainViewController.m

- (IBAction)showSecondViewController:(id)sender 
{
    SecondViewController *secondVC = [[SecondViewController alloc] init];
    [self presentViewController:secondVC animated:YES completion:nil];

    // Set self to listen for the message "SecondViewControllerDismissed"
    // and run a method when this message is detected
    [[NSNotificationCenter defaultCenter] 
     addObserver:self
     selector:@selector(didDismissSecondViewController)
     name:@"SecondViewControllerDismissed"
     object:nil];
}

- (void)dealloc
{
    // simply unsubscribe from *all* notifications upon being deallocated
    [[NSNotificationCenter defaultCenter] removeObserver:self];
} 

- (void)didDismissSecondViewController 
{
    // this method gets called in MainVC when your SecondVC is dismissed
    NSLog(@"Dismissed SecondViewController");
}

In SecondViewController.m

- (IBAction)close:(id)sender 
{
    [self dismissViewControllerAnimated:YES completion:nil];

    // This sends a message through the NSNotificationCenter 
    // to any listeners for "SecondViewControllerDismissed"
    [[NSNotificationCenter defaultCenter] 
     postNotificationName:@"SecondViewControllerDismissed" 
     object:nil userInfo:nil];
}

Hope this helps!


The modal view should tell its parent to dismiss it, then the parent will know because it is responsible for doing the dismissing.

An example of this can be seen if you create a new project and choose the Utility Application template.

ReferenceURL : https://stackoverflow.com/questions/10387039/how-can-i-detect-the-dismissal-of-a-modal-view-controller-in-the-parent-view-con

반응형