在iOS 13上检测表格被解散

170
在iOS 13之前,呈现的视图控制器通常会覆盖整个屏幕。当关闭时,父视图控制器的viewDidAppear函数将被执行。
现在,iOS 13默认将视图控制器呈现为一个卡片,这意味着该卡片将部分覆盖底层视图控制器,也就是说,viewDidAppear不会被调用,因为父视图控制器实际上从未消失。
有没有一种方法可以检测到已解除显示的视图控制器表格?我可以在父视图控制器中覆盖另一个函数,而不是使用某种代理吗?

6
非常感谢您的信任,请问需要翻译哪种语言?中文还是其他语言? - matt
那么有没有一种方法可以将所有模态表单同时关闭到根视图控制器? - Weslie
https://dev59.com/ElMI5IYBdhLWcg3wV6Jr - Varsha Vijayvargiya
你为什么需要知道它何时被解雇?如果是为了重新加载数据和更新UI,通知或KVO可能是一个不错的选择。 - martn_st
13个回答

-2
如果您在FullScreen中使用了ModalPresentationStyle,则控制器的行为将像往常一样返回。
ConsultarController controllerConsultar = this.Storyboard.InstantiateViewController("ConsultarController") as ConsultarController; controllerConsultar.ModalPresentationStyle = UIModalPresentationStyle.FullScreen; this.NavigationController.PushViewController(controllerConsultar, true);

重复现有答案。 - matt

-3

从我的角度来看,苹果不应该将pageSheet设置为默认的modalPresentationStyle

我想通过使用swizzlingfullScreen样式恢复为默认值

像这样:

private func _swizzling(forClass: AnyClass, originalSelector: Selector, swizzledSelector: Selector) {
    if let originalMethod = class_getInstanceMethod(forClass, originalSelector),
       let swizzledMethod = class_getInstanceMethod(forClass, swizzledSelector) {
        method_exchangeImplementations(originalMethod, swizzledMethod)
    }
}

extension UIViewController {

    static func preventPageSheetPresentationStyle () {
        UIViewController.preventPageSheetPresentation
    }

    static let preventPageSheetPresentation: Void = {
        if #available(iOS 13, *) {
            _swizzling(forClass: UIViewController.self,
                       originalSelector: #selector(present(_: animated: completion:)),
                       swizzledSelector: #selector(_swizzledPresent(_: animated: completion:)))
        }
    }()

    @available(iOS 13.0, *)
    private func _swizzledPresent(_ viewControllerToPresent: UIViewController,
                                        animated flag: Bool,
                                        completion: (() -> Void)? = nil) {
        if viewControllerToPresent.modalPresentationStyle == .pageSheet
                   || viewControllerToPresent.modalPresentationStyle == .automatic {
            viewControllerToPresent.modalPresentationStyle = .fullScreen
        }
        _swizzledPresent(viewControllerToPresent, animated: flag, completion: completion)
    }
}

然后将这行代码放到你的AppDelegate

UIViewController.preventPageSheetPresentationStyle()

1
这很巧妙,但我不能同意。这是 hacky 的,并且更重要的是,它违背了 iOS 13 的本质。在 iOS 13 中,您应该使用“卡片”呈现方式。Apple 希望我们作出的回应不是“绕过它”,而是“适应它”。 - matt
1
是的,但正如我在自己的答案中已经说过的那样,这对于非全屏演示(例如iPad上的弹出窗口和页面/表单表)始终是一个问题,因此这并不新鲜。只是现在有更多的问题。依赖于viewWillAppear在某种意义上总是错误的。当然,我不喜欢苹果公司来削弱我的立场。但正如我所说,我们必须接受这一点,并用新的方式做事。 - matt
在我的项目中,有一些情况我不知道一个视图控制器(称为“presentedController”)是如何呈现的,也不知道确切的“presentingViewController”。例如:在某些情况下,我必须使用UIViewController.topMostViewController(),它会返回当前窗口上最顶层的视图控制器。因此,我想进行方法交换以保持当前行为,在我的视图控制器的viewWillAppear中执行正确的操作(刷新数据、UI)。如果您有任何解决方案,请帮忙提供。 - jacob
好的,我在回答末尾链接的解决方案确实可以解决这个问题。在演示时需要做一些配置工作,但基本上保证了每个演示者(包括警报演示者)都听到呈现的视图控制器被解除的消息。 - matt
是的,这很痛苦,但交换也是如此。不管怎样,争论很有趣!:) 感谢讨论。 - matt
显示剩余2条评论

-7

在dismiss之前调用presentingViewController.viewWillAppear会不会很简单?

self.presentingViewController?.viewWillAppear(false)
self.dismiss(animated: true, completion: nil)

5
不归你管。 - matt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接