iOS 路由跳转
项目中我们会有很多的页面,我们就需要不断的push或者present
如果我们能够实现路由跳转(像网页一样通过一个URL地址去访问)就会方便很多
那么我们今天就来讨论下页面使用路由跳转
一、首先我们要清楚一些基本概念
1、scheme
每个app都有自己独立的沙盒、互相独立。这样阻碍了app之间的通信。
苹果给我们的通信是通过URL Schemes。只要每个app定义了自己的Schemes,便能实现app之间跳转。
苹果系统原生的app、比如打电话tel://等。还有一些第三方的,比如支付宝alipay://
其实scheme 就是://前面的英文字符
路由跳转就是约定一个url。也就是根据scheme进行跳转
2、NSURL
/* Any URL is composed of these two basic pieces. The full URL would be the concatenation of [myURL scheme], ':', [myURL resourceSpecifier] */ @property (nullable, readonly, copy) NSString *scheme; @property (nullable, readonly, copy) NSString *resourceSpecifier; /* If the URL conforms to rfc 1808 (the most common form of URL), the following accessors will return the various components; otherwise they return nil. The litmus test for conformance is as recommended in RFC 1808 - whether the first two characters of resourceSpecifier is @"//". In all cases, they return the component's value after resolving the receiver against its base URL. */ @property (nullable, readonly, copy) NSString *host; @property (nullable, readonly, copy) NSNumber *port; @property (nullable, readonly, copy) NSString *user; @property (nullable, readonly, copy) NSString *password; @property (nullable, readonly, copy) NSString *path; @property (nullable, readonly, copy) NSString *fragment; @property (nullable, readonly, copy) NSString *parameterString API_DEPRECATED("The parameterString method is deprecated. Post deprecation for applications linked with or after the macOS 10.15, and for all iOS, watchOS, and tvOS applications, parameterString will always return nil, and the path method will return the complete path including the semicolon separator and params component if the URL string contains them.", macosx(10.2,10.15), ios(2.0,13.0), watchos(2.0,6.0), tvos(9.0,13.0)); @property (nullable, readonly, copy) NSString *query;
例如:
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com/test/mypath?test=baiduhome&number=123"];
scheme http
host www.baidu.com
path /test/mypath
query test=baiduhome&number=123
二、实现原理
1、创建一个单例对象拥有一个可变字典,用来保存键值对
2、以query之前为key 类名为value 在每个页面的load方法中完成注册
3、在每个页面实现具体跳转逻辑
例如:
NSURL *url = [NSURL URLWithString:@"project://test/mypath?test=baiduhome&number=123"];
key project://test/mypath
value TestViewController
SchemeProtocol
typedef void(^SchemeCompletion)(id objc); @protocol SchemeProtocol <NSObject> // 跳转方法 + (void)SchemeData:(NSDictionary *)data url:(NSString *)url completion:(SchemeCompletion)handler; @end
SchemeTool
@interface SchemeTool() @property (nonatomic,strong) NSMutableDictionary *modules; @end @implementation SchemeTool #pragma mark - Instancet + (instancetype)shared { static SchemeTool * schemeTool = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ schemeTool = [[SchemeTool alloc] init]; }); return schemeTool; } - (instancetype)init{ self = [super init]; if (self) { _modules = [[NSMutableDictionary alloc] init]; } return self; }
// 注册 url与Class绑定
+ (void)registerModule:(Class)moduleClass pathName:(NSString *)pathName{
[iComeSchemeTool shared].modules[pathName] = moduleClass;
}
// 跳转 通过url实现跳转
+ (void)receiveSchemeURL:(NSURL *)schemeURL completion:(SchemeCompletion)handler{
NSString *query = schemeURL.query;
NSString *key = [[schemeURL.absoluteString componentsSeparatedByString:@"?"] firstObject];
// 通过url找到对应Class
Class ocClass = [SchemeTool shared].modules[key];
// 判断是否实现跳转方法
if (ocClass &&
[ocClass respondsToSelector:@selector(SchemeData:url:completion:)]){
// 解析query
NSDictionary *dic = [SchemeTool queryDicWithStr:query];
// 调用跳转方法
[[ocClass class] SchemeData:dic url:schemeURL.absoluteString completion:handler];
}else {
// 未实现跳转方法
}
}
// 解析query
+ (NSDictionary *)queryDicWithStr:(NSString *)queryStr{
NSMutableDictionary *dict = [NSMutableDictionary new];
NSArray *paramArray = [queryStr componentsSeparatedByString:@"&"];
for (NSString *param in paramArray) {
if (param && param.length) {
NSRange range = [param rangeOfString:@"="];
if (range.location != NSNotFound) {
NSString *keyStr = [param substringToIndex:range.location];
NSString *valueStr = [param substringFromIndex:range.location+range.length];
dict[keyStr] = valueStr;
}else{
dict[param] = param;
}
}
}
return dict;
}
TestViewController
@implementation TestViewController
+ (void)load {
// 注册 url与Class 绑定
[SchemeTool registerModule:[self class] pathName:@"project://test/mypath"];
}
// 跳转方法
+ (void) SchemeData:(NSDictionary *)data url:(NSString *)url completion:(SchemeCompletion)handler { TestViewController *vc = [[TestViewController alloc] init]; vc.test = data[@"test"]; [[WOWSUtils getCurrentVC] pushViewController:vc]; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
2021-07-21 iOS sizeForItemAtIndexPath方法在iOS14下变化