實際操作-手把手探究tableViewCell上的控件點擊事件

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

iOS17年4月市場背景~

探究tableViewCell的點擊事件步驟:

1.tableViewCell上的控件觸發(fā)點擊事件


我們都知道,tableViewCell的點擊事件,寫個“didSelectRowAtIndexPath”方法就能實現(xiàn)行點擊效果,經(jīng)常我們做的是行點擊之后頁面跳轉(zhuǎn)(push到另一個界面);

此時:如果我們在cell上自定義幾個控件,然后點擊控件,想要實現(xiàn)控件的點擊效果,不實現(xiàn)cell的行點擊效果:

測試Cell上控件的點擊事件

參與測試的cell上的兩個控件:一個UIButton,一個UIImageView。

我們都知道,UIButton的點擊事件:添加一個addtarget,然后選擇點擊觸發(fā):UIControlEventTouchUpInside,就可以實現(xiàn)Btn的點擊事件。


-->探究1:點擊Button的時候,因為Button在cell上,是否會同時觸發(fā)Button的點擊事件以及 cell的行點擊事件?

測試如上:不會同時觸發(fā)兩個點擊效果

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

imageView的點擊事件

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

addTarget方法底層

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

UIButton繼承自UIControl,所以有addTarget方法
UIImageView不繼承UIControl,所以沒有addTarget方法

-->探究4:沒有addTarget方法的ImageView如何添加點擊事件?

答:使用手勢。

為imageView點擊點按手勢(Tap)

這里要切記:選擇手勢別選錯,也別選默認的手勢,要選擇點按的Tap手勢;


----------------測試:是否會和Btn一樣,觸發(fā)imageView的點按手勢,不觸發(fā)cell的行點擊事件!

imageVIew的點擊

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

打開imageView的用戶交互事件

拓展:UIView,UIButton默認是可以進行用戶交互,如果父控件不能(or 手動關(guān)閉用戶交互),子控件即使是UIButton,也無法觸發(fā)交互事件(例如點擊事件)!!

2.tableViewCell上的控件觸發(fā)點擊事件實現(xiàn)頁面跳轉(zhuǎn)

如同:cell上的點擊事件實現(xiàn)頁面跳轉(zhuǎn)

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

cell的push操作

如同,因為tableViewCell不是ViewController,沒有navigationVC屬性,并不能實現(xiàn)控制器的push操作!


-->解決辦法:值回傳-->通過控制器實現(xiàn)頁面跳轉(zhuǎn)!

回傳的方法:a.通知(沒跨界面的話用通知有點魚,比較low)

? ? ? ? ? ? ? ? ? ? ?b.代理/Block,這里差不多,我使用的是代理,可以僅適用一個代理方法,將按鈕的tag傳過去判斷。

控制器界面--通過代理,實現(xiàn)控制器的跳轉(zhuǎn)

進階篇:實際項目操作

需求如下: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方法可以得到:

tableVIewCell設(shè)置數(shù)據(jù)源

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

在cell的設(shè)置數(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容