표시된 보기 컨트롤러 해제
이론적인 질문이 있습니다.지금 Apple의 View Controller 가이드를 읽고 있습니다.
그들은 다음과 같이 썼습니다.
제시된 뷰 컨트롤러를 해제할 때는 제시된 뷰 컨트롤러가 해제되도록 하는 것이 좋습니다.즉, 가능할 때마다 뷰 컨트롤러를 제공한 동일한 뷰 컨트롤러도 해당 뷰 컨트롤러를 해제할 책임을 져야 합니다.제시된 뷰 컨트롤러가 해제되어야 함을 제시된 뷰 컨트롤러에게 알리는 몇 가지 기법이 있지만, 선호되는 기법은 위임입니다.
그러나 제시된 VC에서 프로토콜을 생성하고 대리자 변수를 추가하고 제시된 VC를 해제하기 위해 VC에서 대리자 메서드를 생성해야 하는 이유를 설명할 수 없습니다. 제시된 뷰 컨트롤러 메서드에서 단순한 호출 대신에
[self dismissViewControllerAnimated:NO completion:nil]
?
왜 첫 번째 선택이 더 나은가요?애플이 추천하는 이유는 무엇입니까?
저는 애플이 잠재적으로 흐리멍덩한 API를 위해 여기서 그들의 뒤를 조금 가리고 있다고 생각합니다.
[self dismissViewControllerAnimated:NO completion:nil]
사실은 약간의 바이올린입니다.표시된 보기 컨트롤러에서 합법적으로 이를 호출할 수 있지만 메시지를 표시 보기 컨트롤러로 전달하는 것이 전부입니다.VC를 무시하는 것 이상의 작업을 수행하려면 이를 알아야 하며, 위임 방법과 거의 동일한 방식으로 처리해야 합니다. 즉, 약간 융통성이 없는 기본 대리 방법입니다.
아마도 그들은 사람들이 이것이 어떻게 조립되는지 이해하지 못해서 많은 나쁜 코드들을 접했을 것입니다. 그래서 그들의 주의.
하지만 물론, 당신이 해야 할 일이 그것을 무시하는 것이라면, 계속하세요.
저만의 접근 방식은 타협입니다. 적어도 무슨 일이 일어나고 있는지 상기시켜 줍니다.
[[self presentingViewController] dismissViewControllerAnimated:NO completion:nil]
[신속]
self.presentingViewController?.dismiss(animated: false, completion:nil)
Swift 3용으로 업데이트됨
저는 단지 현재의 (제시된) View 컨트롤러를 해지하고 싶어서 여기에 왔습니다.저는 같은 목적으로 이곳에 오는 사람들을 위해 이 대답을 하는 것입니다.
내비게이션 컨트롤러
만약 당신이 내비게이션 컨트롤러를 사용하고 있다면, 그것은 꽤 쉽습니다.
이전 보기 컨트롤러로 돌아갑니다.
// Swift
self.navigationController?.popViewController(animated: true)
// Objective-C
[self.navigationController popViewControllerAnimated:YES];
루트 보기 컨트롤러로 돌아갑니다.
// Swift
self.navigationController?.popToRootViewController(animated: true)
// Objective-C
[self.navigationController popToRootViewControllerAnimated:YES];
(목표 C에 대한 이 답변 덕분입니다.)
모달 뷰 컨트롤러
View 컨트롤러가 모듈식으로 표시되면 다음을 호출하여 (두 번째 View 컨트롤러에서) 해제할 수 있습니다.
// Swift
self.dismiss(animated: true, completion: nil)
// Objective-C
[self dismissViewControllerAnimated:YES completion:nil];
문서에는 다음과 같이 나와 있습니다.
제시된 뷰 컨트롤러는 제시된 뷰 컨트롤러를 해제할 책임이 있습니다.제시된 뷰 컨트롤러 자체에서 이 메서드를 호출하면 UIKit는 제시된 뷰 컨트롤러에 해제 처리를 요청합니다.
따라서 제시된 뷰 컨트롤러가 스스로 호출할 수 있습니다.여기 완전한 예가 있습니다.
대표자
OP의 질문은 의견을 무시하기 위해 대의원을 사용하는 복잡성에 관한 것이었습니다.
저는 보통 내비게이션 컨트롤러나 모달 뷰 컨트롤러를 가지고 있기 때문에 지금까지는 대리인을 사용할 필요가 없었지만, 앞으로 대리인 패턴을 사용해야 할 경우 업데이트를 추가할 것입니다.
이는 뷰 컨트롤러 재사용을 위한 것입니다.
보기 컨트롤러는 보기가 모달로 표시되는지, 탐색 컨트롤러에서 푸시되는지 또는 무엇이든 상관하지 않습니다.보기 컨트롤러가 자동으로 해제되면 보기 컨트롤러가 형식적으로 표시되는 것으로 가정합니다.해당 보기 컨트롤러를 탐색 컨트롤러에 푸시할 수 없습니다.
프로토콜을 구현하면 상위 보기 컨트롤러가 표시/푸시 및 해제/팝업 방법을 결정할 수 있습니다.
사용해 보십시오.
[self dismissViewControllerAnimated:true completion:nil];
제 경험에 따르면, 원하는 View 컨트롤러에서 이 기능을 해제하고 이 기능을 해제하는 각 View 컨트롤러에 대해 다른 작업을 수행해야 할 때 유용합니다.프로토콜을 채택하는 모든 viewController는 고유한 방식으로 보기를 무시할 수 있습니다.(iphone과 비교하거나, 서로 다른 뷰에서 다른 데이터를 전달하거나, 서로 다른 메서드로 호출하는 등)
편집:
따라서, 명확하게 하기 위해, 만약 당신이 보기를 거부하고 싶다면, 저는 위임 프로토콜을 설정할 필요가 없다고 봅니다.다른 프레젠테이션 뷰 컨트롤러에서 제거한 후 다른 작업을 수행해야 하는 경우 대리자를 사용하는 것이 가장 좋습니다.
Swift 3.0 //Swift에서 View 컨트롤러 제거
self.navigationController?.popViewController(animated: true)
dismiss(animated: true, completion: nil)
View 컨트롤러 프로그래밍 가이드, "View 컨트롤러가 다른 View 컨트롤러를 표시하는 방법"에서 인용.
제시된 뷰 컨트롤러 체인의 각 뷰 컨트롤러에는 체인에서 자신을 둘러싼 다른 개체에 대한 포인터가 있습니다.즉, 다른 뷰 컨트롤러를 제공하는 제시된 뷰 컨트롤러에는 제시된 뷰 컨트롤러 속성과 제시된 뷰 컨트롤러 속성 모두에 유효한 개체가 있습니다.이러한 관계를 사용하여 필요에 따라 뷰 컨트롤러 체인을 추적할 수 있습니다.예를 들어 사용자가 현재 작업을 취소하는 경우 첫 번째로 표시된 보기 컨트롤러를 해제하여 체인의 모든 개체를 제거할 수 있습니다. 보기 컨트롤러를 해제하면 해당 보기 컨트롤러뿐만 아니라 표시된 모든 보기 컨트롤러도 해제됩니다.
그래서 한편으로는 균형 잡힌 디자인, 좋은 디커플링 등을 만듭니다.그러나 다른 한편으로는 매우 실용적입니다. 내비게이션의 특정 지점으로 빠르게 돌아갈 수 있기 때문입니다.
하지만 저는 개인적으로 제시된 뷰 컨트롤러 트리를 뒤로 넘기 보다는 세그를 푸는 것을 사용하고 싶습니다. 이 트리는 Apple이 이 장에서 언급한 인용문의 출처입니다.
한 가지 요점은 이것이 좋은 코딩 접근법이라는 것입니다.그것은 많은 사람들을 만족시킵니다.OOP
원칙(예: SRP, 우려의 분리 등)
따라서 뷰를 표시하는 뷰 컨트롤러는 뷰를 무시하는 컨트롤러여야 합니다.
예를 들어, 임대주택을 주는 부동산 회사가 그것을 다시 가져갈 수 있는 권한이 되어야 합니다.
Michael Enriquez의 대답 외에도, 저는 이것이 결정되지 않은 상태로부터 여러분 자신을 보호하는 좋은 방법이 될 수 있는 또 다른 이유를 생각할 수 있습니다.
ViewController A가 ViewController B를 모듈식으로 제공한다고 가정합니다.그러나 당신은 A 뷰 컨트롤러에 대한 코드를 작성하지 않았을 수 있기 때문에 A 뷰 컨트롤러의 라이프사이클을 알지 못합니다.View 컨트롤러인 ViewController B를 표시한 후 5초가 지나면 해제될 수 있습니다.
이 경우, 단순히 사용하는 경우dismissViewController
ViewController B에서 자신을 제거할 경우, 충돌이나 검은 화면이 아니라 사용자의 관점에서 정의되지 않은 상태가 될 수 있습니다.
대신 대리자 패턴을 사용하는 경우 ViewController B의 상태를 인식하고 제가 설명한 것과 같은 경우에 맞게 프로그래밍할 수 있습니다.
스위프트
let rootViewController:UIViewController = (UIApplication.shared.keyWindow?.rootViewController)!
if (rootViewController.presentedViewController != nil) {
rootViewController.dismiss(animated: true, completion: {
//completion block.
})
}
나는 이것이 좋습니다:
(viewController.navigationController?.presentingViewController
?? viewController.presentingViewController
?? viewController).dismiss(animated: true)
모달 사용 보기를 사용하는 경우 해제합니다.
[self dismissViewControllerAnimated:NO completion:nil];
이것은 많은 헛소리입니다.위임은 필요할 때는 괜찮지만, 코드를 더 복잡하게 만들 경우에는 이유가 있어야 합니다.
나는 애플이 이유가 있다고 확신합니다.그러나 제시된 VC가 다른 이유가 없고 오늘 현재 제가 볼 수 있는 것을 제시한 사람이 없는 한 단순히 기각을 하도록 하는 것이 더 명확하고 간결합니다.
프로토콜은 필요할 때는 훌륭하지만 객체 지향 설계는 모듈이 서로 불필요하게 통신하도록 하는 것이 아니었습니다.
Tom Love (목표 C의 공동 개발자)는 목표 C가 "우아함", "작음", "위기", 그리고 (C++과 비교했을 때) 잘 정의된" 것이라고 말한 적이 있습니다.그가 말하는 것은 쉽습니다.위임은 "단순히" 과도하게 사용된 것처럼 보이는 유용한 기능이며, 저는 언어로 일하는 것을 좋아하지만, 불필요한 구문을 사용하여 필요한 것보다 더 복잡하게 만들어야 한다는 생각이 두렵습니다.
질문의 제목에만 초점을 맞추면, 이것이 정답입니다.
presentedViewController?.dismiss(animated: true)
언급URL : https://stackoverflow.com/questions/14636891/dismissing-a-presented-view-controller
'itsource' 카테고리의 다른 글
범위의 각 셀 주변 경계 (0) | 2023.06.01 |
---|---|
VBA를 사용하여 HTML 테이블을 Excel로 변환 (0) | 2023.06.01 |
다운타임 없이 ASP.NET 애플리케이션을 배포하는 방법 (0) | 2023.06.01 |
텍스트/입력 상자 주변의 포커스 테두리(아웃라인)를 제거하는 방법은 무엇입니까?(크롬) (0) | 2023.06.01 |
iOS에서 입력 텍스트 색상 사용 안 함 (0) | 2023.06.01 |