[ios] dismissModalViewControllerAnimated 사용 중지됨

iPhone 5 용 4 인치 디스플레이에서 실행되도록 iOS 앱을 업데이트하기 위해 XCode 4.5로 업그레이드했지만 다음과 같은 빌드 오류가 발생 dismissModalViewControllerAnimated:' is deprecated합니다.

[self dismissModalViewControllerAnimated:NO];

다음과 같이 완료 핸들러 (하지만 NULL로 설정)를 사용하여 권장 오버로드로 업데이트하려고했습니다.

[self dismissModalViewControllerAnimated:NO completion:NULL];

그러나이 줄은 두 가지 오류를 발생시킵니다.

warning: 'TabBarController' may not respond to '-presentModalViewController:animated:completion:'
Instance method '-presentModalViewController:animated:completion:' not found (return type defaults to 'id')

감사!



답변

새로운 방법은 다음과 같습니다.

[self dismissViewControllerAnimated:NO completion:nil];

모달 이라는 단어 가 제거되었습니다. 제시하는 API 호출과 마찬가지로 :

[self presentViewController:vc animated:NO completion:nil];

그 이유는 2012 WWDC 세션 236-iOS 비디오 에서보기 컨트롤러의 진화 에서 논의되었습니다 . 기본적으로이 API에서 제공하는 뷰 컨트롤러는 더 이상 항상 모달이 아니며 완료 핸들러를 추가했기 때문에 이름을 바꾸는 것이 좋습니다.

Marc의 의견에 대한 답변 :

4.3 이상의 모든 장치를 지원하는 가장 좋은 방법은 무엇입니까? 새로운 방법은 iOS4에서 작동하지 않지만 이전 방법은 iOS6에서 더 이상 사용되지 않습니다.

나는 이것이 거의 별개의 질문이라는 것을 알고 있지만 모든 사람이 3 년마다 모든 장치를 업그레이드 할 돈이있는 것은 아니기 때문에 언급 할 가치가 있다고 생각합니다. 그래서 많은 사람들이 이전 (5.0 이전) 장치를 가지고 있습니다. 그래도 말하면 고통 스럽지만 5.0 미만을 타겟팅 할 가치가 있는지 고려해야합니다. 5.0 이하에서는 사용할 수없는 새롭고 멋진 API가 많이 있습니다. 그리고 애플은 계속해서 그들을 목표로 삼는 것을 더 어렵게 만들고 있습니다. 예를 들어 armv6 지원은 Xcode 4.5에서 삭제되었습니다.

5.0 미만을 목표로하려면 (완료 블록이 nil 인 한) handy respondsToSelector: 메소드를 사용하십시오 .

if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]){
    [self presentViewController:test animated:YES completion:nil];
} else {
    [self presentModalViewController:test animated:YES];
}

Marc의 또 다른 의견에 대한 답변 :

그것은 내 응용 프로그램에서 상당히 많은 If 문이 될 수 있습니다! …이 코드를 캡슐화하는 범주를 만들려고 생각하고 있었는데 UIViewControler에 범주를 만들면 거부됩니까?

그리고 Full Decent에서 하나 :

… 수동으로 컴파일러 경고를 표시하지 않도록하는 방법이 있습니까?

첫째, 아니요, UIViewController자체적 으로 카테고리를 생성 해도 앱이 거부되지는 않습니다. 카테고리 메소드가 개인 API 또는 유사한 것을 호출하지 않는 한.

카테고리 메소드는 이러한 코드에 매우 좋은 위치입니다. 또한 더 이상 사용되지 않는 API에 대한 호출이 하나만 있기 때문에 컴파일러 경고가 하나만 있습니다.

Full Decent의 의견 (질문)을 해결하기 위해 예, 컴파일러 경고를 수동으로 억제 할 수 있습니다. 여기에 바로 그 주제에 대한 답변에 대한 링크가 있습니다. 범주 메서드는 경고를 한 곳에서만 억제하므로 컴파일러 경고를 억제하는데도 좋습니다. 당신은 확실히 컴파일러를 무의미하게 침묵시키고 싶지 않을 것입니다.

이에 대한 간단한 카테고리 메소드를 작성하면 다음과 같을 수 있습니다.

@implementation UIViewController (NJ_ModalPresentation)
-(void)nj_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion{
    NSAssert(completion == nil, @"You called %@ with a non-nil completion. Don't do that!",NSStringFromSelector(_cmd));
    if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]){
        [self presentViewController:viewControllerToPresent animated:flag completion:completion];
    } else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
        [self presentModalViewController:viewControllerToPresent animated:flag];
#pragma clang diagnostic pop
    }
}
@end


답변

이제 iOS 6 이상에서 다음을 사용할 수 있습니다.

[[Picker presentingViewController] dismissViewControllerAnimated:YES completion:nil];

대신에:

[[Picker parentViewControl] dismissModalViewControllerAnimated:YES];

… 다음을 사용할 수 있습니다.

[self presentViewController:picker animated:YES completion:nil];

대신에

[self presentModalViewController:picker animated:YES];    


답변

[self dismissModalViewControllerAnimated:NO]; 더 이상 사용되지 않습니다.

[self dismissViewControllerAnimated:NO completion:nil];대신 사용하십시오 .


답변

사용하다

[self dismissViewControllerAnimated:NO completion:nil];


답변

경고는 여전히 있습니다. 그것을 제거하기 위해 다음과 같은 선택기에 넣습니다.

if ([self respondsToSelector:@selector(dismissModalViewControllerAnimated:)]) {
    [self performSelector:@selector(dismissModalViewControllerAnimated:) withObject:[NSNumber numberWithBool:YES]];
} else {
    [self dismissViewControllerAnimated:YES completion:nil];
}

그것은 나처럼 강박증을 가진 사람들에게 유익합니다;)


답변

다음은 저와 같은 다른 초보자에게 도움이되는 경우 사용한 해당 presentViewController 버전입니다.

if ([self respondsToSelector:@selector(presentModalViewController:animated:)]) {
    [self performSelector:@selector(presentModalViewController:animated:) withObject:testView afterDelay:0];
} else {
    [self presentViewController:configView animated:YES completion:nil];
}
[testView.testFrame setImage:info]; //this doesn't work for performSelector
[testView.testText setHidden:YES];

나는 ViewController를 ‘일반적으로’사용했고, 호출 된 (setHidden 및 setImage 사용)에 따라 모달 뷰를 다르게 표시 할 수있었습니다. 그리고 이전에는 잘 작동했지만 performSelector는 ‘set’항목을 무시하므로 결국 내가 시도한 것처럼 효율적으로 시도하면 좋지 않은 솔루션 인 것 같습니다.


답변