Навигация Между Экранами С Помощью Файлов Xib

Читая различные источники, я сталкиваюсь с проектами, реализованными с использованием xib-файлов.

Я сам предпочитаю использовать xib вместо раскадровки (пишу не ради холивара, раскадровка тоже хороша), но зачастую обучение навигации между экранами превращается в пытку.

И поэтому мне хотелось бы поделиться собственным опытом.



Навигация между экранами с помощью файлов xib

Почему раскадровка так хороша? Прежде всего, он позволяет собрать всю навигацию и наглядно отобразить большую часть переходов.

Да, используя xib для каждого экрана мы теряем возможность визуально увидеть все переходы (ну и еще пару возможностей), но получаем ряд своих преимуществ.

Я не буду подробно описывать плюсы и минусы использования того и другого во избежание холивара, покажу лишь, как можно собрать всю навигацию с помощью xib-файлов, избавиться от ненужного использования синглтонов, а также как исключить связь между контроллерами.

Подход очень простой.

Мы используем объекты Router для связи между экранами.

Разделим Router на пользовательские истории.

Взаимодействуем с помощью обратного вызова.



Мини демонстрация на практике

  • Энажмите на таблицу и кнопку, чтобы добавить запись.

  • ? Нажмите на создание записи
  • Эдетальный просмотр записи


Начальная настройка

Давайте создадим маршрутизатор и отобразим пустой экран.

RXAppDelegate.m

  
  
  
  
  
  
   

#import "RXAppDelegate.h" #import "RXRouter.h" @implementation RXAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.rootViewController = [[RXRouter alloc] initRouter]; [self.window makeKeyAndVisible]; return YES; } @end

RXRouter.h

#import <UIKit/UIKit.h> @interface RXRouter : UINavigationController - (instancetype)initRouter; @end

RXRouter.m

#import "RXRouter.h" @implementation RXRouter - (instancetype)initRouter { UIViewController *rootViewController = [self createRootViewController]; self = [super initWithRootViewController:rootViewController]; if (self != nil) { self.interactivePopGestureRecognizer.enabled = NO; } return self; } - (UIViewController *)createRootViewController { UIViewController *controller = [[UIViewController alloc] init]; return controller; } @end



Выполнение

Давайте создадим контроллер, который будет показывать записи.

Также мы сразу свяжем этот экран с другими экранами и взаимодействием между ними.

RXRoute.m

#import "RXRouter.h" #import "RXNoteListViewController.h" #import "RXCreateNoteViewController.h" #import "RXDetailNoteViewController.h" @implementation RXRouter - (instancetype)initRouter { UIViewController *rootViewController = [self createRootViewController]; self = [super initWithRootViewController:rootViewController]; if (self != nil) { self.interactivePopGestureRecognizer.enabled = NO; } return self; } - (UIViewController *)createRootViewController { RXNoteListViewController *noteListController = [[RXNoteListViewController alloc] init]; __weak RXRouter *weakSelf = self; __weak RXNoteListViewController *weakNoteListController = noteListController; noteListController.createNoteBlock = ^{ RXCreateNoteViewController *createNoteViewController = [weakSelf createNoteViewController]; createNoteViewController.createNoteBlock = ^(RXNote *note){ [weakNoteListController addNote:note]; [weakSelf popViewControllerAnimated:YES]; }; [weakSelf pushViewController:createNoteViewController animated:YES]; }; noteListController.detailNoteBlock = ^(RXNote *note){ RXDetailNoteViewController *detailNoteViewController = [weakSelf createDetailNoteViewControllerWithNote:note]; [weakSelf pushViewController:detailNoteViewController animated:YES]; }; return noteListController; } - (RXCreateNoteViewController *)createNoteViewController { return [[RXCreateNoteViewController alloc] init]; } - (RXDetailNoteViewController *)createDetailNoteViewControllerWithNote:(RXNote *)note { RXDetailNoteViewController *controller = [[RXDetailNoteViewController alloc] init]; [controller showNote:note]; return controller; } @end

RXNoteListViewController.h

#import <UIKit/UIKit.h> @class RXNote; typedef void (^RXNoteListViewControllerCreateNoteBlock)(); typedef void (^RXNoteListViewControllerDetailNoteBlock)(RXNote *note); @interface RXNoteListViewController : UIViewController @property (copy, nonatomic) RXNoteListViewControllerCreateNoteBlock createNoteBlock; @property (copy, nonatomic) RXNoteListViewControllerDetailNoteBlock detailNoteBlock; - (void)addNote:(RXNote *)note; @end

RXCreateNoteViewController.h

#import <UIKit/UIKit.h> @class RXNote; typedef void (^RXCreateNoteViewControllerCreateNoteBlock)(RXNote *note); @interface RXCreateNoteViewController : UIViewController @property (copy, nonatomic) RXCreateNoteViewControllerCreateNoteBlock createNoteBlock; @end

RXDetailNoteViewController.h

#import <UIKit/UIKit.h> @class RXNote; typedef void (^RXDetailNoteViewControllerDoneBlock)(); @interface RXDetailNoteViewController : UIViewController - (void)showNote:(RXNote *)note; @end

Таким образом, мы сразу видим навигацию между экранами, и каждый экран ничего не знает о других экранах.

Более того, за счет использования блоков удалось исключить необходимость вывода на экран информации о роутере.

Мы также можем легко переносить данные с экрана на экран и сократить использование синглтонов.

Ссылка к проект Теги: #iOS #objective-c #OOP #storyboard #xib #Разработка для iOS #objective-c #OOP

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.