在app中页面跳转是无法回避的问题, 我们平常在代码中遇到跳转,基本都是:

[Swift] 纯文本查看 复制代码
let vc = UIViewController()
self.navigationController?.pushViewController(vc, animated: true)


后面出现了storyboard后可以通过连线进行跳转,传参通过:

[Swift] 纯文本查看 复制代码
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)


获取到要跳转的对象进行传参, 后来还有了Reference可以跳到不同的storyboard,不得不说这样真的方便,但个人感觉这样同时也有一个缺点就是不明确, 我在追踪的时候不容易跟踪, 自己写的过段时间忘了或者说后来人看你写的代码很难理解。

所以写了个简单的路由器, 现在网上也有类似的实现,比如HHRouterroutable-ios等。

iOS页面跳转之Router的Swift实现

iOS页面跳转之Router的Swift实现逐步讲解,含Demo源代码下载 - 敏捷大拇指 - iOS页面跳转之Router的Swift实现





1、基本要求

现有项目要用Swift, 所以做了个Swift版本的跳转,有以下基本需求:

  • 做到write once run anywhere;
  • 页面初始化支持code、xib、storyboard、传参;
  • 基本页面跳转(push、present),内部外部网页跳转,推送通知跳转;
  • 松耦合。


考虑到以上,写了个基本的Routable协议,如果这个ViewController要想支持跳转就必须实现这个协议。




2、Swift实现逐步讲解

协议中的两个方法:

一个是初始化, 一个是返回这个ViewController对应的key。

[Swift] 纯文本查看 复制代码
public protocol Routable {
 
/**
类的初始化方法
- params 传参字典
*/
static func initWithParams(params: RouterParam?) -> UIViewController
/**
每个类跳转对应的key
*/
static var routableKey:String { get }
}


同时在设置了根控制器之后,将此ViewController的key与类名进行对应起来:

[Swift] 纯文本查看 复制代码
let router = Router.sharedInstance
router.navigationController = nav
 
router.map(FirstViewController.routableKey, className: FirstViewController.description())
router.map(SecondViewController.routableKey, className: SecondViewController.description())
router.map(WebViewController.routableKey, className: WebViewController.description())
router.map(FirstNavigationController.routableKey, className: FirstNavigationController.description())


传参,由于Swift是强类型的,没办法,字典中用了Any做为Value:

[Swift] 纯文本查看 复制代码
public typealias RouterParam = [String: Any]


同时为了支持present时的动画效果,添加了RouterOptions来支持一些额外的效果或者要求:

[Swift] 纯文本查看 复制代码
public class RouterOptions {
    let presentationStyle: UIModalPresentationStyle
    let transitionStyle: UIModalTransitionStyle
    /** 只有在isModal为true是才会考虑modal下的style */
    var isModal = false
    /** 只对pushViewController有效 */
    var shouldOpenAsRoot = false
 
    public class func rootOptions() -> RouterOptions {
        return RouterOptions(presentationStyle: .FullScreen, transitionStyle: .CoverVertical, isModal: false, isRoot: true)
    }
 
    public class func modalOptions() -> RouterOptions {
        return RouterOptions(presentationStyle: .FullScreen, transitionStyle: .CoverVertical, isModal: true, isRoot: false)
    }
 
    public init(presentationStyle: UIModalPresentationStyle, transitionStyle: UIModalTransitionStyle, isModal: Bool) {
        self.presentationStyle = presentationStyle
        self.transitionStyle = transitionStyle
        self.isModal = isModal
    }
 
    public init(presentationStyle: UIModalPresentationStyle, transitionStyle: UIModalTransitionStyle, isRoot: Bool) {
        self.presentationStyle = presentationStyle
        self.transitionStyle = transitionStyle
        self.shouldOpenAsRoot = isRoot
    }
 
    private init(presentationStyle: UIModalPresentationStyle, transitionStyle: UIModalTransitionStyle, isModal: Bool, isRoot: Bool) {
        self.presentationStyle = presentationStyle
        self.transitionStyle = transitionStyle
        self.isModal = isModal
        self.shouldOpenAsRoot = isRoot
    }
}


调用open进入新界面,可以选择性的是否传入参数,动画效果, present时的options要求, push/present后的回调等。

[Swift] 纯文本查看 复制代码
private func open(key: String, params: RouterParam?, options: RouterOptions?, animated: Bool, completion: ((opened: UIViewController?) -> Void)?)
{
 
}


添加了基本的打电话,打开外部网页功能,打开外部app。




3、Demo源代码下载

同时写了基本的使用demo,详细代码见Router,需下载本帖附件,如下。

iOS页面跳转之Router的Swift实现逐步讲解,含Demo源代码下载 Router-master.zip.zip (43.79 KB, 下载次数: 0, 售价: 10 金钱)