Xcode 8 Swift 3:模态呈现转场代理未被调用

8

问题

'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中提出了这个问题,此处
  • iOS 9中提出了这个问题,此处
2个回答

34
解决方案

可选协议函数现在是一种事物。

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

这些函数对编译器来说就像我的自定义函数一样。

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
}

3
我在类似的问题上被卡了好几个小时......在我的情况下,这两个“animationController”函数被调用了,但是“presentationController”函数没有被调用。modalPresentationStyle是.custom。求助!这让我彻底发疯了!;-) - jbm
1
好的,问题解决了...实际上还有另一个版本的 public func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? 我是从一些示例代码中复制过来的。我记不清确切的措辞,但编译器没有识别出错误。 - jbm

3

你的 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

1
将transitionDelegate添加到inits中解决了我的问题,但为了让presentationController(..)方法正常工作,我使用了.custom作为呈现样式。 - Hedylove

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