Утрата ссылки на 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
,