iOS - Swift 面向協議程式設計(二)

LinXunFeng發表於2017-10-23

上一篇文章iOS - Swift 面向協議程式設計(一) 已經對Swift的面向協議程式設計做了介紹,接下來該篇文章將使用面向協議開發(POP)來做下實際的應用

在實際開發中,自定義View基本上是必須的,相信這對我們來說都是比較簡單,不過我們還是來回顧一下下~

物件導向開發

1 新建一個UIView的FirstTypeView

FirstTypeView
FirstTypeView

2 建立一個View的xib檔案

xib
xib

3 設定xib對應的class進行繫結

xib class
xib class

4 在FirstTypeView.swift 中實現一個類方法,方便我們外部用xib來初始化FirstTypeView

import UIKit

class FirstTypeView: UIView {

}

extension FirstTypeView {
    class func loadFromNib() -> FirstTypeView {
        return Bundle.main.loadNibNamed("\(self)", owner: nil, options: nil)?.first as! FirstTypeView
    }
}複製程式碼

在外部只要呼叫FirstTypeView的loadFromNib方法就可以初始化一個View來使用了。好,現在又有一個類SecondTypeView,也是要求使用xib來初始化view。這時我們就會想,一樣的載入xib的方法,那我們就把它抽取出來放到父類就可以了。這裡的父類以BaseView.swift為例
父類的主要實現程式碼

extension BaseView {
    class func loadFromNib() -> BaseView {
        return Bundle.main.loadNibNamed("\(self)", owner: nil, options: nil)?.first as! BaseView
    }
}複製程式碼

那我們的FirstTypeView和SecondTypeView只需要直接繼承於BaseView就可以了,在其它地方初始化view也很方便

let firstView = FirstTypeView.loadFromNib()
view.addSubview(firstView)

let secondView = SecondTypeView.loadFromNib()
view.addSubview(secondView)複製程式碼

好,現在FirstTypeView裡宣告瞭一個屬性name,SecondTypeView宣告的屬性為age,假如我們現在要使用各自對應的屬性,這時是直接點不出來的,需要先進行強轉

let firstView = FirstTypeView.loadFromNib() as! FirstTypeView
firstView.name = "LXF"
view.addSubview(firstView)

let secondView = SecondTypeView.loadFromNib() as! SecondTypeView
secondView.age = 100
view.addSubview(secondView)複製程式碼

但是這樣覺得不是很方便,還需要進行強轉,我們能不能在BaseView裡面搞定它呢?如果是Swift 2.x 的話是可以的

extension BaseView {
    class func loadFromNib() -> Self { // 注意這裡是大寫的S
        return Bundle.main.loadNibNamed("\(self)", owner: nil, options: nil)?.first as! Self
    }
}複製程式碼

但是現在Swift 3.0已經不支援這種寫法了,會報錯。這個時候如果使用面向協議的開發就很方便了。

面向協議開發

將BaseView刪除,FirstTypeView和SecondTypeView改回繼承於UIView

1 新建一個Swift檔案 Nibloadable.swift

Nibloadable
Nibloadable

2 實現協議方法

協議中不允許定義類方法,需改為靜態方法

import UIKit

protocol Nibloadable {

}

extension Nibloadable {
    static func loadFromNib() -> Self {
        return Bundle.main.loadNibNamed("\(self)", owner: nil, options: nil)?.first as! Self
    }
}複製程式碼

3 遵守協議

class SecondTypeView: UIView, Nibloadable {
    var age: Int = 10
}複製程式碼

這樣就可以了,而且你在呼叫loadFromNib方法時可以發現,型別是對應上的

loadFromNib協議方法
loadFromNib協議方法

好了,面向協議開發的應用就記錄到這裡,希望能幫助到大家!

Demo

相關文章