测试已测试 | ✓ |
Lang语言 | Obj-CObjective C |
许可协议 | Apache 2 |
发布最后发布 | 2016年11月 |
由 Rafael Lopez Diez 维护。
如果您想要遵循面向对象编程的单一职责原则,则您的视图控制器不应该负责您的应用程序的导航流程。
RLDNavigation
是一组类,允许您通过使用导航命令对象来解耦视图控制器和导航,以定义您的应用程序中可能的导航流程。
它通过广度优先搜索实现路由,以解析复杂的路径。它还防止了如 A > B > C > B
的导航循环。包含了一个示例应用程序。
Swift 版本 也可用。
最简单的设置涉及为您的应用程序中每个 destination
视图控制器子类化 RLDPushPopNavigationCommand
,定义可以导致该视图控制器的可能流程以及如何初始化它,通过重写以下这些类方法来实现
+ (NSArray *)origins;
+ (Class)destination;
+ (NSString *)viewControllerStoryboardIdentifier;
+ (NSString *)nibName; // Defaults to @"Main"
您应在 origins
中返回一个所有可以导致由 destination
中的导航命令所引用的视图控制器类的数组。如果您返回一个空数组或 nil
,则 destination
视图控制器类将可以从任何其他视图控制器访问。
如果您的导航命令没有实现 viewControllerStoryboardIdentifier
和 nibName
,将按以下步骤初始化视图控制器:分配它并调用其 init
方法。
您可以通过创建符合 RLDNavigationCommand
协议的新类或通过子类化同名类簇来创建更高级的导航命令。
一旦您拥有了所有需要的导航命令,您就可以轻松地在视图控制器之间导航。
#import "RLDNavigation.h"
...
Class classOfDestinationViewController = NSClassFromString(@"ViewControllerClass");
[self goToDestination:classOfDestinationViewController];
如果您需要在导航完成后通知您,则可以使用 goWithCompletionBlock
,例如在这个例子中
[self goToDestination:classOfDestinationViewController] completionBlock:^{
// This will be executed once the navigation has taken place
}];
如果您需要在导航到视图控制器时传递参数或自定义视图控制器,您可以指定属性的字典,并且将会使用 KVC(键值编码)来尝试为导航链中每个新实例化的视图控制器设置所有属性。
例如,在此示例的导航过程中,如果压入三个视图控制器,它们的 userName
属性都将被设置为 John Doe
。如果任何视图控制器没有此属性,或者它是只读的,将忽略它。
[self goToDestination:classOfDestinationViewController properties:@{@"userName" : @"John Doe"}];
您可以通过指定必须达到的中间目的地来覆盖完全自动的流程计算。在必要时,将遵循这些里程碑之间的自动路径。
[self goToDestination:classOfDestinationViewController
properties:@{@"userName" : @"John Doe"}
breadcrumbs:@(firstIntermediateClass, secondIntermediateClass)];
面包屑可以帮助您创建复杂的路线,并且也是替换类似URL的导航定义的有用方式。
您应该考虑使用视图模型,而不是公开您的视图控制器类,视图模型是一种更干净、更灵活且类型强大的方法来传递配置参数。如果您的应用程序没有设计成这种方式,您可能需要付出更多的努力,但长期来看可能会得到回报。您可以在附带的示例应用程序中找到如何使用与 RLDNavigation
相关的视图模型的方法。
// RLDMenuViewController
- (IBAction)contactCardTapped {
RLDContactCardViewModel *viewModel = [RLDContactCardViewModel viewModelWithName:@"John"
surname:@"Doe"
email:@"[email protected]"];
[[RLDNavigationSetup setupWithViewModel:viewModel
navigationController:self.navigationController] go];
}
如果您极不可能想使用类似URL的导航方案,您可以使用 RLDNavigation
轻松实现它。只需在 RLDNavigationSetup
上创建一个类别并实现一个工厂方法来转换URL组件为面包屑,并将最终查询转换为属性。您可以在附带的示例应用程序中找到一个基本示例,说明如何做到这一点。
// RLDMenuViewController
- (IBAction)profileTapped {
[[RLDNavigationSetup setupWithUrl:@"folder/profile?userId=2" navigationController:self.navigationController] go];
}
RLDNavigationCommand
是一个类簇。当您调用它的工厂方法 navigationCommandWithNavigationSetup:
时,它将选择到达指定目的地的导航命令类或类链,创建所需的实例,并依次调用它们的 execute
方法。为了能够这样做,RLDNavigationCommand
需要知道所有符合 RLDNavigationCommand
协议的可用类。
默认情况下,您第一次调用 RLDNavigationCommand
实例的 execute
方法时,它将分析所有已加载的类,只注册合适的类。鉴于通常在运行时加载4,000多个类,这可能会相当耗时。
如果您担心性能,您可以手动使用 RLDNavigationCommand+NavigationCommandRegister
类别注册您的符合 RLDNavigationCommand
规范的类而不是使用此自动发现系统。一旦以这种方式注册了一个类,RLDNavigationCommand
将了解您已选择退出自动类发现机制,而且它将不会自动寻找新的类。
在使用手动注册时,为了确保您的类在需要时都准备好,最好的方法是在它们的 load
方法中注册它们。附带的示例应用程序实现了这种方法。
#import "RLDNavigationCommand+NavigationCommandRegister.h"
...
+ (void)load {
[self registerCommandClass];
}
Classes
目录下的所有文件添加到您自己的项目中。RLDNavigation
遵循Apache许可证第2版。更多信息请参阅LICENSE文件。
此README是用GitHub风格的Markdown编辑器制作的。