7

在 Xcode beta 2 和 iOS 10 beta 2 之前,我有一个可以正常工作的自定义 UIPresentationController。我没有更改任何代码,但演示文稿现在以标准模式演示文稿呈现。

UIPresentationController 的 Apple 示例代码中有一条注释说:

对于将使用自定义演示控制器的演示,该演示控制器也可以是 transitioningDelegate。这避免了在源视图控制器中引入另一个对象或实现。

transitioningDelegate 不持有对其目标对象的强引用。为了防止在调用 -presentViewController:animated:completion 之前释放presentationController:将NS_VALID_UNTIL_END_OF_SCOPE 属性附加到声明中。

我在演示前后检查了演示视图控制器上的 transitioningDelegate。在它之前是我的自定义 UIPresentationController,但在它之后是 nil。我的猜测是该引用正在发布,但我在 Swift 中找不到与 NS_VALID_UNTIL_END_OF_SCOPE 等效的内容。编辑:我已经验证了 transitioningDelegate 设置到演示之前,然后是 nil 时演示。

我在呈现视图控制器中的代码:

@IBAction func buttonAction(_ sender: UIButton) {
    let secondViewController = storyboard!.instantiateViewController(withIdentifier: "NewViewController") as! NewViewController
    let presentationController = MyPresentationController(presentedViewController: secondViewController, presenting: self)
    presentationController.initialFrame = button.frame
    secondViewController.transitioningDelegate = presentationController

    // Move map
    let pixelsToMove: CGFloat = mapView.frame.height / 4
    let region = self.mapView.region

    self.mapView.setRegion(region, offsetBy: pixelsToMove, animated: true)

    // Delegate to NewViewController
    secondViewController.mapView = mapView
    mapView.delegate = secondViewController

    print(secondViewController.transitioningDelegate)
    UIView.animate(withDuration: 0.3, animations: {
        let tabBar = self.tabBarController!.tabBar
        tabBar.frame.origin.y += tabBar.frame.height

        self.present(secondViewController, animated: true, completion: nil)
    })
}

我在 UIPresentationController 中的代码:

override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) {
    super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
    presentedViewController.modalPresentationStyle = .custom
}
4

2 回答 2

4

transitioningDelegate物业是一个weak var。请参阅此处的文档。这意味着presentationController设置时不会增加保留计数secondViewController.transitioningDelegate = presentationController。由于您在该方法中进行实例化presentationController,并且没有其他任何东西对该对象具有强引用,因此它的保留计数将变为 0,并且一旦从该函数返回控制权,它将为零(就在 之后print(secondViewController.transitioningDelegate),因为UIView.animate(...)是异步的)。

presentationController您将需要一些东西来在视图控制器的整个演示过程中保持强烈的参考。由于某些东西强烈地保留在引用上,它的保留计数不会低于 1,直到您专门将该引用设置为nil. 一种解决方案是将其保留为当前类的属性或secondViewController.

于 2016-08-01T18:54:45.793 回答
2

问题在于 beta 2 中的方法签名发生了UIViewControllerTransitioningDelegate变化,因此在我的代码中没有调用它们。我不明白为什么,但在没有明确存储对演示控制器的强引用的情况下,一切都再次完美运行。

于 2016-08-07T17:05:08.720 回答