天天看點

窺探Swift之協定(Protocol)和委托代理(Delegate)回調的使用

  今天就結合兩個執行個體來窺探一下swift中的協定與delegate回調(委托代理回調)。本篇先給出cocoatouch中常用控件uitableview的常用回調,并以此來認識一下回調的使用方式。緊接着會給出如何去實作自己的delegate回調,即在自定義控件中去實作委托代理回調。言歸正傳,開始今天的部落客題。

  一.從uitableview中來窺探協定的委托代理回調

    uitableview這個進階控件在ios開發中的出鏡率是比較高的,今天的重點不是介紹如何使用uitableview, 而是讓通過uitableview的工作方式來直覺的感受一下協定的使用場景,以及delegate代理的工作方式。如果你對uitableview控件不熟的話,完全可以跳過這一部分,直接進入第二部分。如果你要更好的了解delegate委托回調,還是很有必要看這一部分的。

    下面就先以uitableview的uitableviewdatasource協定來看一下委托代理的使用方式。為了簡化代碼呢,下面的tableview的使用就沒有實作uitableviewdelegate協定還是那句話,今天的重點是protocol和delegate, 而不是如何使用uitableview。下方的截圖就是我們要使用uitableview和uitableviewdatasource來做的事情。當然下方的執行個體無論是代碼還是布局方面還是灰常簡單的,運作效果如下所示。

窺探Swift之協定(Protocol)和委托代理(Delegate)回調的使用

    上面的cell中就是一個imageview和一個label, 布局灰常簡單啦,接下來就簡單介紹一下在swift中是如何實作(說白了,和objc實作起來大同小異)。還是結合着storyboard來做吧,畢竟使用storyboard布局更為簡單一些。

    1. 使用storyboard來布局控件,控件布局如下:

窺探Swift之協定(Protocol)和委托代理(Delegate)回調的使用

    2. 給上述cell綁定相應的swift源碼,并關聯imageview和label, 相應cell(beautifulgrillcell)的代碼如下所示。girlimageview即為做吧的圖檔,

girlnamelable為圖檔右邊的文字。

    3.接下來就是要模拟我們在tableview上顯示的資料了,在正常開放中這些資料往往來源于網絡請求,而在本篇部落格中就模拟資料源,來為我們的tableview提供顯示的資料。資料源的格式是一個數組,而數組中存放的是多個字典,每個字典有兩個鍵值對,一個鍵值對存儲要顯示圖檔的檔案名,另一個鍵值對則存儲美女的名字。為了使該資料的存儲結構,請看下方結構圖。

窺探Swift之協定(Protocol)和委托代理(Delegate)回調的使用

    原理圖有了,接下來就要使用代碼來建立出上述結構的資料以供tableview的資料源使用,下面的方法就是實作上述結構的函數。

       (1) 首先我們要在視圖控制器相應的類中添加一個可變數組,用來存放資料,如下所示:

      (2) 接着就是往上面這個數組中填充資料了,代碼如下:

    4. 我們上面storyboard中的視圖控制器使用的是uiviewcontroller而不是uitableviewcontroller。 我們在uiviewcontroller上貼了一層uitableview, 是以我們需要在相應的viewcontroller對應的swift源碼中進行uitableview的綁定,并實作uitableviewdatasource代理,并為uitableview指定該代理。下方的代碼就是關聯tableview并指定代理方法。代碼如下:

    4. 對mytableview的datasource(資料提供者)指定完代理對象後,接下來就是要實作uitableviewdatasource中的相應的方法了,viewcontroller通過這些協定委托回調的代理方法來為tableview提供資料。下方是uitableviewdatasource委托方法中傳回tableview的section個數的回調方法,如下所示:

    5.上面回調方法是傳回section個數的,緊接着下方就是傳回每個section中cell個數的回調方法。cell的個數就是數組datasource中元素的個數。

    6. 下面這個方法是比較重要的,下方的方法,就是傳回每行的cell的委托回調方法。通過cell的重用标示符來建立cell的執行個體對象,并對cell上的一些屬性指派,并傳回目前是cell執行個體對象,代碼如下所示。

經過上面這些步驟,你就可以去實作部落格最上方截圖中的效果了,上面主要用到的還是tableview的uitableviewdatasource委托代理, 使用方法如上。上面使用的委托回調主要是使用swift中的協定(protocol)來實作的。那麼如何使用協定來實作你自己的委托回調呢?這将是下面将要介紹的内容。

  二. 認識協定,并使用協定實作委托回調

    接下來的内容就要介紹如何使用協定來定義屬于你自己的委托代理回調(delegate)了。第二部分還是以執行個體為準,在上面的demo中加入我們自己定義的委托代理回調。我們需要做的就是,在上面界面中,我們點選任意cell就可以push(導航控制器展示視圖控制器的一種方式,可以了解為視圖控制器壓棧的過程)到一個viewcontroller中,這個viewcontroller要做的事情就是輸入美女的名字,點選傳回後通過自己定義的委托回調,把你輸入的值回調到上一個頁面(tableview)中去,并修改相應cell上的名字。說白了,就是對美女的名字做一個修改。

    如果上面的文字讓你迷惑的話,那麼接下來看執行個體好了,該執行個體還算是簡單的。下方是執行個體的操作步驟,如下所示:

窺探Swift之協定(Protocol)和委托代理(Delegate)回調的使用

    1.實作編輯美女姓名的頁面

      (1) 在storyboard上新添加一個視圖控制器(uiviewcontroller), 并命名為editviewcontroller,給視圖控制器就是上方截圖中綠色的那個視圖控制器,主要用來對美女姓名 修改,并通過委托回調把值傳給上個頁面。該視圖控制器的頁面布局比較簡單,具體如下所示:

窺探Swift之協定(Protocol)和委托代理(Delegate)回調的使用

      (2)ui就如數所示,為editviewcontroller關聯editviewcontroller.swift源檔案後,再對其上面的使用到的控件進行關聯即可。緊接着我們要實作一個協定,這個協定我們用來所委托回調使用。這個協定可以定義在editviewcontroller.swift源檔案中。在協定定義之前,先對什麼是協定簡單的提上一嘴。先簡單的了解,協定中的方法隻有聲明,沒有實作,并且使用protocol關鍵自進行聲明,下方的代碼就是我們要使用的協定。協定中有一個fetchgirlname(name:string)的方法,用來回調出輸入的數值。預設方法是必選的,你可以使用optional關鍵字使方法可選,在此就不做過多贅述了。

      (3) 接着要實作editviewcontroller類中的東西了,代碼如下。

        成員變量var girloldname:string?負責接收上個頁面傳過來的美女的姓名。weak var delegate:editviewcontrollerdelegate? 這個聲明為weak的delegate成員變量則是必須要實作editviewcontrollerdelegate協定的委托代理者,使用weak修飾為了避免強引用循環。接着是girlnametextfield就是關聯的輸入框了,負責接收使用者輸入,把值傳遞給委托代理者。

        在viewwilldisappear方法中,會将使用者輸入的值傳遞給委托代理者的fetchgirlname方法。deinit是析構函數,用來觀察是否引起強引用循環,因為我們是使用的weak, 是以不會引起強引用循環,該deinit方法當傳回時,是會被釋放掉的。

    2.上面的代碼是實作編輯頁面并實作相應的委托協定,下方就是要從之前tableview中進行跳轉。也就是點選tableview的每一行,然後跳轉到編輯頁面對其目前點選的cell進行編輯,編輯後傳回通過代理進行值的修改。

      (1)首先要解決的就是點選cell跳轉到editviewcontroller, 要執行這個事件,我們還必須實作tableview的另一個協定,就是uitableviewdelegate, 以為點選cell的事件擷取的方法就在tableviewdelegate中。是以我們要在tableview所在的viewcontroller中的viewdidload()中指定uitableviewdelegate的委托代理者。如下所示。同時該viewcontoller也要實作uitableviewdelegate協定。

    

      (2) 實作uitableviewdelegate協定中點選cell的方法,方法中的内容如下所示。在該方法中,首先我們要暫存一下點選的是哪個cell, 也就是記錄一下點選cell的indexpath, 然後就是擷取點選的cell對象,因為通過該cell對象,可以擷取相應cell上的資料。具體的不多說了,請看代碼中的注釋。

      (3)上面是跳轉,接下來就是要實作editviewcontrollerdelegate中的回調方法,來處理相應的回調參數了。下方就是在表視圖中實作的回調方法,具體請看代碼中的注釋:

  

    經過上面的步驟,我們就可以去定義屬于自己的協定,并在此協定上實作委托回調了。上面的場景在ios開發中極為常見,使用場景也是比較廣泛的。是以協定無論在swift還是在ios開發中都是極為重要的概念之一。好今天的部落格内容也挺多的了,就到此為止,剩下的東西,會在以後的部落格中繼續更新。