Нативный segue слева направо в iOS
Предупреждаю сразу, это трюк. Он подойдёт далеко не всем и не всегда, но если вам нужно вывести окно с какой-то информацией слева от основного — то мой способ будет в самый раз.Вполне возможно, что он всем уже известен, и я изобрёл велосипед, но я изобрёл его самостоятельно, после пары дней бесплодных попыток сделать нативный segue слева направо, так что рад поделиться.
Для начала, немного вводных данных. Segue — это способ смены экранов в iOS. Одна из самых популярных разновидностей, это push (с версии iOS 8 — show). Push segue всегда замещает текущий вид справа налево. То есть, у вас как-бы справа есть второе окно, и при нажатии кнопки оно переезжает налево, замещая первое.
Такое поведение вы видите в телефонной книге при выборе абонента. При этом, вверху появляется кнопка возврата на предыдущее окно, и, при нажатии на него, происходит искомая анимация слева направо.
Проблема в том, что мне нужно было сделать всё тоже самое, но в зеркальном отражении и стандартных способов для этого не существует (если верить Google). Есть масса инструкций, как сделать custom segue с похожей анимацией, но все они режут глаз своей неестественностью по сравнению с родным push.
Вот, что у меня получилось в итоге:[embedded content]Используются исключительно стандартные методы и 0% кастомной анимации. Готовый пример на GitHub.
ИдеяОсновной трюк заключается в том, что мы не делаем никакого нового segue, мы используем родной push, по назначению. Думаю, уже по этому скриншоту понятен смысл. Стартовое окно — Info, которое нам нужно выводить слева. При его активации мы быстро и незаметно, без анимации, выводим окно Main при помощи push segue. А после этого уже можно вернуться обратно, используя unwindFromViewController. Только пользователь об этом не знает и видит плавный и красивый left to right segue.Реализация Не буду расписывать как соединять друг с другом элементы и назначать кастомные классы, уверен — вы все и так это знаете. В любом случае, можно скачать исходники с GitHub и посмотреть.Нам понадобятся 2 иконки, один custom segue и один InfoViewController.
На окошко Info мы добавляем 2 кнопки. Одну с иконкой домика — справа, а вторую прозрачную — слева. Она нам нужна для custom segue без анимации, плюс поможет выравнивать заголовок посередине окна. Кнопка «домик» соединяется с окном Main обычным push (show) segue.
Создаём кастомный класс InfoViewController, наследник UIViewController и назначаем его окошку Info:
#import «InfoViewController.h»
@interface InfoViewController ()
@end
@implementation InfoViewController
// Быстрая перемотка на окно Main при первом запуске — (void) viewDidLoad { [self performSegueWithIdentifier:@«FastSegue» sender: nil]; }
// Указание метода для возврата на окно Info — (IBAction)unwindFromViewController:(UIStoryboardSegue *)sender { }
@end Теперь нам нужен custom segue с идентификатором FastSegue, который будет незаметно выводить окно Main при старте приложения:
#import «FastSegue.h»
@implementation FastSegue
// Обычный push segue, только без анимации — (void) perform { [[[self sourceViewController] navigationController] pushViewController:[self destinationViewController] animated: NO]; }
@end Вешаем этот segue на прозрачную кнопку и назначаем ему идентификатор FastSegue.Дело за малым — сделать возврат на окно Info при нажатии на кнопку окошка Main. Это необязательная часть, потому что, по умолчанию, там и так будет сгенерирована кнопка возврата со стрелкой и названием предыдущего окна, но мне нужна именно иконка.
Добавляем на окно Main элемент UINavigationItem и leftBarButtonItem, чтобы заменить автоматически генерирующийся backBarButtonItem. Картинкой выбираем иконку «i» и наша кнопка успешно показывается при старте приложения. Только ничего не делает.
Для того, чтобы она заменила собой функционал backBarButtonItem, нужно назначить ей action unwindFromViewController — именно для этого мы и обозначили его в контроллере окна Info.
Так что связываем кнопку с точкой выхода и выбираем unwindFromViewController:
Вот и всё! Добавлю еще, что для незаметного стартового переключения нужна LaunchImage, или LaunchScreen, но приложений без них и так не бывает.Если вам кажется, что я здесь написал полный бред и костыль — буду рад увидеть ваше решение и применить его на практике. Мне тоже данный способ кажется не совсем верным, и, тем более, совсем не универсальным, но он работает как мне нужно и отлично выглядит!
Спасибо за внимание.