美文网首页iOS开发程序员iOS学习
Swift开发小技巧系列 - 更优雅的实现Segue

Swift开发小技巧系列 - 更优雅的实现Segue

作者: DEREK_ZHOU | 来源:发表于2017-09-25 16:25 被阅读0次

    原文链接

    正文

    我们在实际开发中偶尔会遇到一些很傻很天真的BUG,结果花了很长时间调试,最后发现这些BUG大多源于一个非常小的问题。最常见的就是在一个字符串中敲错了一两个字母。在实际开发中我们又不得不面对很多读取资源文件的操作,这些操作很多都需要直接操作资源文件名称的字符串来完成。

    比如初始化Image

    let image = UIImage(named: "checklist_not_completed_20x20_")
    

    注:从Xcode8开始,读取image可以使用Image Literal

    Perform Segue

    self.performSegue(withIdentifier: "showDetail", sender: self)
    

    这样其实有两个问题:

    1. 对于字符串Xcode IDE没有代码提示功能,重复敲这些字符串很费时间,并且当字符串稍微复杂点时,你有一定的概率敲错,增加了出BUG的概率。
    2. Xcode IDE也不会为字符串提供编译时检测,所以如果敲错,你只能等测试出现BUG,然后去查找修复,成本很高。

    今天我们就来探讨下怎么优化Segue,来解决我们上面提到的问题。

    public protocol CustomSegueProtocol {
        associatedtype CustomSegueIdentifier: RawRepresentable
        func performCustomSegue(_ segue: CustomSegueIdentifier, sender: Any?)
        func customSegueIdentifier(forSegue segue: UIStoryboardSegue) -> CustomSegueIdentifier
    }
    

    首先定义一个协议CustomSegueProtocol,在协议里添加一个关联类型CustomSegueIdentifier,继承与RawRepresentable协议。同时声明两个方法performCustomSegue(_::)customSegueIdentifier(_:)

    extension CustomSegueProtocol where Self: UIViewController,
        CustomSegueIdentifier.RawValue == String {
        
        public func performCustomSegue(_ segue: CustomSegueIdentifier, sender: Any?) {
            performSegue(withIdentifier: segue.rawValue, sender: sender)
        }
        
        public func customSegueIdentifier(forSegue segue: UIStoryboardSegue) -> CustomSegueIdentifier {
            guard let identifier = segue.identifier,
                let customSegueIndentifier = CustomSegueIdentifier(rawValue: identifier) else {
                    fatalError("Cannot get custom segue indetifier for segue: \(segue.identifier ?? "").")
            }
            
            return customSegueIndentifier
        }
    }
    

    CustomSegueProtocol添加默认实现,并且在添加一些约束。首先我们要求CustomSegueProtocol协议只能被UIViewController及其子类使用。其次关联类型CustomSegueIdentifierRawValueString,因为我们在storyboard里面设置Segue的identifier只能是String。具体实现内容比较简单,就是调用Apple原生处理segue的方法。

    下面看看具体怎么使用?

    class TestCustomSegueViewController: UITableViewController, CustomSegueProtocol {
        enum CustomSegueIdentifier: String {
            case showNext
        }
    
        override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            performCustomSegue(.showNext, sender: self)
        }
        
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            switch customSegueIdentifier(forSegue: segue) {
            case .showNext:
                // Configuration for next page
            }
        }
    }
    

    首先让你的UIViewController继承CustomSegueProtocol协议。然后把该协议的关联类型CustomSegueIdentifier定义为枚举类型,并列出所有的segue。然后在操作segue的时候调用performCustomSegue(_::)customSegueIdentifier(_:)这两个协议函数。

    总结

    • 通过上面的改造,我们用新的方式来操作segue有以下一些好处:

      1. Xcode 的代码提示功能,减少了敲错字母引起BUG的概率
      2. 因为新的CustomSegueIdentifier是个强类型,Xcode能在编译时期对其进行类型检测。
      3. UIViewController统一用枚举类型定义所有的segue,方便管理维护,同时也可以充分利用枚举一些特性。
    • 具体详细代码请参考SwiftDevHints

    联系方式

    备注

    我们在软件开发的过程中,为了提高效率,其中很重要的一环就是把反复使用到的功能或模块封装起来。因此我在GitHub上开源了一个小工具集 - SwiftDevHints,来总结自己在实际项目开发过程中封装的一些小功能。

    刚刚介绍的只是其中一个小功能,想看看其它更多功能,请直接点击SwiftDevHints。如果您觉得对您有所帮助,请给一个star吧。

    相关文章

      网友评论

        本文标题:Swift开发小技巧系列 - 更优雅的实现Segue

        本文链接:https://www.haomeiwen.com/subject/cdddextx.html