? ? 下面就讓我們以純iOS小白的視角,手把手一步步探究tableView中Cell上的控件點擊事件。

探究tableViewCell的點擊事件步驟:
1.tableViewCell上的控件觸發(fā)點擊事件
我們都知道,tableViewCell的點擊事件,寫個“didSelectRowAtIndexPath”方法就能實現(xiàn)行點擊效果,經(jīng)常我們做的是行點擊之后頁面跳轉(zhuǎn)(push到另一個界面);
此時:如果我們在cell上自定義幾個控件,然后點擊控件,想要實現(xiàn)控件的點擊效果,不實現(xiàn)cell的行點擊效果:

參與測試的cell上的兩個控件:一個UIButton,一個UIImageView。
我們都知道,UIButton的點擊事件:添加一個addtarget,然后選擇點擊觸發(fā):UIControlEventTouchUpInside,就可以實現(xiàn)Btn的點擊事件。
-->探究1:點擊Button的時候,因為Button在cell上,是否會同時觸發(fā)Button的點擊事件以及 cell的行點擊事件?

-->探究2:ImageView的點擊事件

-->探究3:為啥ImageView 沒有 UIbutton 的addtarget方法?

如圖,我們發(fā)現(xiàn)addTarget并不是所有的類都有這個方法-->只有UIControl的子類才能有這個方法!


-->探究4:沒有addTarget方法的ImageView如何添加點擊事件?
答:使用手勢。

這里要切記:選擇手勢別選錯,也別選默認的手勢,要選擇點按的Tap手勢;
----------------測試:是否會和Btn一樣,觸發(fā)imageView的點按手勢,不觸發(fā)cell的行點擊事件!

原因:imageView需要手動打開用戶交互!

拓展:UIView,UIButton默認是可以進行用戶交互,如果父控件不能(or 手動關(guān)閉用戶交互),子控件即使是UIButton,也無法觸發(fā)交互事件(例如點擊事件)!!
2.tableViewCell上的控件觸發(fā)點擊事件實現(xiàn)頁面跳轉(zhuǎn)

需求:通過點擊cell上的不同的按鈕-->實現(xiàn)不同頁面跳轉(zhuǎn)

如同,因為tableViewCell不是ViewController,沒有navigationVC屬性,并不能實現(xiàn)控制器的push操作!
-->解決辦法:值回傳-->通過控制器實現(xiàn)頁面跳轉(zhuǎn)!
回傳的方法:a.通知(沒跨界面的話用通知有點魚,比較low)
? ? ? ? ? ? ? ? ? ? ?b.代理/Block,這里差不多,我使用的是代理,可以僅適用一個代理方法,將按鈕的tag傳過去判斷。

進階篇:實際項目操作
需求如下:1.有網(wǎng)絡(luò)數(shù)據(jù)請求;2.cell的數(shù)據(jù)是從控制器傳過去的(可以通過字典轉(zhuǎn)模型);3.使用AFN請求數(shù)據(jù)(異步請求)
問題:何時發(fā)起數(shù)據(jù)請求?
答:因為我們一開始并不知道要點擊的是哪行的數(shù)據(jù)->在tableView的行點擊(didSelectRowAtIndexPath)的時候,由于我們可以拿到點擊的下標,通過下標可以知道我們點擊的是哪行,此時發(fā)送數(shù)據(jù)請求
-->錯誤:1.我們點擊的是頭像(UIImageView),觸發(fā)的是頭像的點按手勢,并不會調(diào)用didSelectRowAtIndexPath方法;
? ? ? ? ? ? ? 2.異步請求,在點擊的時候,發(fā)送請求,點擊整個操作結(jié)束后,異步的請求都不一定執(zhí)行完,由于異步執(zhí)行,數(shù)據(jù)經(jīng)常是當(dāng)時獲取沒完成就接下去執(zhí)行了,導(dǎo)致數(shù)據(jù)為空;
? ? ? ? ? ? ? 3.在2的基礎(chǔ)上,執(zhí)行完didSelectRowAtIndexPath之后AFN請求完畢,獲取數(shù)據(jù)成功,以往我們經(jīng)常調(diào)用tableView的刷新數(shù)據(jù)方法-reloadData,但是我們會發(fā)現(xiàn)didSelectRowAtIndexPath并不會再tableView reloadData之后再被調(diào)用一次?。∷詫?dǎo)致了:數(shù)據(jù)一直是空的可能性!
-------------------------華麗分割線------------------------
正確做法:不在tableView的行點擊進行數(shù)據(jù)請求,要拿到數(shù)據(jù)下標,并不只有didSelectRowAtIndexPath方法可以得到:

數(shù)據(jù)請求何時發(fā)送?

-->在cell界面加載的時候,就會自動發(fā)送網(wǎng)絡(luò)請求獲取數(shù)據(jù)
當(dāng)我們點擊的時候,cell界面都不知道加載完成多少秒了,此時AFN發(fā)送的異步請求怎么說也該請求成功了(邏輯嚴謹性:此時加個網(wǎng)絡(luò)請求數(shù)據(jù)是否成功的判斷,成功在展示可以點擊的按鈕)
-->怎么讓控制器知道我們點擊了哪行的cell --> 沒有觸發(fā)cell的didSelectRowAtIndexPath方法

我們拿到的當(dāng)前行的數(shù)據(jù),是tableView - cellForRowAtIndexPath方法設(shè)置cell數(shù)據(jù)展示的時候,一行一行傳過來的,所以每個indexPath.row對應(yīng)的數(shù)據(jù),我們通過網(wǎng)絡(luò)請求+數(shù)據(jù)回傳(通過代理),還是當(dāng)前行的數(shù)據(jù)!
解釋如下圖:

如圖:我們并不調(diào)用行點擊事件,但是當(dāng)我們點擊cell的按鈕,通過代理把cell的內(nèi)容(如上圖的內(nèi)容:b)回傳到控制器tableView上顯示的時候,從tableVIew展示的內(nèi)容-->b,我們就可以知道剛才點擊的是哪個cell里面的按鈕!
-->而且完美解決了AFN異步網(wǎng)絡(luò)請求導(dǎo)致的需要數(shù)據(jù)可能為空的問題,也希望能給新手們提供一點探究原理的思路和流程
抽空寫了一個簡單Demo:Demo