Как получить самый верхний контроллер представления на iPad с несколькими сценами (UIScene) в Swift?IOS

Программируем под IOS
Ответить
Anonymous
 Как получить самый верхний контроллер представления на iPad с несколькими сценами (UIScene) в Swift?

Сообщение Anonymous »

У меня есть метод получения самого верхнего контроллера представления в приложениях iOS без нескольких сцен, который отлично работает для приложений с одним окном как на iPhone, так и на iPad:

Код: Выделить всё

extension UIApplication {

// Get top most view controller in App.

class func getTopMostViewController(base: UIViewController? = UIApplication.shared.windows.filter { $0.isKeyWindow }.first?.rootViewController) -> UIViewController? {

if let nav = base as? UINavigationController {
return getTopMostViewController(base: nav.visibleViewController)
}

if let tab = base as? UITabBarController {
if let selected = tab.selectedViewController {
return getTopMostViewController(base: selected)
}
}
if let presented = base?.presentedViewController {
return getTopMostViewController(base: presented)
}

return base
}
}
Однако с появлением нескольких сцен (UIScene) в iOS 13 мне нужен способ получить самый верхний контроллер представления, который может обрабатывать несколько окон и сцен. Я адаптировал функцию следующим образом:

Код: Выделить всё

extension UIApplication {

class func getTopViewController(base: UIViewController? = keyWindow?.rootViewController) -> UIViewController? {
// Find the most visible view controller in the hierarchy

if let nav = base as? UINavigationController {
return getTopViewController(base: nav.visibleViewController)
}

if let tab = base as? UITabBarController {
if let selected = tab.selectedViewController {
return getTopViewController(base: selected)
}
}

if let presented = base?.presentedViewController {
return getTopViewController(base: presented)
}

return base
}

private static var keyWindow: UIWindow? {
// Get connected scenes
return UIApplication.shared.connectedScenes
// Keep only active scenes, onscreen and visible to the user
.filter { $0.activationState == .foregroundActive }
// Keep only the first `UIWindowScene`
.compactMap { $0 as? UIWindowScene }
// Get its associated windows
.flatMap { $0.windows }
// Finally, keep only the key window
.first { $0.isKeyWindow }
}
}
В большинстве случаев это работает нормально, но иногда keyWindow на iPhone равен нулю. Я попробовал добавить задержку в 0,5 секунды и сделать функцию асинхронной, и это сработало, но мне нужно синхронное решение, которое надежно работает как для одной, так и для нескольких сцен/окон.
Как я могу это изменить? функцию, чтобы всегда синхронно получать правильный верхний контроллер представления?
Дополнительный контекст:
Я ориентированы на iOS 13 и более поздних версий.
Примечание. Прежде всего, я хочу, чтобы вторая функция работала на iPhone в каждом случае, когда в настоящее время закрывается диалоговое окно разрешения камеры, и я немедленно вызываю вторую функцию при обратном вызове диалогового окна. , то эта проблема возникает, когда ключевое окно равно нулю.

Подробнее здесь: https://stackoverflow.com/questions/785 ... -uiscene-i
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»