Я столкнулся с парой случаев, когда было бы удобно найти «самый верхний» контроллер представления (тот, который отвечает за текущее представление), но не нашел способа сделать это.
В основном проблема заключается в следующем: учитывая, что каждый выполняется в классе, который не является контроллером представления (или представлением) [и не имеет адреса активного представления] и ему не был передан адрес самого верхнего контроллера представления ( или, скажем, адрес контроллера навигации), можно ли найти этот контроллер просмотра? (И если да, то как?)
Или, если это не удастся, можно найти самый верхний вид?
ios
objective-c
uiview
uiviewcontroller
uikit
Горячие лижет
источник
источник
Ответы:
iOS 4 представила свойство rootViewController в UIWindow:
Вам нужно будет установить его самостоятельно после создания контроллера вида.
источник
-[UINavigationController topViewController]
). Тогда есть слово «корень», который является корнем дерева (как-[UIWindow rootViewController]
.Я думаю, что вам нужно сочетание принятого ответа и @ fishstix's
Swift 3.0+
источник
UINavigationController
и попросить егоtopViewController
или даже проверитьUITabBarController
и попроситьselectedViewController
. Это даст вам контроллер представления, который в данный момент виден пользователю.Чтобы завершить ответ JonasG (который пропустил контроллеры панели вкладок при обходе), вот моя версия возврата видимого в данный момент контроллера представления:
источник
childViewControllers
Полная нерекурсивная версия, учитывающая различные сценарии:
UINavigationController
UITabBarController
Objective-C
Свифт 4+
источник
visibleViewController
чтобы было понятно, что он делает.Получение самого популярного контроллера представления для Swift с использованием расширений
Код:
Использование:
источник
Чтобы завершить ответ Эрика (который исключил всплывающие окна, контроллеры навигации, контроллеры табуляции, контроллеры представлений, добавленные в качестве подпредставлений к некоторым другим контроллерам представлений при обходе), вот моя версия возврата текущего видимого контроллера представлений:
================================================== ===================
================================================== ===================
И теперь все, что вам нужно сделать, чтобы получить самый верхний контроллер представления, это вызвать вышеуказанный метод следующим образом:
источник
Этот ответ включает
childViewControllers
и поддерживает чистую и читаемую реализацию.источник
Недавно я столкнулся с такой ситуацией в одном из моих проектов, в котором требовалось отображать представление уведомлений независимо от того, какой контроллер отображался, и какого бы типа он ни был (UINavigationController, классический контроллер или пользовательский контроллер представления), когда состояние сети изменилось.
Поэтому я просто выпустил свой код, который довольно прост и фактически основан на протоколе, так что он гибок с каждым типом контроллера контейнера. Кажется, это связано с последними ответами, но в гораздо более гибкой форме.
Вы можете получить код здесь: PPTopMostController
И получил самый верхний контроллер с помощью
источник
Это улучшение ответа Эрика:
_topMostController(UIViewController *cont)
вспомогательная функцияТеперь все, что вам нужно сделать, это позвонить,
topMostController()
и самый верхний UIViewController должен быть возвращен!источник
self
должен принадлежать.Вот мой взгляд на это. Спасибо @Stakenborg за указание на способ пропустить получение UIAlertView в качестве самого верхнего контроллера
источник
getSomething:
в Objective-C. Это имеет особое значение (подробнее: cocoadevcentral.com/articles/000082.php ), и вы не удовлетворяете этим требованиям в своем коде.источник
источник
Для последней версии Swift:
создайте файл, назовите его
UIWindowExtension.swift
и вставьте следующий фрагмент:Используйте его где угодно как:
источник
switch
вместо, если еще. 3. Я не уверен, что вам нужна статическая функция, я думаю, вы могли бы легко это сделать в объявленном вами уровне первого экземпляра var. 4. Вероятно, лучше не создавать слишком много глобальных функций, но это дело вкуса. Вы можете использовать одну строку кода для достижения эффекта глобальной функции:UIApplication.sharedApplication().delegate?.window?.visibleViewController
Простое расширение для
UIApplication
в Swift:НОТА:
Это заботится
moreNavigationController
внутриUITabBarController
Простое использование:
источник
Используйте расширение ниже, чтобы захватить текущий видимый
UIViewController
. Работал на Swift 4.0 и позжеSwift 4.0 и позже:
Как пользоваться?
источник
presentedViewController
первых, доUINavigationController
иUITabBarController
случаев? В противном случае, если контроллер представления модально представлен изUINavigationController
илиUITabBarController
, он не будет возвращен как контроллер вида сверху, даже если виден контроллер представления.Еще одно решение Swift
источник
Расширение Swift 4.2
Используйте его из любого места, как,
или как,
Подходит для любых классов, таких как UINavigationController, UITabBarController
Наслаждайтесь!
источник
Вот что сработало для меня.
Я обнаружил, что иногда в окне ключа контроллер был нулевым, поскольку keyWindow - это какая-то операционная система, например, оповещение и т. Д.
источник
Расширяя ответ @ Эрика, вы должны быть осторожны, так как keyWindow - это действительно то окно, которое вы хотите. Если вы пытаетесь использовать этот метод после касания чего-либо, например, в представлении оповещений, то keyWindow фактически будет окном оповещения, и это, несомненно, вызовет проблемы. Это случилось со мной в дикой природе при обработке глубоких ссылок через оповещение и вызвало SIGABRT без использования STACK TRACE. Всего сука для отладки.
Вот код, который я сейчас использую:
Не стесняйтесь смешивать это с любым вкусом получения контроллера вида сверху, который вам нравится из других ответов на этот вопрос.
источник
Альтернативное решение Swift:
источник
Это решение является наиболее полным. Это принимает во внимание: UINavigationController UIPageViewController UITabBarController И самый верхний представленный контроллер представления от контроллера вида сверху
Пример приведен в Swift 3.
Есть 3 перегрузки
источник
Краткое, но всеобъемлющее решение в Swift 4.2, учитывает UINavigationControllers , UITabBarControllers , представленные и дочерние контроллеры представления:
Использование:
источник
Отличное решение в Swift, внедрить в AppDelegate
источник
Я думаю, что большинство ответов полностью проигнорировано
UINavigationViewController
, поэтому я рассмотрел этот вариант использования с последующей реализацией.источник
Я знаю, что это очень поздно и может быть излишним. Но вот фрагмент, который я придумал, который работает для меня:
источник
Это прекрасно работает для поиска top viewController 1 из любого корневого элемента управления
источник
Не уверен, поможет ли это тому, чего вы пытаетесь достичь, найдя самый верхний контроллер представления, но я пытался представить новый контроллер представления, но если бы у моего корневого контроллера представления уже был модальный диалог, он был бы заблокирован, поэтому я будет цикл до вершины всех модальных контроллеров представления, используя этот код:
источник
Вы можете найти самый верхний контроллер вида, используя
источник
self
не имеетnavigationController
свойства.Другое решение основано на цепочке респондента, которая может работать или не работать в зависимости от того, что является первым респондентом:
Пример псевдокода:
источник
Swift:
Использование:
источник