Xcode 8 Swift 3:未调用模态演示转换委托

Posted

技术标签:

【中文标题】Xcode 8 Swift 3:未调用模态演示转换委托【英文标题】:Xcode 8 Swift 3: Modal presentation transitioning delegate not called 【发布时间】:2016-09-14 18:58:50 【问题描述】:

问题

不调用“DrinkTransitioningDelegate”中的委托函数。 'td' 实例在演示文稿的生命周期期间和之后都保留在内存中。

class PresentingViewController: UIViewController 

    let td = DrinkTransitioningDelegate()

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        let item = inventory.beverages[indexPath.row]
        item.isSelected = true
        let controller = DrinkViewController(item: item)
        controller.delegate = self
        controller.transitioningDelegate = td
        controller.modalPresentationStyle = .custom
        //let navCon = UINavigationController(rootViewController: controller)
        //navCon.transitioningDelegate = td
        //navCon.modalPresentationStyle = .custom
        present(controller, animated: true)
    



class DrinkTransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate 

    func presentationControllerForPresentedViewController(presented: UIViewController, presentingViewController presenting: UIViewController!, sourceViewController source: UIViewController) -> UIPresentationController? 
        return DrinkPresentationViewController(presentedViewController:presented, presenting: presenting)
    

    let animationController = DrinkAnimatedTransition()

    func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? 
        animationController.isPresentation = true
        return animationController
    

    func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? 
        animationController.isPresentation = false
        return animationController
    

    deinit 
        print("adf")
    


历史

针对 ios 7 提出了问题here 针对 iOS 9 提出了问题here

【问题讨论】:

【参考方案1】:

解决方案

可选的协议功能现在是一个东西。

委托完全由可选函数组成,因此没有警告。

这些函数在编译器中显示为我自己的自定义函数。

func presentationControllerForPresentedViewController(presented: UIViewController, presentingViewController presenting: UIViewController!, sourceViewController source: UIViewController) -> UIPresentationController? 
    return DrinkPresentationViewController(presentedViewController:presented, presenting: presenting)


let animationController = DrinkAnimatedTransition()

func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? 
    animationController.isPresentation = true
    return animationController


func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? 
    animationController.isPresentation = false
    return animationController

这些是正确的函数。

func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? 
    return DrinkPresentationViewController(presentedViewController:presented, presenting: presenting)


func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? 
    let animationController = DrinkAnimatedTransition()
    animationController.isPresentation = true
    return animationController


func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? 
    let animationController = DrinkAnimatedTransition()
    animationController.isPresentation = false
    return animationController

【讨论】:

我已经被类似的问题困扰了好几个小时......在我的例子中,两个“animationController”函数被调用,而不是“presentationController”函数。 modalPresentationStyle 是 .custom。帮助!这让我彻底疯了! ;-) 好吧,想通了...实际上我从一些示例代码中复制了public func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController?另一个 版本。不记得确切的措辞,但编译器没有识别出错误。【参考方案2】:

您的 transitioningDelegate = self 可能没有足够早地被调用。围绕我的问题的解决方案是添加以下内容,然后调用 animationController(forPresented..) 和 animationController(forDismissed..)。

init() 
    super.init(nibName: nil, bundle: nil)
    modalPresentationStyle = .overCurrentContext
    transitioningDelegate = self


required init?(coder aDecoder: NSCoder) 
    super.init(coder: aDecoder)
    modalPresentationStyle = .overCurrentContext
    transitioningDelegate = self


您可能不需要以下行,但如果您有部分半抽屉屏幕,则在许多情况下留在此处。

modalPresentationStyle = .overCurrentContext

【讨论】:

将 transitionDelegate 添加到 inits 解决了我的问题,但我使用 .custom 作为演示样式,以便让 presentationController(..) 方法正常工作。

以上是关于Xcode 8 Swift 3:未调用模态演示转换委托的主要内容,如果未能解决你的问题,请参考以下文章

Swift 3.0 和 Xcode 8 迁移后未调用 UITableViewDelegate 方法

swift 1.2 / xcode 6.3 更新后未调用获取的结果控制器委托

升级到 Xcode 8 并将语法从 swift 2.3 转换为 swift 3.0 后文件丢失警告

UITextViewDelegate 方法在 Swift 3 和 Xcode 8.0 中给出“使用未声明的类型 URL”错误

在 Xcode 8 和 Swift 3 中将 UITextField 转换为 Integer 并使用它们进行计算

从 AppDelegate 调用 GameScene 方法(Swift 3、SpriteKit、Xcode 8)