Swift как с модального экрана делать pushviewcontroller
Решение 1. Сначала закройте модальное окно, получите соответствующий контроллер навигации, а затем нажмите новый контроллер.
Решение 2. В модальном окне перейдите в модальное окно, чтобы появился контроллер навигации.
Схема 3. Пуш на модальном
Интеллектуальная рекомендация
Poj2796 чувствую себя хорошим одиноким стеком
http://poj.org/problem?id=2796 Значение: требует поиска диапазона значения, интервальное значение, определенное как минимум интервала интервала и умножения. Практика: непосредственно нашел интервалы с.
Начало работы с spring-mvc (1): примеры начала работы
введение 1.MVC :Model-View-Control РамообразнойC Основная работа, которую необходимо выполнить на уровне: инкапсуляцияweb Запрос является объектом данных, вызывает уровень бизнес-логики для обработки .
От Дао к Джейн — Душа архитектуры RISC-V (Часть 2)
Эта статья входит в серию статей «Проектирование ЦП RISC-V» и «Разработка встроенного программного обеспечения RISC-V». Примечание. Эта статья представляет собой отрывок из пер.
последовательность очереди
При написании кода вам необходимо добавить заголовочный файл «очередь», за которым следует #include «алгоритм». с использованием пространства имен std; также есть q, pop () при.
N Вопрос королевы (рекурсивный + обратно) Реализация C ++
N Вопросы королевы (рекурсивный + назад N Queens, выпущенные технологией функции имитации C ++: Решить класс проблем: Основная функция: результат Результаты здесь опущены, и существует 92 консенсус бе.
Вам также может понравиться
Bluetooth 4.0 BLE Программирование Вопросы, связанные с вопросами решения (воспроизводится)
Q: Что такое связь Bluetooth? A: Оригинальный дизайн связи Bluetooth заключается в том, чтобы облегчить низкую стоимость между мобильными телефонами (мобильными телефонами) и аксессуарами, беспроводны.
Напишите скрипт оболочки в Linux и выполните инструкцию Python
Статус -кво спроса: вам нужно написать сценарий, и некоторые вызовы сценария Python инкапсулируются в скрипте Пример Описание: Напишите скрипт оболочки на платформе Linux, а затем регулярно вызовите. .
Selenium2 испытательный фреймворк идея-03
Фактически, в процессе нашего тестирования мы обнаружим, что существует множество проблем с данными, которые необходимо решить. Например, верны ли данные, возвращаемые на странице? Данные полны? Нам в.
Командный режим
Определения Командный режим инкапсулирует запросы в объекты, чтобы можно было использовать разные запросы, очереди или журналы. Оцифровка других объектов. Командный режим также поддерживает отмену опе.
Одно -гликовая микрокомпьютер (STM32).
Одно -гликовая микрокомпьютер (STM32). Эта статья представляет собой запись опыта личного обучения, что удобно для будущего обзора, а также предоставляет удобство для других друзей. У меня ограниченна.
Как поменять UIViewController внутри модального окна?
Потому-что в нормальном варианте это должно выглядеть следующим образом:
[MainScreenVC]
Button1
—> present [LogInVC]
——> present [NavigationController]
———> push [UserFeedVC]
Button2
—> present [SignInVC]
——>present [NavigationController]
———>push [UserFeedVC]
- Вконтакте
В нормальном варианте:
— модальное окно закрывается, пересылая МэйнСкрину инфу о результате логина
— МэйнСкрин пушит/презентит то что надо
pushViewController не работает в XIB в Swift
Я использую xibs и swift, есть ли способ, которым я могу использовать pushViewController чтобы перейти к другому представлению и вернуться программно?
Ошибка: fatal error: unexpectedly found nil while unwrapping an Optional value
Вещи, которые я пробовал:
- Установка его в корневой вид не позволяет вернуться
И если я перейду с navigationController! to navigationController? Ничего не произошло
6 ответов
Свойство navigationController ( self.navigationController ) контроллера представления вернет действительный объект навигационного контроллера только в том случае, если контроллер вида находится в навигационном self.navigationController навигационного контроллера.
Вы можете попытаться встроить навигационный контроллер, как на этом рисунке:
presentViewController и отображение панели навигации
документы для ‘presentViewController: animated: completion:’ Примечание:
‘ на iPhone и iPod touch, представленный вид всегда полный экран.
На iPad, презентация зависит от значения в
свойство modalPresentationStyle.-
для ‘modalPresentationStyle’, The docs say:
стиль представления определяет, как модально представленный контроллер вида отображается на экране. На iPhone и iPod touch контроллеры modal view всегда представлены в полноэкранном режиме, но на iPad есть несколько различных вариантов презентации.
есть ли способ убедиться,что панель навигации отображается под строкой состояния после отображения элемента управления view? Должен ли я интерпретировать документ так, как вы этого не делаете получите любые варианты iPhone / iPod и только на iPad?
ранее я использовал ‘UIViewController:presentModalViewController:animated’ который работал нормально, но с iOS 5.0 API был устаревшим, поэтому я переключаюсь на новый.
визуально, что я хочу сделать, это иметь новый контроллер слайд в нижней части экрана, так же, как старый API, используемый для этого.
Swift как с модального экрана делать pushviewcontroller
Swift — Как использовать pushViewController в NSObject
У меня есть боковое меню, которое вызывается при нажатии leftBarButtonItem в панели наб.
И я закодировал слайд-меню с помощью NSObject, и я знаю, что NSObject не имеет метода pushViewController.
У меня есть меню в UITableView в NSObject, и я хочу нажать viewController.
Как я могу заставить это работать? Спасибо.
Ответы 1
Вы можете сделать @property из вашего parentVC в классе SlideMenuLauncher .
и тогда вы можете использовать это вместо self .
Вы можете опубликовать уведомление вместо отправки из класса SlideMenuLauncher и передать destinationVC как объект в уведомлении. Наблюдайте за этим уведомлением на вашем parentVC , затем извлеките destinationVC из объекта уведомления и нажмите на контроллер.
Вы можете заблокировать или делегировать событие didSelectRowAt .
Пример блока:
Вам нужно определить его обратный вызов в parentVC (вы можете определить его где угодно, сделайте это в viewDidLoad: ), и вам придется использовать экземпляр SideMenuLAuncher .
Композиция UIViewController-ов и навигация между ними (и не только)
В этой статье я хочу поделиться опытом который мы успешно используем уже несколько лет в наших iOS приложениях, 3 из которых в данный момент находятся в Appstore. Данный подход хорошо зарекомендовал себя и недавно мы сегрегировали его от остального кода и оформили в отдельную библиотеку RouteComposer о которой собственно и пойдет речь.
Но, для начала, давайте попробуем разобраться что подразумевается под композицией вью контроллеров в iOS.
Прежде чем переходить собственно к пояснениям, я напомню, что в iOS чаще всего подразумевается под вью контролером или UIViewController . Это класс унаследованный от стандартного UIViewController , который является базовым контроллером паттерна MVC, который Apple рекомендует использовать для разработки iOS приложений.
Можно использовать альтернативные архитектурные паттерны такие как MVVM, VIP, VIPER, но и в них UIViewController будет задействован так или иначе, а, значит, данная библиотека может использоваться вместе с ними. Cущность UIViewController используется для контроля UIView , которая чаще всего представляет собой экран или значительную часть экрана, обработки событий от него и отображения в нем неких данных.
Все UIViewController ы можно условно разделить на Обычные Вью Контроллеры, которые отвечают за некую видимую область на экране, и Контейнер Вью Контроллеры, которые, помимо отображения себя самих и некоторых своих элементов управления, способны также отображать дочерние вью контролеры интегрированные в них тем или иным способом.
Стандартными контейнер вью контроллерами поставляемыми с Cocoa Touch можно считать: UINavigationConroller , UITabBarController , UISplitController , UIPageController и некоторые другие. Также, пользователь может создавать свои кастомные контейнер вью контролеры следуя правилам Cocoa Touch описаным в документации Apple.
Процесс внедрения стандартных вью контролеров в контейнер вью контроллеры, а также интеграцию вью контролеров в стек вью контролеров мы будем называть композицией в этой статье.
Почему же стандартное решение для композиции вью контроллеров оказалось для нас не оптимальным и мы разработали библиотеку облегчающую наш труд.
Давайте рассмотрим для начала композицию некоторых стандартных контейнер вью контролеров для примера:
Примеры композиции в стандартных контейнерах
UINavigationController
UITabBarController
UISplitViewController
Примеры интеграции (композиции) вью котроллеров в стек
Установка вью контролера рутом
Модальная презентация вью контролера
Почему мы решили создать библиотеку для композиции
Как видно из примеров выше, нет единого способа интеграции обычных вью контролеров в контейнеры, как и нет единого способа построения стека вью контролеров. И, стоит вам захотеть слегка изменить лайаут вашего приложения или способ навигации в нем, как вам потребуются значительные изменения кода приложения, так же вам потребуются ссылки на объекты контейнеров, что бы вы могли вставить в них ваши вью контроллеры и т.д. То есть, сам стандартный способ подразумевает достаточно большой объем работы, а так же наличие ссылок на вью контролеры для порождения действий и презентации других контролеров.
Всему этому добавляют головной боли различные способы дип-линкинга в приложение (например с использованием Universal links), так как вам придется ответить на вопрос: а что если контролер которой нужно показать пользователю так как он кликнул на ссылку в сафари уже показан, или вью контроллер который должен его показать еще не создан, вынуждая вас ходить по дереву вью контролеров и писать код от которого иной раз начинают кровоточить глаза и который любой iOS девелопер старается спрятать. Кроме того, в отличие от Android архитектуры где каждый экран строится отдельно, в iOS чтобы показать какую то часть приложения сразу после запуска может потребоваться построить достаточно большой стек вью контроллеров который будут скрыты под тем который вы показываете по запросу.
Было бы здорово просто вызывать методы вроде goToAccount() , goToMenu() или goToProduct(withId: «012345») по нажатии пользователем на некоторую кнопку или по получении приложением универсальной ссылки из другого приложения и не задумываться о интеграции данного вью контроллера в стек, зная что создатель этого вью контроллера уже предоставил эту реализацию.
Кроме того, зачастую, наши приложения состоят из огромного количества экранов разрабатываемых разными командами, и, что бы добраться до одного из экранов в процессе разработки, нужно пройти через другой экран который возможно еще не создан. В нашей компании мы использовали подход который мы называем чашкой Петри. То есть в режиме разработки девелоперу и тестировщику доступен список всех экранов приложения и он может перейти к любому из них (разумеется к некоторым из них могут потребоваться некоторый входные параметры).
С ними можно взаимодействовать и тестировать индивидуально, а потом собрать в конечное приложение для продакшена. Такой подход сильно облегчает разработку, но, как вы видели из примеров выше, начинается ад композиции, когда нужно держать в коде несколько способов интеграции вью контролера в стек.
Остается добавить, что это все умножится на N как только ваша маркетинговая команда изъявит желание провести A/B тестирование на живых пользователях и проверить какой способ навигации работает лучше, например, таб бар или гамбургер меню?
- Давайте отрежем Сусанину ноги Давайте показывать 50% пользователей Таб Бар, а другим Гамбургер меню и через месяц мы вам скажем какие пользователи видят больше наших специальных предложений?
Я попробую рассказать вам как мы подошли к решению этой проблемы и в конце концов выделили его в библиотеку RouteComposer.
Сусанин Route Composer
Проанализировав все сценарии композиции и навигации мы попытались абстрагировать приведенный в примерах выше код и выделили 3 основных сущности из которых состоит и которыми оперирует библиотека RouteComposer — Factory , Finder , Action . Кроме того, в библиотеке присутствуют 3 вспомогательные сущности которые отвечают за небольшой тюнинг который может потребоваться в процессе навигации — RoutingInterceptor , ContextTask , PostRoutingTask . Все эти сущности должны быть сконфигурированы в цепь зависимостей и переданы Router у — объекту, который и будет строить ваш стек вью контролеров.
Но, о каждой из них по порядку:
Factory
Как и следует из названия Factory отвечает за создание вью контролера.
Здесь же важно оговориться о понятии контекста. Контекстом в рамках библиотеки мы называем все что может понадобиться вью контролеру для того что бы быть созданным. Например, для того что бы показать вью контроллер отображающий детали продукта — необходимо в него передать некий productID например в виде String . Сущностью контекста может быть все что угодно: объект, структура, блок или тупл(tuple). Если же вашему контроллеру ничего не нужно для того что бы быть созданным — контекст можно указать как Any? и устанавливать в nil .
Из реализации выше становится понятно, что данная фабрика загрузит образ вью контроллера из XIB файла и установит в него переданный productID. Помимо стандартного протокола Factory , библиотека предоставляет несколько стандартных реализаций этого протокола для того что бы избавить вас от написания банального кода (в частности приведенного в примере выше).
Далее я воздержусь от приведения описаний протоколов и примеров их реализаций, так как с ними можно подробно ознакомиться скачав пример, поставляемый вместе с библиотекой. Там приведены различные реализации фабрик для обычных вью контролеров и контейнеров, а так же способы их конфигурации.
Action
Сущность Action представляет описывает собой способ интеграции вью контролера, который будет построен фабрикой, в стек. Вью контроллер не может после создания просто повиснуть в воздухе и, поэтому, каждая фабрика должна содержать Action как видно из примера выше.
Самой банальной реализацией Action является модальная презентация контроллера:
Библиотека содержит реализацию большинства стандартных способов интеграции вью контролеров в стек и вам скорее всего не придется создавать свои самостоятельно до тех пор, пока вы не используете некий кастомный контейнер вью контроллер или способ презентации. Но создание кастомных Action не должно вызвать проблем если вы ознакомитесь с примерами.
Finder
Сущность Finder отвечает роутеру на вопрос — А создан ли уже такой вью контроллер и есть ли он уже в стеке? Возможно, ничего создавать не требуется и достаточно показать то что уже есть?.
Если вы храните ссылки на все созданные вами вью контроллеры — то в вашей реализации Finder вы можете просто возвращать ссылку на искомый вью контроллер. Но чаще всего это не так, ведь стек приложения, особенно особенно если оно большое, меняется довольно динамично. Кроме того, вы можете иметь несколько одинаковых вью контроллеров в стеке показывающих разные сущности (например несколько ProductViewController показывающие разные товары с разным productID), поэтому реализация Finder может потребовать кастомной имплементации и поиска соответствующего вью контролера в стеке. Библиотека облегчает эту задачу предоставляя StackIteratingFinder как расширение Finder — протокол с соответствующими настройками, позволяющий упростить эту задачу. В реализации StackIteratingFinder вам потребуется только ответить на вопрос — является ли данный вью контролер тем который роутер ищет по вашему запросу.
Пример такой реализации:
Вспомогательные сущности
RoutingInterceptor
RoutingInterceptor позволяет перед началом композиции вью контролеров выполнить некоторые действия и сообщить роутеру, можно ли интегрировать вью контроллеры в стек. Самым банальным примером такой задачи является аутентификация (но совсем не банальным в реализации). Например, вы хотите показать вью контроллер с деталями пользовательского аккаунта, но, для этого, пользователь должен быть залогинен в системе. Вы можете реализовать RoutingInterceptor и добавить его к конфигурации вью контроллера пользовательских деталей и внутри проверить: если пользователь залогинен — разрешить роутеру продолжить навигацию, если же нет — показать вью контроллер который предложит пользователю залогиниться и если данное действие пройдет успешно — разрешить роутеру продолжить навигацию или отменить ее, если пользователь откажется от входа в систему.
Реализация такого RoutingInterceptor с комментариями содержится в примере поставляемом с библиотекой.
ContextTask
Сущность ContextTask , если вы ее предоставите, может быть применена по отдельности к каждому вью контроллеру в конфигурации вне зависимости от того был ли он только что создан роутером или был найден в стеке, и, вы просто хотите обновить в нем данные и или установить некоторые дефолтные параметры (например показывать кнопку закрыть или не показывать).
PostRoutingTask
Реализация PostRoutingTask будет вызвана роутером после успешного завершения интеграции запрошенного вью контроллера в стек. В его реализации удобно добавлять различную аналитику или дергать различные сервисы.
Более подробно с реализацией всех описанных сущностей можно ознакомиться в документации к библиотеке а также в прилагаемом примере.
PS: Количество вспомогательных сущностей которое может быть добавлено в конфигурацию не ограничено.
Конфигурация
Все описанные сущности хороши тем что разбивают процесс композиции на маленькие, взаимозаменяемые и хорошо трестируемые блоки.
Теперь перейдем к самому главному — к конфигурации, то есть соединению этих блоков между собой. Для того что бы собрать данные блоки между собой и объединить в цепочку шагов, библиотека предоставляет билдер класс StepAssembly (для контейнеров — ContainerStepAssembly ). Его реализация позволяет нанизать блоки композиции в единый конфигурационный объект как бусины на ниточку, а также указать зависимости от конфигураций других вью контроллеров. Что делать с конфигурацией в дальнейшем — зависит от вас. Можете скормить ее роутеру с необходимыми параметрами и он построит для вас стек вью контроллеров, можете сохранить в словарь и использовать в последствии по ключу — зависит от вашей конкретной задачи.
Рассмотрим банальный пример: Допустим, по нажатии на ячейку в списке или получении приложением универсальной ссылки из сафари или почтового клиента, нам нужно показать модально вью контроллер продукта с неким productID. При этом вью контролер продукта должен быть построен внутри UINavigationController -а, что бы на его панели управления он мог показать свое название и кнопку закрыть. Кроме того, этот продукт можно показывать только пользователям которые вошли в систему, в противном случае предложить им войти в систему.
Если разобрать этот пример без использования библиотеки, то выглядеть он будет примерно вот так:
Данный пример не включает в себя реализацию универсальных ссылок, который потребует вычленения кода авторизации и сохранения контекста куда юзер должен быть направлен после, а также поиска, вдруг пользователь кликнул ссылку, а этот продукт ему уже показан, что, в конечном итоге, сделает код весьма тяжело читаемым.
Рассмотрим конфигурацию этого примера с использованием библиотеки:
Если перевести это на человеческий язык:
- Проверить что пользователь вошел в систему, и если нет предложить ему вход
- Если пользователь успешно вошел в систему, продолжить
- Искать продукт вью контроллер предоставленным Finder
- Если был найден — сделать видимым и закончить
- Если не был найден — создать UINavigationController , интегрировать в него вью контролер созданный ProductViewControllerFactory используя PushToNavigationAction
- Встроить полученый UINavigationController используя GenericActions.PresentModally от текущего вью контролера
Конфигурирование требует некоторого изучения как и многие комплексные решения, например концепция AutoLayout и, на первый взгляд, может показаться сложным и излишним. Однако, количество решаемых задач приведенным фрагментом кода охватывает все аспекты от авторизации до дип-линкига, а разбитие на последовательности действий дает возможность легко менять конфигурацию без необходимости внесения изменений в код. Кроме того, реализация StepAssembly поможет вам избежать проблем с незаконченой цепочкой шагов, а контроль типов — проблем с несовместимостью входных параметров у разных вью котроллеров.
Рассмотрим псевдокод полного приложения в котором в неком ProductArrayViewController выводится список продуктов и, если пользователь выбирает этот продукт, показывает его в зависимости от того залогинен пользователь или нет, или предлагает войти в систему и показывает после успешного входа:
Объекты конфигурации
Реализация списка продуктов
Реализация универсальных ссылок
Вот в сущности и все что требовалось для реализации всех условий из поставленного примера.
Следует также упомянуть что конфигурация может быть гораздо сложнее и состоять из зависимостей. Например, если вам нужно показывать продукт не просто от текущего контроллера, но, в случае если пользователь пришел в него по универсальной ссылке — то под ним должен оказаться обязательно ProductArrayViewController, который должен находиться обязательно внутри UINavigationController после условного HomeViewController — то это все может быть указано в конфигурации StepAssembly используя from() . Если ваше приложение охвачено RouteComposer полностью, сделать это не составит труда (Смотрите приложение в примере к библиотеке). Кроме того, вы можете создать несколько реализаций Configuration и передавать их в один и тот же вью контроллер для реализации разных вариантов композиции. Или выбирать один из них, если в вашем приложении проводится A/B тестирование, в зависимости к какой фокус группе относится ваш пользователь.
Вместо заключения
На данный момент, описаный выше подход используется в 3х приложениях в продакшене и хорошо зарекомендовал себя. Разбиение задачи композиции на маленькие, легко читаемые, взаимозаменяемые блоки облегчает понимание и поиск багов. Дефолтная реализация Fabric , Finder и Action позволяет для большинства задач сразу начать с конфигурации без необходимости создавать свои. А самое главное, что дает данный подход — возможность автономного создания вью контроллеров без необходимости внесения в их код знания о том, как они будут построены, и как пользователь будет двигаться в дальнейшем. Вью контроллер должен лишь по действию пользователя вызвать нужную конфигурацию, что может быть так же абстрагировано.
Библиотека, как и предоставляемая ей реализация роутера, не использует никаких трюков с objective c рантаймом и полностью следует всем концепциям Cocoa Touch, лишь помогая разбить процесс композиции на шаги и выполняет их в заданной последовательности. Библиотека протестирована с версиями iOS с 9 по 12.
Данный подход вписывается во все архитектурный паттерны которые подразумевают работу с UIViewController стеком (MVC, MVVM, VIP, RIB, VIPER и т.д.)
Библиотека находится в активной разработке и, тем не менее, как я уже писал выше, используется в продакшне. Я бы рекомендовал опробовать данный подход и поделиться впечатлениями. В нашем случае это позволило нам избавиться от большого количества головной боли.
Программно вернуться к предыдущему ViewController в Swift
Я отправляю пользователя на страницу одним нажатием кнопки. Эта страница является UITableViewController .
Теперь, если пользователь нажимает на ячейку, я бы хотел вернуть его на предыдущую страницу.
Я думал о чем-то вроде, self.performSegue(«back»). но это, кажется, плохая идея.
Как правильно это сделать?
Свифт 3:
Если вы хотите вернуться к предыдущему виду контроллера
Если вы хотите вернуться к корневому контроллеру представления
Свифт 3 , Свифт 4
navigationController является необязательным, поскольку его может не быть.
Свифт 3
Я мог бы опоздать с ответом, но для быстрого 3 вы можете сделать это следующим образом:
Swift 4
есть два способа вернуться / вернуться к предыдущему ViewController:
- Первый случай : если вы использовали: self.navigationController?.pushViewController(yourViewController, animated: true) в этом случае вам нужно использовать self.navigationController?.popViewController(animated: true)
- Второй случай : если вы использовали: self.present(yourViewController, animated: true, completion: nil) в этом случае вам нужно использовать self.dismiss(animated: true, completion: nil)
В первом случае убедитесь, что вы встроили свой ViewController в navigationController в вашей раскадровке
В случае, когда вы представили UIViewController изнутри то UIViewController есть ..
Просто вызовите dismiss функцию:
Свифт 5 и выше
вариант 1: использование с контроллером навигации
Случай 2: использование с настоящим контроллером представления
Если Segue является видом ‘Show’ или ‘Push’, то вы можете вызвать «popViewController (animated: Bool)» в экземпляре UINavigationController. Или, если segue является своего рода «настоящим», тогда вызовите «dismiss (animated: Bool, завершение: (() -> Void)?)» С экземпляром UIViewController
для Swift 3 вам просто нужно написать следующую строку кода
Попробуйте это: для предыдущего просмотра используйте это:
поп в корень используйте этот код:
Swift 4.0 Xcode 10.0 с TabViewController в качестве последнего представления
Если ваш последний ViewController встроен в TabViewController, приведенный ниже код отправит вас в корень .
Но если вы действительно хотите вернуться к последнему представлению (это может быть представление Tab1, Tab2 или Tab3 . ), вы должны написать следующий код:
Это работает для меня, я использовал представление после одного из моего TabView
Для вопросов, касающихся того, как встроить ваш viewController в navigationController в раскадровке:
- Откройте раскадровку, в которой расположены ваши разные viewController
- Нажмите на viewController, с которого вы хотите запустить свой контроллер навигации
- В верхней части Xcode нажмите «Редактор»
- -> Нажмите встраивать в
- -> Нажмите «Контроллер навигации
Этот работает для меня (Swift UI)
Я сделал это так
Я хотел бы предложить другой подход к этой проблеме. Вместо того, чтобы использовать контроллер навигации, чтобы открыть контроллер представления, используйте разматывать сегменты. Это решение имеет несколько, но действительно важных преимуществ:
- Контроллер источника может вернуться к любому другому контроллеру назначения (не только к предыдущему), ничего не зная о пункте назначения.
- Сегменты push и pop определены в раскадровке, поэтому в контроллерах представления нет кода навигации.
Вы можете найти более подробную информацию в разделе «Размотка сегментов» . Как лучше объяснить в предыдущей ссылке, в том числе, как отправить данные обратно, но здесь я сделаю краткое объяснение.
1) Перейдите к контроллеру представления пункта назначения (не источника) и добавьте раскрутку:
2) Перетащите CTRL от самого контроллера представления к значку выхода в исходном контроллере представления:
3) Выберите функцию размотки, которую вы только что создали несколько минут назад:
4) Выберите «раскрутить» и дайте ему имя:
5) Пойдите в любое место контроллера представления источника и вызовите sewind:
Я обнаружил, что такой подход приносит много пользы, когда ваша навигация начинает усложняться.
Swift как с модального экрана делать pushviewcontroller
Pushing, Popping, Presenting, & Dismissing ViewControllers
I recently found myself in a situation where I had presented a UINavigationController modally and then pushed UIViewControllers within the UINavigationController. On the last UIViewController, I had two scenarios that I wanted to handle: 1) navigate back to the first UIViewController within the UINavigationController’s stack and 2) dismiss the UINavigationController, including all the pushed UIViewControllers contained in the UINavigationController stack.
After some initial trial & error, I decided to spend some time understanding the different ways in which both UINavigationControllers and UIViewControllers handle navigation.
First lesson learned:
Any UIViewController (including UINavigationControllers as UINavigationControllers are a type of UIViewControllers) presented modally must be dismissed.
Second lesson learned:
Since UINavigationControllers hold UIViewControllers in their stack, they can present UIViewControllers both modally and via a push. When navigating away from any pushed UIViewControllers, UINavigationControllers must pop the UIViewController.
Third lesson learned:
Though it is possible to present UIViewControllers both modally and via a push, UIViewControllers can only present other UIViewControllers. Therefore, UIViewControllers can only be dismissed (unless they are inside a UINavigationController stack and the UINavigationController is handling the pop — see lesson #2). This is why it is not possible to call popViewController on a UIViewController.
Fourth lesson learned:
PresentingViewController is a property provided by Apple that is available on both UIViewControllers and UINavigationControllers. Calling presentingViewController.dismiss(animated:completion) will dismiss everything presented by the parentViewController. The parentViewController is the UIViewController that presented the current UIViewController. So, if you have a UINavigationController with 3 UIViewControllers within its stack, calling presentingViewController.dismiss(animated:completion) will dismiss both the UINavigationController and the 3 UIViewControllers held within its stack.
Fifth lesson learned:
Similarly, Apple also provides another property on UIViewControllers and UINavigationControllers — presentedViewController. Calling presentedViewController.dismiss(animated:completion) will dismiss the childViewController. The childViewController is the current UIViewController that is being presented.
Prior to this recent investigation, I always thought that navigation was relatively basic. However, when faced with a combination of pushed & presented UIViewControllers, I realized how important it is to fully understand the different navigation patterns.
Swift как с модального экрана делать pushviewcontroller
Pushing, Popping, Presenting, & Dismissing ViewControllers
I recently found myself in a situation where I had presented a UINavigationController modally and then pushed UIViewControllers within the UINavigationController. On the last UIViewController, I had two scenarios that I wanted to handle: 1) navigate back to the first UIViewController within the UINavigationController’s stack and 2) dismiss the UINavigationController, including all the pushed UIViewControllers contained in the UINavigationController stack.
After some initial trial & error, I decided to spend some time understanding the different ways in which both UINavigationControllers and UIViewControllers handle navigation.
First lesson learned:
Any UIViewController (including UINavigationControllers as UINavigationControllers are a type of UIViewControllers) presented modally must be dismissed.
Second lesson learned:
Since UINavigationControllers hold UIViewControllers in their stack, they can present UIViewControllers both modally and via a push. When navigating away from any pushed UIViewControllers, UINavigationControllers must pop the UIViewController.
Third lesson learned:
Though it is possible to present UIViewControllers both modally and via a push, UIViewControllers can only present other UIViewControllers. Therefore, UIViewControllers can only be dismissed (unless they are inside a UINavigationController stack and the UINavigationController is handling the pop — see lesson #2). This is why it is not possible to call popViewController on a UIViewController.
Fourth lesson learned:
PresentingViewController is a property provided by Apple that is available on both UIViewControllers and UINavigationControllers. Calling presentingViewController.dismiss(animated:completion) will dismiss everything presented by the parentViewController. The parentViewController is the UIViewController that presented the current UIViewController. So, if you have a UINavigationController with 3 UIViewControllers within its stack, calling presentingViewController.dismiss(animated:completion) will dismiss both the UINavigationController and the 3 UIViewControllers held within its stack.
Fifth lesson learned:
Similarly, Apple also provides another property on UIViewControllers and UINavigationControllers — presentedViewController. Calling presentedViewController.dismiss(animated:completion) will dismiss the childViewController. The childViewController is the current UIViewController that is being presented.
Prior to this recent investigation, I always thought that navigation was relatively basic. However, when faced with a combination of pushed & presented UIViewControllers, I realized how important it is to fully understand the different navigation patterns.
Swift как с модального экрана делать pushviewcontroller
За последнюю неделю я ломаю себе голову над тем, как решить проблему с отображением и отключением нескольких контроллеров представления. Я создал образец проекта и вставил код прямо из проекта. У меня есть 3 контроллера просмотра с соответствующими файлами .xib. MainViewController, VC1 и VC2. У меня есть две кнопки на главном контроллере вида.
Это открывает VC1 без проблем. В VC1 у меня есть еще одна кнопка, которая должна открывать VC2 и одновременно закрывать VC1.
Я хочу, чтобы он вернулся к контроллеру основного представления, в то время как VC1 должен был быть навсегда удален из памяти. VC1 должен отображаться только тогда, когда я нажимаю кнопку VC1 на главном контроллере.
Другая кнопка на контроллере главного представления также должна иметь возможность отображать VC2 напрямую, минуя VC1, и должна возвращаться на главный контроллер при нажатии кнопки на VC2. Нет длительного кода, циклов или таймеров. Просто вызовы костей для просмотра контроллеров.
Ответы
не отправляет сообщение самому себе, он фактически отправляет сообщение своему представляющему VC, прося его выполнить отклонение. Когда вы представляете VC, вы создаете отношения между представляющим VC и представленным. Таким образом, вы не должны уничтожать представляющий VC во время его представления (представленный VC не может отправить это сообщение о закрытии…). Поскольку вы на самом деле не учитываете это, вы выходите из приложения в запутанном состоянии. См. Мой ответ « Отклонение представленного контроллера представления», в котором я рекомендую этот метод, написан более четко:
В вашем случае вам необходимо убедиться, что все управление выполняется в mainVC . Вы должны использовать делегата для отправки правильного сообщения обратно в MainViewController из ViewController1, чтобы mainVC мог отклонить VC1, а затем представить VC2.
В VC2 VC1 добавьте протокол в файл .h над @interface:
и ниже в том же файле в разделе @interface объявите свойство для хранения указателя делегата:
В файле VC1 .m метод кнопки отклонения должен вызывать метод делегата
Теперь в mainVC установите его как делегата VC1 при создании VC1:
и реализуем метод делегата:
present2: может быть тем же методом, что и ваш метод IBAction VC2Pressed: button. Обратите внимание, что он вызывается из блока завершения, чтобы гарантировать, что VC2 не будет представлен, пока VC1 не будет полностью отклонен.
Теперь вы переходите от VC1-> VCMain-> VC2, поэтому вы, вероятно, захотите, чтобы был анимирован только один из переходов.
Обновить
В своих комментариях вы выражаете удивление по поводу сложности, необходимой для достижения, казалось бы, простой вещи. Уверяю вас, этот шаблон делегирования настолько важен для большей части Objective-C и Какао, и этот пример — самый простой из возможных, и вам действительно стоит приложить усилия, чтобы освоиться с ним.
В Руководстве по программированию контроллера View от Apple говорится следующее :
Отклонение представленного контроллера представления
Когда приходит время отклонить представленный контроллер представления, предпочтительный подход состоит в том, чтобы позволить контроллеру представления представления отклонить его. Другими словами, всякий раз, когда это возможно, тот же контроллер представления, который представил контроллер представления, также должен нести ответственность за его отклонение. Хотя существует несколько методов для уведомления контроллера представления представления о том, что его представленный контроллер представления должен быть отклонен, предпочтительным методом является делегирование. Для получения дополнительной информации см. «Использование делегирования для связи с другими контроллерами».
Если вы действительно продумаете, чего хотите достичь и как вы это делаете, вы поймете, что обмен сообщениями с вашим MainViewController для выполнения всей работы является единственным логическим выходом, учитывая, что вы не хотите использовать NavigationController. Если вы действительно используете NavController, вы фактически «делегируете», даже если не явно, navController для выполнения всей работы. Должен быть какой-то объект, который будет отслеживать все, что происходит с вашей навигацией по VC, и вам нужен какой-то способ связи с ним, что бы вы ни делали.
На практике совет Apple немного экстремален . в обычных случаях вам не нужно создавать выделенный делегат и метод, вы можете положиться на [self presentingViewController] dismissViewControllerAnimated: — это когда в таких случаях, как ваш, вы хотите, чтобы вы уволили чтобы иметь другие эффекты на удаленные объекты, о которых вам нужно позаботиться.
Вот что вы можете себе представить, работая без хлопот с делегатами .
После того, как представляющий контроллер попросил нас уволить, у нас есть блок завершения, который вызывает метод в PresentingViewController для вызова VC2. Делегат не требуется. (Большой плюс блоков в том, что они уменьшают потребность в делегатах в этих обстоятельствах). Однако в этом случае есть несколько вещей, которые мешают .
- в VC1 вы не знаете, что mainVC реализует метод present2 — вы можете столкнуться с трудными для отладки ошибками или сбоями. Делегаты помогут вам избежать этого.
- после того, как VC1 отклонен, на самом деле не нужно выполнять блок завершения . или нет? Означает ли self.presentingViewController что-нибудь еще? Вы не знаете (я тоже) . с делегатом у вас нет этой неопределенности.
- Когда я пытаюсь запустить этот метод, он просто зависает без предупреждений или ошибок.
Так что, пожалуйста . найдите время, чтобы изучить делегирование!
update2
В своем комментарии вам удалось заставить его работать, используя это в обработчике кнопки увольнения VC2:
Это, конечно, намного проще, но при этом возникает ряд проблем.
Тесная связь
Вы жестко связываете свою структуру viewController вместе. Например, если вы вставите новый viewController перед mainVC, ваше требуемое поведение будет нарушено (вы перейдете к предыдущему). В VC1 вам также нужно было #import VC2. Следовательно, у вас довольно много взаимозависимостей, что нарушает цели ООП / MVC.
При использовании делегатов ни VC1, ни VC2 не нужно ничего знать о mainVC или его предшественниках, поэтому мы сохраняем все слабо связанное и модульное.
объем памяти
VC1 никуда не делся, у вас все еще есть два указателя на него:
- presentedViewController свойство mainVC
- Свойство presentingViewController VC2
Вы можете проверить это, зарегистрировавшись, а также просто сделав это из VC2.
Он по-прежнему работает, по-прежнему возвращает вас к VC1.
Мне это кажется утечкой памяти.
Ключ к разгадке — в предупреждении, которое вы здесь получаете:
Логика нарушается, поскольку вы пытаетесь отклонить представляющий VC, для которого VC2 является представленным VC. Второе сообщение на самом деле не выполняется — возможно, что-то происходит, но у вас все еще остаются два указателя на объект, от которого, как вы думали, вы избавились. ( править — я проверил это, и это не так уж плохо, оба объекта исчезнут, когда вы вернетесь в mainVC )
Это довольно длинный способ сказать — пожалуйста, используйте делегатов. Если это поможет, я сделал еще одно краткое описание паттерна здесь:
Всегда ли передача контроллера в конструктор — плохая практика?
обновление 3
Если вы действительно хотите избегать делегатов, это может быть лучшим выходом:
Но ничего не сбрасывайте со счетов . как мы выяснили, на самом деле этого не происходит.
Как мы (знаем), мы не отклонили VC1, мы можем вернуться через VC1 к MainVC. MainVC отклоняет VC1. Поскольку VC1 ушел, предполагается, что VC2 идет с ним, так что вы вернулись на MainVC в чистом состоянии.
Он по-прежнему сильно связан, поскольку VC1 должен знать о VC2, а VC2 должен знать, что он был доставлен через MainVC-> VC1, но это лучшее, что вы получите без небольшого явного делегирования.
Push ViewController с модальной анимацией (горизонтальный флип)
Мне нужно нажать контроллер вида на другой контроллер представления.
переход от menuVC к VC1 не требует анимации, но переход от VC1 к VC2 и от VC2 к VC1 требует возникновения флип-анимации.
Однако при переходе с VC2 на menuVC анимация не требуется.
Я использую следующий код:
Экран полностью исчезает, когда я пытаюсь сделать это.
Теперь вы должны использовать анимацию на основе блоков. Кроме того, если вы создаете контролер раскадровки из контроллера, который также находится в одном и том же раскадровке, вы можете более легко получить доступ к этой раскадровке с помощью self.storyboard.
Однако это также создало пустой экран.
Вместо этого, если вы используете раскадровки, лучше всего создать экземпляр через раскадровку:
yourViewControllerID устанавливается в раскадровке под инспектором идентификации для класса yourviewcontroller.
Как поменять UIViewController внутри модального окна?
Потому-что в нормальном варианте это должно выглядеть следующим образом:
[MainScreenVC]
Button1
—> present [LogInVC]
——> present [NavigationController]
———> push [UserFeedVC]
Button2
—> present [SignInVC]
——>present [NavigationController]
———>push [UserFeedVC]
- Вконтакте
В нормальном варианте:
— модальное окно закрывается, пересылая МэйнСкрину инфу о результате логина
— МэйнСкрин пушит/презентит то что надо
Как поменять UIViewController внутри модального окна?
Потому-что в нормальном варианте это должно выглядеть следующим образом:
[MainScreenVC]
Button1
—> present [LogInVC]
——> present [NavigationController]
———> push [UserFeedVC]
Button2
—> present [SignInVC]
——>present [NavigationController]
———>push [UserFeedVC]
- Вконтакте
В нормальном варианте:
— модальное окно закрывается, пересылая МэйнСкрину инфу о результате логина
— МэйнСкрин пушит/презентит то что надо
iOS 5 Попытка pushViewController из модального представления
У меня есть приложение с вкладками iOS 5, использующее раскадровки.
Мой контроллер панели вкладок указывает на три контроллера навигации.
С одной из них поток выглядит так:
Начальный вид —> Просмотр фотографий (модальный) —> Просмотр каталога
На экране фото у меня есть кнопка со следующим кодом:
Я пробовал дурачиться с presentingViewController , parentViewController — даже тип привёл их к UINavigationController . Это приводит к сбою со следующим сообщением об ошибке:
Так что это говорит мне, что я не получил UINavigationController , но UITabBarController .
Есть ли способ обойти это?
2 ответы
Переход в стиле «push» может быть выполнен только из контроллера представления, которым управляет UINavigationController . Если вы попытаетесь это сделать, иначе ничего не произойдет.
Вместо того, чтобы отображать представление Photo модально, как вы описываете в своем вопросе, вы должны отобразить экземпляр UINavigationController в качестве модального представления и сделать представление Photo View контроллером корневого представления представления навигации. (Все это можно настроить с помощью раскадровки). Тогда ваш push segue будет работать.
Если вы не хотите, чтобы верхняя панель навигации появлялась на вашем первом контроллере представления (просмотр фотографий), вы можете использовать:
Это скроет верхнюю панель навигации. После того, как вы нажмете новый контроллер представления, если вы хотите, чтобы панель навигации снова появлялась на этом и любых последующих контроллерах представления, вам нужно будет установить для setNavigationBarHidden значение NO на новом контроллере представления.
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
Exploring the differences between presentViewController and pushViewController with new iOS 13 modal presentation styles.
russell-archer/ModalStylesDemo
Name already in use
- Local
- Codespaces
Use Git or checkout with SVN using the web URL.
Work fast with our official CLI. Learn more about the CLI.
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
presentViewController vs pushViewController
Exploring the differences between presentViewController and pushViewController with new iOS 13 modal presentation styles.
With presentViewController the new view controller is presented modally, “on top” of the existing view controller. With pushViewController the new view controller is pushed onto the existing navigation stack.
In iOS 13 there is a new style of presentation for modal view controllers. Rather than always being presented fullscreen, by default, the new view controller is displayed on top of the existing view controller with the existing view controller being partially visible “underneath”. The user can then close/dismiss the new view controller by dragging down or tapping off it.
The following summarizes the situation:
- The new view controller is presented MODALLY
- The new view controller is NOT added to the existing navigation stack and is not contained by your nav controller
- You DO NOT get a navigation bar and back button
- modalPresentationStyle == .automatic
- Presents the new view controller on top of the current view controller
- The top of current view controller can be seen “underneath” the new view controller
- The user can dismiss the new view controller by dragging down
- As it’s not part of the navigation stack, there is no navigation bar
- Presents the new view controller on top of the current view controller
- The current view controller CANNOT be seen underneath the new view controller
- There is no way for the user dismiss the new view controller
- As it’s not part of the navigation stack, there is no navigation bar (the user is «stuck»)
- Pushes the new view controller onto the EXISTING navigation stack
- The new view controller is NOT presented modally
- The new view controller is always presented full screen (it’s indepedent of modalPresentationStyle)
- You automatically get a navigation bar and back button
The demo shows the main principles involved:
Here we have used presentViewController with modalPresentationStyle == .automatic:
Here we use presentViewController with modalPresentationStyle == .fullscreen. We can see that without (manually) adding a Done button there would be no way for the user to dismiss the new view controller:
Note that you can also control the style of modal presentation when using segues on a storyboard:
About
Exploring the differences between presentViewController and pushViewController with new iOS 13 modal presentation styles.
Swift как с модального экрана делать pushviewcontroller
Решение 1. Сначала закройте модальное окно, получите соответствующий контроллер навигации, а затем нажмите новый контроллер.
Решение 2. В модальном окне перейдите в модальное окно, чтобы появился контроллер навигации.
Схема 3. Пуш на модальном
Интеллектуальная рекомендация
Poj2796 чувствую себя хорошим одиноким стеком
http://poj.org/problem?id=2796 Значение: требует поиска диапазона значения, интервальное значение, определенное как минимум интервала интервала и умножения. Практика: непосредственно нашел интервалы с.
Начало работы с spring-mvc (1): примеры начала работы
введение 1.MVC :Model-View-Control РамообразнойC Основная работа, которую необходимо выполнить на уровне: инкапсуляцияweb Запрос является объектом данных, вызывает уровень бизнес-логики для обработки .
От Дао к Джейн — Душа архитектуры RISC-V (Часть 2)
Эта статья входит в серию статей «Проектирование ЦП RISC-V» и «Разработка встроенного программного обеспечения RISC-V». Примечание. Эта статья представляет собой отрывок из пер.
последовательность очереди
При написании кода вам необходимо добавить заголовочный файл «очередь», за которым следует #include «алгоритм». с использованием пространства имен std; также есть q, pop () при.
N Вопрос королевы (рекурсивный + обратно) Реализация C ++
N Вопросы королевы (рекурсивный + назад N Queens, выпущенные технологией функции имитации C ++: Решить класс проблем: Основная функция: результат Результаты здесь опущены, и существует 92 консенсус бе.
Вам также может понравиться
Bluetooth 4.0 BLE Программирование Вопросы, связанные с вопросами решения (воспроизводится)
Q: Что такое связь Bluetooth? A: Оригинальный дизайн связи Bluetooth заключается в том, чтобы облегчить низкую стоимость между мобильными телефонами (мобильными телефонами) и аксессуарами, беспроводны.
Напишите скрипт оболочки в Linux и выполните инструкцию Python
Статус -кво спроса: вам нужно написать сценарий, и некоторые вызовы сценария Python инкапсулируются в скрипте Пример Описание: Напишите скрипт оболочки на платформе Linux, а затем регулярно вызовите. .
Selenium2 испытательный фреймворк идея-03
Фактически, в процессе нашего тестирования мы обнаружим, что существует множество проблем с данными, которые необходимо решить. Например, верны ли данные, возвращаемые на странице? Данные полны? Нам в.
Командный режим
Определения Командный режим инкапсулирует запросы в объекты, чтобы можно было использовать разные запросы, очереди или журналы. Оцифровка других объектов. Командный режим также поддерживает отмену опе.
Одно -гликовая микрокомпьютер (STM32).
Одно -гликовая микрокомпьютер (STM32). Эта статья представляет собой запись опыта личного обучения, что удобно для будущего обзора, а также предоставляет удобство для других друзей. У меня ограниченна.
Как поменять UIViewController внутри модального окна?
Потому-что в нормальном варианте это должно выглядеть следующим образом:
[MainScreenVC]
Button1
—> present [LogInVC]
——> present [NavigationController]
———> push [UserFeedVC]
Button2
—> present [SignInVC]
——>present [NavigationController]
———>push [UserFeedVC]- Вконтакте
В нормальном варианте:
— модальное окно закрывается, пересылая МэйнСкрину инфу о результате логина
— МэйнСкрин пушит/презентит то что надоpushViewController не работает в XIB в Swift
Я использую xibs и swift, есть ли способ, которым я могу использовать pushViewController чтобы перейти к другому представлению и вернуться программно?
Ошибка: fatal error: unexpectedly found nil while unwrapping an Optional value
Вещи, которые я пробовал:
- Установка его в корневой вид не позволяет вернуться
И если я перейду с navigationController! to navigationController? Ничего не произошло
6 ответов
Свойство navigationController ( self.navigationController ) контроллера представления вернет действительный объект навигационного контроллера только в том случае, если контроллер вида находится в навигационном self.navigationController навигационного контроллера.
Вы можете попытаться встроить навигационный контроллер, как на этом рисунке:
presentViewController и отображение панели навигации
документы для ‘presentViewController: animated: completion:’ Примечание:
‘ на iPhone и iPod touch, представленный вид всегда полный экран.
На iPad, презентация зависит от значения в
свойство modalPresentationStyle.-для ‘modalPresentationStyle’, The docs say:
стиль представления определяет, как модально представленный контроллер вида отображается на экране. На iPhone и iPod touch контроллеры modal view всегда представлены в полноэкранном режиме, но на iPad есть несколько различных вариантов презентации.
есть ли способ убедиться,что панель навигации отображается под строкой состояния после отображения элемента управления view? Должен ли я интерпретировать документ так, как вы этого не делаете получите любые варианты iPhone / iPod и только на iPad?
ранее я использовал ‘UIViewController:presentModalViewController:animated’ который работал нормально, но с iOS 5.0 API был устаревшим, поэтому я переключаюсь на новый.
визуально, что я хочу сделать, это иметь новый контроллер слайд в нижней части экрана, так же, как старый API, используемый для этого.
Swift как с модального экрана делать pushviewcontroller
Swift как с модального экрана делать pushviewcontroller
Today I pondered about a problem which I had overlooked in past. How to add a completion handler block for when I pop UIViewController?
In modal transition, dismissViewControllerAnimated, apple offers an option to call a completion block when dismissal of modal is finished. This is quite handy for various situations where you need to perform certain task like signalling a delegate about something when controller is removed from top of navigation or window.
Something similar isn’t offered directly in api for pop and push transitions. We do have been provided with viewDidAppear like methods that may be used to get things certain way. Flexibility and easiness that comes from completion handler of transition is unbeaten.
What we don’t have available from api can be solved by using core animation’s transactions. We group multiple animation related changes together and ensure all changes are run at the same time.
This is fine but how to notify when animation changes are finished?
CATransaction enables to create completion block which no matter the numbers of animation change is running or various combination of animation timings, completion block will be called when all animation changes has finishing performing.
Let’s create an extension to UINavigationController and implement the method that takes the closure to perform our completion handler which gets called when our transition is finished within CATransaction queue.
Now we use below to pop and push our UIViewController and have completion handler:
[Code answers]-Using pushViewController after presentModalViewController
If you presentModelViewController then you need to dismiss it before you can call the navigation controller's methods, otherwise you have to put this view controller into the navigation stack in order to put another view controller on top of it.
Read More
If you use that in conjunction with [self.navigationController pushViewController:childController animated:NO]; to disable the native animation, it may produce the effect you're looking for.
Don't forget to reverse the operation when popping childController off the nav stack.
Using the following method, you first present the childViewController modally with animated:YES, then dismiss it without any animation and then push it on the view controller without animation. You will need to create your own navigation bar for this view and will need to hide the navigation bar of the navigation controller.
In the childController when cancel button clicked:
and in the delegate:
Use the following lines of code to present childController, then navigationcontroller will not be null so it will work as u want.
After presentModelViewController you can present or push any other view controller within presented view controller.
Как программно переключиться на другой контроллер вида в Swift 4?
Мне нужно переключить страницу (другой контроллер представления) с помощью кнопки. У меня есть два контроллера (viewController to HomeViewController) У меня есть кнопка, созданная в viewController:
и я установил функцию и использовал инструкцию печати для проверки функции:
Я выполнил программу, и когда я нажимаю кнопку, она выводит «нажатие кнопки»,
Затем я добавил в функцию следующее:
В результате он не переключается на другой viewController (HomeViewController).
Любая идея о том, как мне это сделать? Спасибо
4 ответа
Переключиться на другой viewController программно в Swift 4 —
Процесс навигации
во-первых, вам необходимо встроить свой вид с помощью навигационного контроллера, например —
Для навигации программно вы можете использовать код ниже —
- Но этот код работает, если вы работаете со StoryBoard в своем проекте. Во-первых, вам нужно установить идентификатор вида в storyBoard
Push with StoryBoard
Present with StoryBoard
Push with XIB
Present with XIB
Чтобы избежать каких-либо сбоев, вы также можете попробовать этот код —
Существует несколько способов переключения на другой ViewController.
Если вы создали контроллеры в раскадровке, вам нужно сначала получить экземпляр раскадровки в случае нескольких раскадровки.
В случае множественного раскадровки вам нужно указать название раскадровки.
Затем получите экземпляр контроллера вида, который вы хотите переключить.
* Убедитесь, что вы установили правильный идентификатор в ViewController.
если вы хотите представить контроллер вида:
если вы хотите нажать контроллер вида:
если вы хотите переключиться на другой контроллер, который вы создали как Xib
Если вы хотите нажать:
Представьте контроллер:
Другие способы переключения между контроллерами.
Проводка Segues
Ctrl + Перетащите из кнопки «View Controller», где-нибудь во втором контроллере просмотра (HomeViewController). Он может находиться где угодно в главном окне второго контроллера. Когда вы отпустите, он покажет вам поле, подобное приведенному ниже.
в этом вам не нужен какой-либо код для переключения, он включается одним нажатием кнопки.
или вы можете CTLR + перетащить из контроллера View на другой контроллер, чтобы создать segue и написать ниже код при нажатии кнопки и переключиться на другой контроллер представления.
performSegue (withIdentifier: «mySegueID», отправитель: ноль)
убедитесь, что вы установили правильный идентификатор segue.
Подробная информация о разных сегментах
Показать. Когда контроллеры View находятся в UINavigationController, это вызывает следующий контроллер View в стек навигации. Это позволяет пользователю нажать кнопку «Назад», чтобы вернуться к предыдущему экрану с помощью кнопки «Назад» в левом верхнем углу панели навигации.
Настоящий modally — это представляет собой следующий контроллер представления в модальном режиме над текущим View Controller. Этот не обязательно должен быть частью UINavigationController или UISplitViewController. Он просто показывает конечный контроллер просмотра перед предыдущим. Обычно это используется, когда пользователь должен либо закончить, либо отменить.
Custom — Точно, как это звучит. Вы можете создать свой собственный стиль и переходы segue и использовать его здесь.
Name already in use
Work fast with our official CLI. Learn more about the CLI.
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
presentViewController vs pushViewController
Exploring the differences between presentViewController and pushViewController with new iOS 13 modal presentation styles.
With presentViewController the new view controller is presented modally, “on top” of the existing view controller. With pushViewController the new view controller is pushed onto the existing navigation stack.
In iOS 13 there is a new style of presentation for modal view controllers. Rather than always being presented fullscreen, by default, the new view controller is displayed on top of the existing view controller with the existing view controller being partially visible “underneath”. The user can then close/dismiss the new view controller by dragging down or tapping off it.
The following summarizes the situation:
- The new view controller is presented MODALLY
- The new view controller is NOT added to the existing navigation stack and is not contained by your nav controller
- You DO NOT get a navigation bar and back button
- modalPresentationStyle == .automatic
- Presents the new view controller on top of the current view controller
- The top of current view controller can be seen “underneath” the new view controller
- The user can dismiss the new view controller by dragging down
- As it’s not part of the navigation stack, there is no navigation bar
- Presents the new view controller on top of the current view controller
- The current view controller CANNOT be seen underneath the new view controller
- There is no way for the user dismiss the new view controller
- As it’s not part of the navigation stack, there is no navigation bar (the user is «stuck»)
- Pushes the new view controller onto the EXISTING navigation stack
- The new view controller is NOT presented modally
- The new view controller is always presented full screen (it’s indepedent of modalPresentationStyle)
- You automatically get a navigation bar and back button
The demo shows the main principles involved:
Here we have used presentViewController with modalPresentationStyle == .automatic:
Here we use presentViewController with modalPresentationStyle == .fullscreen. We can see that without (manually) adding a Done button there would be no way for the user to dismiss the new view controller:
Note that you can also control the style of modal presentation when using segues on a storyboard:
About
Exploring the differences between presentViewController and pushViewController with new iOS 13 modal presentation styles.
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
Exploring the differences between presentViewController and pushViewController with new iOS 13 modal presentation styles.
russell-archer/ModalStylesDemo
Name already in use
- Local
- Codespaces
Use Git or checkout with SVN using the web URL.
Work fast with our official CLI. Learn more about the CLI.
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
presentViewController vs pushViewController
Exploring the differences between presentViewController and pushViewController with new iOS 13 modal presentation styles.
With presentViewController the new view controller is presented modally, “on top” of the existing view controller. With pushViewController the new view controller is pushed onto the existing navigation stack.
In iOS 13 there is a new style of presentation for modal view controllers. Rather than always being presented fullscreen, by default, the new view controller is displayed on top of the existing view controller with the existing view controller being partially visible “underneath”. The user can then close/dismiss the new view controller by dragging down or tapping off it.
The following summarizes the situation:
- The new view controller is presented MODALLY
- The new view controller is NOT added to the existing navigation stack and is not contained by your nav controller
- You DO NOT get a navigation bar and back button
- modalPresentationStyle == .automatic
- Presents the new view controller on top of the current view controller
- The top of current view controller can be seen “underneath” the new view controller
- The user can dismiss the new view controller by dragging down
- As it’s not part of the navigation stack, there is no navigation bar
- Presents the new view controller on top of the current view controller
- The current view controller CANNOT be seen underneath the new view controller
- There is no way for the user dismiss the new view controller
- As it’s not part of the navigation stack, there is no navigation bar (the user is «stuck»)
- Pushes the new view controller onto the EXISTING navigation stack
- The new view controller is NOT presented modally
- The new view controller is always presented full screen (it’s indepedent of modalPresentationStyle)
- You automatically get a navigation bar and back button
The demo shows the main principles involved:
Here we have used presentViewController with modalPresentationStyle == .automatic:
Here we use presentViewController with modalPresentationStyle == .fullscreen. We can see that without (manually) adding a Done button there would be no way for the user to dismiss the new view controller:
Note that you can also control the style of modal presentation when using segues on a storyboard:
About
Exploring the differences between presentViewController and pushViewController with new iOS 13 modal presentation styles.
Swift как с модального экрана делать pushviewcontroller
Pushing, Popping, Presenting, & Dismissing ViewControllers
I recently found myself in a situation where I had presented a UINavigationController modally and then pushed UIViewControllers within the UINavigationController. On the last UIViewController, I had two scenarios that I wanted to handle: 1) navigate back to the first UIViewController within the UINavigationController’s stack and 2) dismiss the UINavigationController, including all the pushed UIViewControllers contained in the UINavigationController stack.
After some initial trial & error, I decided to spend some time understanding the different ways in which both UINavigationControllers and UIViewControllers handle navigation.
First lesson learned:
Any UIViewController (including UINavigationControllers as UINavigationControllers are a type of UIViewControllers) presented modally must be dismissed.
Second lesson learned:
Since UINavigationControllers hold UIViewControllers in their stack, they can present UIViewControllers both modally and via a push. When navigating away from any pushed UIViewControllers, UINavigationControllers must pop the UIViewController.
Third lesson learned:
Though it is possible to present UIViewControllers both modally and via a push, UIViewControllers can only present other UIViewControllers. Therefore, UIViewControllers can only be dismissed (unless they are inside a UINavigationController stack and the UINavigationController is handling the pop — see lesson #2). This is why it is not possible to call popViewController on a UIViewController.
Fourth lesson learned:
PresentingViewController is a property provided by Apple that is available on both UIViewControllers and UINavigationControllers. Calling presentingViewController.dismiss(animated:completion) will dismiss everything presented by the parentViewController. The parentViewController is the UIViewController that presented the current UIViewController. So, if you have a UINavigationController with 3 UIViewControllers within its stack, calling presentingViewController.dismiss(animated:completion) will dismiss both the UINavigationController and the 3 UIViewControllers held within its stack.
Fifth lesson learned:
Similarly, Apple also provides another property on UIViewControllers and UINavigationControllers — presentedViewController. Calling presentedViewController.dismiss(animated:completion) will dismiss the childViewController. The childViewController is the current UIViewController that is being presented.
Prior to this recent investigation, I always thought that navigation was relatively basic. However, when faced with a combination of pushed & presented UIViewControllers, I realized how important it is to fully understand the different navigation patterns.
Swift как с модального экрана делать pushviewcontroller
Pushing, Popping, Presenting, & Dismissing ViewControllers
I recently found myself in a situation where I had presented a UINavigationController modally and then pushed UIViewControllers within the UINavigationController. On the last UIViewController, I had two scenarios that I wanted to handle: 1) navigate back to the first UIViewController within the UINavigationController’s stack and 2) dismiss the UINavigationController, including all the pushed UIViewControllers contained in the UINavigationController stack.
After some initial trial & error, I decided to spend some time understanding the different ways in which both UINavigationControllers and UIViewControllers handle navigation.
First lesson learned:
Any UIViewController (including UINavigationControllers as UINavigationControllers are a type of UIViewControllers) presented modally must be dismissed.
Second lesson learned:
Since UINavigationControllers hold UIViewControllers in their stack, they can present UIViewControllers both modally and via a push. When navigating away from any pushed UIViewControllers, UINavigationControllers must pop the UIViewController.
Third lesson learned:
Though it is possible to present UIViewControllers both modally and via a push, UIViewControllers can only present other UIViewControllers. Therefore, UIViewControllers can only be dismissed (unless they are inside a UINavigationController stack and the UINavigationController is handling the pop — see lesson #2). This is why it is not possible to call popViewController on a UIViewController.
Fourth lesson learned:
PresentingViewController is a property provided by Apple that is available on both UIViewControllers and UINavigationControllers. Calling presentingViewController.dismiss(animated:completion) will dismiss everything presented by the parentViewController. The parentViewController is the UIViewController that presented the current UIViewController. So, if you have a UINavigationController with 3 UIViewControllers within its stack, calling presentingViewController.dismiss(animated:completion) will dismiss both the UINavigationController and the 3 UIViewControllers held within its stack.
Fifth lesson learned:
Similarly, Apple also provides another property on UIViewControllers and UINavigationControllers — presentedViewController. Calling presentedViewController.dismiss(animated:completion) will dismiss the childViewController. The childViewController is the current UIViewController that is being presented.
Prior to this recent investigation, I always thought that navigation was relatively basic. However, when faced with a combination of pushed & presented UIViewControllers, I realized how important it is to fully understand the different navigation patterns.
Swift как с модального экрана делать pushviewcontroller
За последнюю неделю я ломаю себе голову над тем, как решить проблему с отображением и отключением нескольких контроллеров представления. Я создал образец проекта и вставил код прямо из проекта. У меня есть 3 контроллера просмотра с соответствующими файлами .xib. MainViewController, VC1 и VC2. У меня есть две кнопки на главном контроллере вида.
Это открывает VC1 без проблем. В VC1 у меня есть еще одна кнопка, которая должна открывать VC2 и одновременно закрывать VC1.
Я хочу, чтобы он вернулся к контроллеру основного представления, в то время как VC1 должен был быть навсегда удален из памяти. VC1 должен отображаться только тогда, когда я нажимаю кнопку VC1 на главном контроллере.
Другая кнопка на контроллере главного представления также должна иметь возможность отображать VC2 напрямую, минуя VC1, и должна возвращаться на главный контроллер при нажатии кнопки на VC2. Нет длительного кода, циклов или таймеров. Просто вызовы костей для просмотра контроллеров.
Ответы
не отправляет сообщение самому себе, он фактически отправляет сообщение своему представляющему VC, прося его выполнить отклонение. Когда вы представляете VC, вы создаете отношения между представляющим VC и представленным. Таким образом, вы не должны уничтожать представляющий VC во время его представления (представленный VC не может отправить это сообщение о закрытии…). Поскольку вы на самом деле не учитываете это, вы выходите из приложения в запутанном состоянии. См. Мой ответ « Отклонение представленного контроллера представления», в котором я рекомендую этот метод, написан более четко:
В вашем случае вам необходимо убедиться, что все управление выполняется в mainVC . Вы должны использовать делегата для отправки правильного сообщения обратно в MainViewController из ViewController1, чтобы mainVC мог отклонить VC1, а затем представить VC2.
В
VC2VC1 добавьте протокол в файл .h над @interface:и ниже в том же файле в разделе @interface объявите свойство для хранения указателя делегата:
В файле VC1 .m метод кнопки отклонения должен вызывать метод делегата
Теперь в mainVC установите его как делегата VC1 при создании VC1:
и реализуем метод делегата:
present2: может быть тем же методом, что и ваш метод IBAction VC2Pressed: button. Обратите внимание, что он вызывается из блока завершения, чтобы гарантировать, что VC2 не будет представлен, пока VC1 не будет полностью отклонен.
Теперь вы переходите от VC1-> VCMain-> VC2, поэтому вы, вероятно, захотите, чтобы был анимирован только один из переходов.
Обновить
В своих комментариях вы выражаете удивление по поводу сложности, необходимой для достижения, казалось бы, простой вещи. Уверяю вас, этот шаблон делегирования настолько важен для большей части Objective-C и Какао, и этот пример — самый простой из возможных, и вам действительно стоит приложить усилия, чтобы освоиться с ним.
В Руководстве по программированию контроллера View от Apple говорится следующее :
Отклонение представленного контроллера представления
Когда приходит время отклонить представленный контроллер представления, предпочтительный подход состоит в том, чтобы позволить контроллеру представления представления отклонить его. Другими словами, всякий раз, когда это возможно, тот же контроллер представления, который представил контроллер представления, также должен нести ответственность за его отклонение. Хотя существует несколько методов для уведомления контроллера представления представления о том, что его представленный контроллер представления должен быть отклонен, предпочтительным методом является делегирование. Для получения дополнительной информации см. «Использование делегирования для связи с другими контроллерами».
Если вы действительно продумаете, чего хотите достичь и как вы это делаете, вы поймете, что обмен сообщениями с вашим MainViewController для выполнения всей работы является единственным логическим выходом, учитывая, что вы не хотите использовать NavigationController. Если вы действительно используете NavController, вы фактически «делегируете», даже если не явно, navController для выполнения всей работы. Должен быть какой-то объект, который будет отслеживать все, что происходит с вашей навигацией по VC, и вам нужен какой-то способ связи с ним, что бы вы ни делали.
На практике совет Apple немного экстремален . в обычных случаях вам не нужно создавать выделенный делегат и метод, вы можете положиться на [self presentingViewController] dismissViewControllerAnimated: — это когда в таких случаях, как ваш, вы хотите, чтобы вы уволили чтобы иметь другие эффекты на удаленные объекты, о которых вам нужно позаботиться.
Вот что вы можете себе представить, работая без хлопот с делегатами .
После того, как представляющий контроллер попросил нас уволить, у нас есть блок завершения, который вызывает метод в PresentingViewController для вызова VC2. Делегат не требуется. (Большой плюс блоков в том, что они уменьшают потребность в делегатах в этих обстоятельствах). Однако в этом случае есть несколько вещей, которые мешают .
- в VC1 вы не знаете, что mainVC реализует метод present2 — вы можете столкнуться с трудными для отладки ошибками или сбоями. Делегаты помогут вам избежать этого.
- после того, как VC1 отклонен, на самом деле не нужно выполнять блок завершения . или нет? Означает ли self.presentingViewController что-нибудь еще? Вы не знаете (я тоже) . с делегатом у вас нет этой неопределенности.
- Когда я пытаюсь запустить этот метод, он просто зависает без предупреждений или ошибок.
Так что, пожалуйста . найдите время, чтобы изучить делегирование!
update2
В своем комментарии вам удалось заставить его работать, используя это в обработчике кнопки увольнения VC2:
Это, конечно, намного проще, но при этом возникает ряд проблем.
Тесная связь
Вы жестко связываете свою структуру viewController вместе. Например, если вы вставите новый viewController перед mainVC, ваше требуемое поведение будет нарушено (вы перейдете к предыдущему). В VC1 вам также нужно было #import VC2. Следовательно, у вас довольно много взаимозависимостей, что нарушает цели ООП / MVC.При использовании делегатов ни VC1, ни VC2 не нужно ничего знать о mainVC или его предшественниках, поэтому мы сохраняем все слабо связанное и модульное.
объем памяти
VC1 никуда не делся, у вас все еще есть два указателя на него:- presentedViewController свойство mainVC
- Свойство presentingViewController VC2
Вы можете проверить это, зарегистрировавшись, а также просто сделав это из VC2.
Он по-прежнему работает, по-прежнему возвращает вас к VC1.
Мне это кажется утечкой памяти.
Ключ к разгадке — в предупреждении, которое вы здесь получаете:
Логика нарушается, поскольку вы пытаетесь отклонить представляющий VC, для которого VC2 является представленным VC. Второе сообщение на самом деле не выполняется — возможно, что-то происходит, но у вас все еще остаются два указателя на объект, от которого, как вы думали, вы избавились. ( править — я проверил это, и это не так уж плохо, оба объекта исчезнут, когда вы вернетесь в mainVC )
Это довольно длинный способ сказать — пожалуйста, используйте делегатов. Если это поможет, я сделал еще одно краткое описание паттерна здесь:
Всегда ли передача контроллера в конструктор — плохая практика?обновление 3
Если вы действительно хотите избегать делегатов, это может быть лучшим выходом:Но ничего не сбрасывайте со счетов . как мы выяснили, на самом деле этого не происходит.
Как мы (знаем), мы не отклонили VC1, мы можем вернуться через VC1 к MainVC. MainVC отклоняет VC1. Поскольку VC1 ушел, предполагается, что VC2 идет с ним, так что вы вернулись на MainVC в чистом состоянии.
Он по-прежнему сильно связан, поскольку VC1 должен знать о VC2, а VC2 должен знать, что он был доставлен через MainVC-> VC1, но это лучшее, что вы получите без небольшого явного делегирования.
Push ViewController с модальной анимацией (горизонтальный флип)
Мне нужно нажать контроллер вида на другой контроллер представления.
переход от menuVC к VC1 не требует анимации, но переход от VC1 к VC2 и от VC2 к VC1 требует возникновения флип-анимации.
Однако при переходе с VC2 на menuVC анимация не требуется.
Я использую следующий код:
Экран полностью исчезает, когда я пытаюсь сделать это.
Теперь вы должны использовать анимацию на основе блоков. Кроме того, если вы создаете контролер раскадровки из контроллера, который также находится в одном и том же раскадровке, вы можете более легко получить доступ к этой раскадровке с помощью self.storyboard.
Однако это также создало пустой экран.
Вместо этого, если вы используете раскадровки, лучше всего создать экземпляр через раскадровку:
yourViewControllerID устанавливается в раскадровке под инспектором идентификации для класса yourviewcontroller.
Как поменять UIViewController внутри модального окна?
Потому-что в нормальном варианте это должно выглядеть следующим образом:
[MainScreenVC]
Button1
—> present [LogInVC]
——> present [NavigationController]
———> push [UserFeedVC]
Button2
—> present [SignInVC]
——>present [NavigationController]
———>push [UserFeedVC]- Вконтакте
В нормальном варианте:
— модальное окно закрывается, пересылая МэйнСкрину инфу о результате логина
— МэйнСкрин пушит/презентит то что надоКак поменять UIViewController внутри модального окна?
Потому-что в нормальном варианте это должно выглядеть следующим образом:
[MainScreenVC]
Button1
—> present [LogInVC]
——> present [NavigationController]
———> push [UserFeedVC]
Button2
—> present [SignInVC]
——>present [NavigationController]
———>push [UserFeedVC]- Вконтакте
В нормальном варианте:
— модальное окно закрывается, пересылая МэйнСкрину инфу о результате логина
— МэйнСкрин пушит/презентит то что надоiOS 5 Попытка pushViewController из модального представления
У меня есть приложение с вкладками iOS 5, использующее раскадровки.
Мой контроллер панели вкладок указывает на три контроллера навигации.
С одной из них поток выглядит так:
Начальный вид —> Просмотр фотографий (модальный) —> Просмотр каталога
На экране фото у меня есть кнопка со следующим кодом:
Я пробовал дурачиться с presentingViewController , parentViewController — даже тип привёл их к UINavigationController . Это приводит к сбою со следующим сообщением об ошибке:
Так что это говорит мне, что я не получил UINavigationController , но UITabBarController .
Есть ли способ обойти это?
2 ответы
Переход в стиле «push» может быть выполнен только из контроллера представления, которым управляет UINavigationController . Если вы попытаетесь это сделать, иначе ничего не произойдет.
Вместо того, чтобы отображать представление Photo модально, как вы описываете в своем вопросе, вы должны отобразить экземпляр UINavigationController в качестве модального представления и сделать представление Photo View контроллером корневого представления представления навигации. (Все это можно настроить с помощью раскадровки). Тогда ваш push segue будет работать.
Если вы не хотите, чтобы верхняя панель навигации появлялась на вашем первом контроллере представления (просмотр фотографий), вы можете использовать:
Это скроет верхнюю панель навигации. После того, как вы нажмете новый контроллер представления, если вы хотите, чтобы панель навигации снова появлялась на этом и любых последующих контроллерах представления, вам нужно будет установить для setNavigationBarHidden значение NO на новом контроллере представления.