iOS 13 이전에는 전체 화면을 덮는 데 사용되는 뷰 컨트롤러가 제시되었습니다. 그리고 해제되면 상위 뷰 컨트롤러 viewDidAppear
기능이 실행되었습니다.
이제 iOS 13은 뷰 컨트롤러를 기본으로 시트로 표시합니다. 즉, 카드가 기본 뷰 컨트롤러를 부분적으로 덮을 것입니다. 즉 viewDidAppear
, 부모 뷰 컨트롤러가 실제로 사라지지 않았기 때문에 호출되지 않습니다.
제시된 뷰 컨트롤러 시트가 닫 혔음 을 감지 하는 방법이 있습니까? 어떤 종류의 델리게이트를 사용 하는 대신 부모 뷰 컨트롤러에서 재정의 할 수있는 다른 기능이 있습니까?
답변
제시된 뷰 컨트롤러 시트가 닫 혔음을 감지하는 방법이 있습니까?
예.
어떤 종류의 델리게이트를 사용하는 대신 부모 뷰 컨트롤러에서 재정의 할 수있는 다른 기능이 있습니까?
아니요. “어떤 종류의 대리인”이 당신이하는 방식입니다. 자신을 프레젠테이션 컨트롤러의 델리게이트로 만들고 presentationControllerDidDismiss(_:)
.
전체 화면이든 아니든, 제시된 뷰 컨트롤러가 닫 혔음을 알리는 일반적인 런타임 생성 이벤트의 부족은 실제로 문제가됩니다. 그러나 항상 전체 화면이 아닌 뷰 컨트롤러가 있기 때문에 새로운 문제는 아닙니다. 이제 (iOS 13에서) 더 많은 것들이 있습니다! 다른 곳에서이 주제에 대해 별도의 질문과 대답을 할애합니다. Unified UIViewController가 “최전방이 된”탐지입니까? .
답변
다음 은 시트로 표시되는 자식 뷰 컨트롤러 (즉, 기본 iOS 13 방식)가 닫힐 때 알림을받는 부모 뷰 컨트롤러의 코드 예제입니다 .
public final class Parent: UIViewController, UIAdaptivePresentationControllerDelegate
{
// This is assuming that the segue is a storyboard segue;
// if you're manually presenting, just see the delegate there.
public override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "mySegue" {
segue.destination.presentationController?.delegate = self;
}
}
public func presentationControllerDidDismiss(
_ presentationController: UIPresentationController)
{
// Only called when the sheet is dismissed by DRAGGING.
// You'll need something extra if you call .dismiss() on the child.
// (I found that overriding dismiss in the child and calling
// presentationController.delegate?.presentationControllerDidDismiss
// works well).
}
}
Jerland2의 대답은 시트가 될 때 (A) 원래 질문자가 함수 호출을받을 싶어하기 때문에, 혼란 기각 (그가 전화했을 때 사용자가 시도되고 presentationControllerDidAttemptToDismiss 구현 반면 과 실패 , 그리고 (b) 설정 isModalInPresentation 시트를 닫를) 완전히 직교하며 실제로 제시된 시트를 닫을 수 없게 만듭니다 (OP가 원하는 것과 반대 임).
답변
또 다른 옵션은 다시 얻을 수 viewWillAppear
와 viewDidAppear
세트입니다
let vc = UIViewController()
vc.modalPresentationStyle = .fullScreen
이 옵션은 전체 화면을 덮고 닫은 후 위의 메서드를 호출합니다.
답변
미래의 독자를 위해 여기에 구현에 대한 더 완전한 답변이 있습니다.
- 루트 뷰 컨트롤러에서 segue를 준비하려면 다음을 추가하십시오 (모달에 nav 컨트롤러가 있다고 가정)
// Modal Dismiss iOS 13
modalNavController.presentationController?.delegate = modalVc
- 모달 뷰 컨트롤러에서 다음 대리자 + 메서드를 추가합니다.
// MARK: - iOS 13 Modal (Swipe to Dismiss)
extension ModalViewController: UIAdaptivePresentationControllerDelegate {
func presentationControllerDidAttemptToDismiss(_ presentationController: UIPresentationController) {
print("slide to dismiss stopped")
self.dismiss(animated: true, completion: nil)
}
}
- 모달 뷰 컨트롤러에서 대리자 메서드를 호출하려면 다음 속성이 참인지 확인하십시오.
self.isModalInPresentation = true
- 이익
답변
빠른
호출에 일반 솔루션 viewWillAppear
에 iOS13
class ViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("viewWillAppear")
}
//Show new viewController
@IBAction func show(_ sender: Any) {
let newViewController = NewViewController()
//set delegate of UIAdaptivePresentationControllerDelegate to self
newViewController.presentationController?.delegate = self
present(newViewController, animated: true, completion: nil)
}
}
extension UIViewController: UIAdaptivePresentationControllerDelegate {
public func presentationControllerDidDismiss( _ presentationController: UIPresentationController) {
if #available(iOS 13, *) {
//Call viewWillAppear only in iOS 13
viewWillAppear(true)
}
}
}
답변
DRAG OR CALL DISMISS FUNC는 아래 코드에서 작동합니다.
1) 루트 뷰 컨트롤러에서 아래 코드와 같이 프레젠테이션 뷰 컨트롤러가 무엇인지 알려줍니다.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "presenterID" {
let navigationController = segue.destination as! UINavigationController
if #available(iOS 13.0, *) {
let controller = navigationController.topViewController as! presentationviewcontroller
// Modal Dismiss iOS 13
controller.presentationController?.delegate = self
} else {
// Fallback on earlier versions
}
navigationController.presentationController?.delegate = self
}
}
2) 다시 루트 뷰 컨트롤러에서 프레젠테이션 뷰 컨트롤러가 해산 될 때 수행 할 작업을 알려줍니다.
public func presentationControllerDidDismiss(
_ presentationController: UIPresentationController)
{
print("presentationControllerDidDismiss")
}
1) 프레젠테이션 뷰 컨트롤러에서이 그림에서 취소 또는 저장 버튼을 누르면. 아래 코드가 호출됩니다.
self.dismiss(animated: true) {
self.presentationController?.delegate?.presentationControllerDidDismiss?(self.presentationController!)
}
답변
해제되는 UIViewController에서 viewWillDisappear를 재정의합니다. isBeingDismissed
부울 플래그 를 통해 해고를 알립니다 .
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if isBeingDismissed {
print("user is dismissing the vc")
}
}
** 사용자가 아래로 스 와이프하고 카드를 다시 위로 스 와이프하면 카드가 해제되지 않은 경우에도 해제 된 것으로 등록됩니다. 그러나 그것은 당신이 신경 쓰지 않을 수있는 가장 중요한 경우입니다.