天天看點

【iOS開發】使用 protocol 與 extension 來限制函數作用域

今天碰到這樣一個場景,我需要一個僅僅用來展示網頁的頁面,那麼在 iOS 9 中,我可以使用 SFSafariViewController,而在 iOS 8 及之前版本中,我會使用一個 WebView 來占據整個視圖空間,來做這件事。

就會有下面這行代碼

webview.frame = UIScreen.mainScreen().bounds
           

進一步地,我想把這個步驟封裝為一個函數,因為比如這個頁面螢幕旋轉時,或者在其他頁面,我都可能需要用到它。

func expandView(view:UIView) {
    if view.isKindOfClass(UIWebView) || view.isKindOfClass(WKWebView) {
        view.frame = UIScreen.mainScreen().bounds
    }
}
           

這段代碼是說,我們現在可以把 UIWebView 和 WKWebView 都擴充到最大了,其他 UIView 被傳入的時候,不會有任何意義。但這不是我想要的,我希望其他 UIView 根本無法調用這個函數,以免産生誤解。

于是我寫了下面這段代碼:

protocol ExpandableView {
    func expandToFullView()
}

private func expand(view:UIView) {
    view.frame = UIScreen.mainScreen().bounds
}

extension WKWebView: ExpandableView {
    func expandToFullView() { expand(self) }
}

extension UIWebView: ExpandableView {
    func expandToFullView() { expand(self) }
}
           

現在,UIWebView 和 WKWebView 都可以通過 ExpandableView 這個協定,來使用我們定義好的(具有擴充一個 View 到整個界面大小這層意義的) expandToFullView 這個函數,而且因為這個函數的實作實際上是 expand 這個函數,是以他們表現起來是一樣的。與此同時,expand 這個函數本身被聲明為了 private,這使得這個函數不會在其他源檔案以其他方式被調用。

這段代碼被應用在了

這個項目

這個檔案

繼續閱讀