В iPadOS 17 происходит сбой при закрытии всплывающего окна и последующем быстром его повторном отображении. Обычно ошибка следующая:
UIPopoverPresentationController должен иметь ненулевой sourceView или barButtonItem, установленный до начала презентации
Однако иногда я видел следующее:
Приложение попыталось модально представить контроллер представления, который уже представлен [контроллером основного представления]
Это минимальный исходный код, необходимый для воспроизведения этого сбоя:
класс ViewController: UIViewController { пусть popoverVC = UIViewController() @IBOutlet var showPopoverButton: UIButton! @IBAction func showPopoverTapped (_ отправитель: UIButton) { popoverVC.modalPresentationStyle = .popover popoverVC.popoverPresentationController?.sourceView = showPopoverButton настоящее время (popoverVC, анимированный: true) } } Некоторые дополнительные моменты, которые следует учитывать по этой проблеме:
[*]Этого не происходит в iOS 16 и более ранних версиях. [*]Установка .sourceRect в popoverPresentationController не имеет никакого эффекта. [*]Установка frame или preferredContentSize всплывающего окна не имеет никакого эффекта. [*]Сбой происходит в UIKit с раскадровками (жестко запрограммированный пользовательский интерфейс) или без них. [*]Сбой не происходит в SwiftUI. Пожалуйста, не предлагайте SwiftUI в качестве исправления. [*]Я могу добавить guard перед представлением, чтобы убедиться, что sourceView не nil, но это не имеет никакого эффекта.
Похоже, эта проблема возникает из-за того, что контроллер представления всплывающего окна не полностью освобождается от памяти при представлении нового всплывающего окна. Это создает своего рода столкновение. Мне удалось успешно провернуть UIPopoverPresentationController.dismissalTransitionWillBegin, и я был бы рад опубликовать это решение, но сначала мне хотелось бы посмотреть, есть ли менее хакерские обходные пути. Я не хочу просто переопределять dismissalTransitionWillBegin, потому что мне нужно поведение по умолчанию, и я бы не хотел переписывать свои собственные анимации всплывающих окон только для устранения этой ошибки.
