Pull to refresh

Нативный segue слева направо в iOS

Reading time 3 min
Views 14K
Предупреждаю сразу, это трюк. Он подойдёт далеко не всем и не всегда, но если вам нужно вывести окно с какой-то информацией слева от основного — то мой способ будет в самый раз.

Вполне возможно, что он всем уже известен, и я изобрёл велосипед, но я изобрёл его самостоятельно, после пары дней бесплодных попыток сделать нативный segue слева направо, так что рад поделиться.

Для начала, немного вводных данных. Segue — это способ смены экранов в iOS. Одна из самых популярных разновидностей, это push (с версии iOS 8 — show). Push segue всегда замещает текущий вид справа налево. То есть, у вас как-бы справа есть второе окно, и при нажатии кнопки оно переезжает налево, замещая первое.

Такое поведение вы видите в телефонной книге при выборе абонента. При этом, вверху появляется кнопка возврата на предыдущее окно, и, при нажатии на него, происходит искомая анимация слева направо.

Проблема в том, что мне нужно было сделать всё тоже самое, но в зеркальном отражении и стандартных способов для этого не существует (если верить Google). Есть масса инструкций, как сделать custom segue с похожей анимацией, но все они режут глаз своей неестественностью по сравнению с родным push.

Вот, что у меня получилось в итоге:



Используются исключительно стандартные методы и 0% кастомной анимации. Готовый пример на GitHub.

Идея


Основной трюк заключается в том, что мы не делаем никакого нового segue, мы используем родной push, по назначению.

Думаю, уже по этому скриншоту понятен смысл. Стартовое окно — Info, которое нам нужно выводить слева. При его активации мы быстро и незаметно, без анимации, выводим окно Main при помощи push segue. А после этого уже можно вернуться обратно, используя unwindFromViewController. Только пользователь об этом не знает и видит плавный и красивый left to right segue.

Реализация


Не буду расписывать как соединять друг с другом элементы и назначать кастомные классы, уверен — вы все и так это знаете. В любом случае, можно скачать исходники с GitHub и посмотреть.

Нам понадобятся 2 иконки, один custom segue и один InfoViewController.

На окошко Info мы добавляем одну кнопку с иконкой домика, справа. Затем соединяем её с окном Main обычным push (show) segue.

Создаём кастомный класс InfoViewController, наследник UIViewController и назначаем его окошку Info:
#import "InfoViewController.h"

@interface InfoViewController ()

@end

@implementation InfoViewController

    // Быстрая перемотка на окно Main при первом запуске
    // Запускаем custom segue с идентификатором FastSegue
	- (void) viewDidLoad {
		[self performSegueWithIdentifier:@"FastSegue" sender:nil];
	}

    // Указание метода для возврата на окно Info
	- (IBAction)unwindFromViewController:(UIStoryboardSegue *)sender {
	}

@end


Теперь нужно создать custom segue, который будет незаметно выводить окно Main при старте приложения:
#import "FastSegue.h"

@implementation FastSegue

    // Обычный push segue, только без анимации
	- (void) perform {
		[[[self sourceViewController] navigationController] pushViewController:[self destinationViewController] animated:NO];
	}

@end

А теперь нужно создать связать этим custom segue контроллер Info с Main. Этой связи обязательно присваиваем идентификатор FastSegue.



Дело за малым — сделать возврат на окно Info при нажатии на кнопку окошка Main. Это необязательная часть, потому что, по умолчанию, там и так будет сгенерирована кнопка возврата со стрелкой и названием предыдущего окна, но мне нужна именно иконка.
Кроме того, как оказалось, если заменить backBarButtonItem своим элементом, то нельзя открыть окно Info жестом слева направо, как при обычном segue.

Итак, добавляем на окно Main элемент UINavigationItem и leftBarButtonItem, чтобы заменить автоматически генерирующийся родной backBarButtonItem. Картинкой выбираем иконку «i» и наша кнопка успешно показывается при старте приложения. Только ничего не делает.

Для того, чтобы она заменила собой функционал backBarButtonItem, нужно назначить ей action unwindFromViewController — именно для этого мы и обозначили его в контроллере окна Info.

Так что связываем кнопку с точкой выхода и выбираем unwindFromViewController:

Вот и всё!
Добавлю еще, что для незаметного стартового переключения нужна LaunchImage, или LaunchScreen, но приложений без них и так не бывает.

Если вам кажется, что я здесь написал полный бред и костыль — буду рад увидеть ваше решение и применить его на практике. Мне тоже данный способ кажется не совсем верным, и, тем более, совсем не универсальным, но он работает как мне нужно и отлично выглядит!

Спасибо за внимание.

Updated

Заменил старое видео на чуть более наглядное, с таблицами.

Updated 2

Как оказалось, никакой это не костыль, никакое это не «необычное поведение». Точно так же работает родное приложение Mail.

Открываем Mail — видим сразу письма и вверху кнопку на открытие всех ящиков. При нажатии на неё происходит left to right segue, скорее всего, точно так же сделанный. То есть, предварительной незаметной отмоткой на второе окно.

Выходит, я переизобрёл то, что сама Apple уже давно использует. Привет всем несогласным.
Tags:
Hubs:
+7
Comments 21
Comments Comments 21

Articles