Утрата ссылки на transitioningDelegate перед представлением presetentation

У меня был рабочий пользовательский UIPresentationController до Xcode beta 2 и iOS 10 beta 2. Я не изменил никакого кода, но презентация теперь представлена ​​со стандартной модальной презентацией.

В примере кода Apple для UIPresentationController есть примечание:

Для презентаций, которые будут использовать пользовательский контроллер презентаций, этот контроллер презентаций также может быть transitioningDelegate. Это позволяет избежать введения другого объекта или реализации в контроллере представления источника.

transitioningDelegate не содержит строгой ссылки на свой целевой объект. Чтобы предотвратить выпуск presentationController перед вызовом -presentViewController:animated: завершение: атрибут NS_VALID_UNTIL_END_OF_SCOPE добавляется к объявлению.

Я проверил transitioningDelegate на представленном контроллере представления до и после представления. До этого мой пользовательский UIPresentationController, но после него ноль. Я предполагаю, что ссылка выпущена, но я не могу найти эквивалент NS_VALID_UNTIL_END_OF_SCOPE в Swift. РЕДАКТИРОВАТЬ: я проверил, что transitioningDelegate настроен до непосредственно перед презентацией, а затем ноль, когда пришло время представить.

Мой код в представлении контроллера представления:

@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
}

2 ответа

Решение

Проблема была в бета 2 метода подписи вUIViewControllerTransitioningDelegate изменилось, и поэтому они не были вызваны в моем коде. Я не понимаю почему, но еще раз все работает отлично, без явного сохранения строгой ссылки на контроллер представления.

transitioningDelegate собственность weak var, Смотрите документы здесь. Это означает, что сохранение рассчитывать на presentationController не увеличивается при настройке secondViewController.transitioningDelegate = presentationController, Так как вы создаете presentationController в этом методе, и ничто иное не имеет строгой ссылки на этот объект, его счетчик сохранения будет равен 0, и он будет равен нулю, как только управление вернется из этой функции (сразу после print(secondViewController.transitioningDelegate), поскольку UIView.animate(...) асинхронный).

Вам нужно что-то, чтобы сохранить сильную ссылку на presentationController на протяжении всей презентации представления контроллера. С чем-то, сильно удерживающим ссылку, его счет удержания не опустится ниже 1, пока вы специально не установите эту ссылку на nil, Одним из решений было бы сохранить его как свойство текущего класса или свойство secondViewController,

Другие вопросы по тегам