iOS的UITabBarButton原生是怎麼實現跳轉的?

最近和button杠上了.....學習的時候總喜歡琢磨點什麼,看了看原生應用,好像不是UpInside,手指不抬起,長按也會有跳轉發生。

問題1:默認實現是直接對button addTarget的嗎?

問題2:如果不是那是什麼?

問題3:我知道可以攔截點擊事件,有沒有辦法能把這個事件從UITabBarButton上完全移除?或者修改事件的類型,但是不知道觸發方法的名稱....

問題4:目前有沒有辦法查看這種控制項的源代碼?


先介紹一個 debug 的小技巧,給 UITabBarController 設置一個 delegate,並在

tabBarController(_:, shouldSelect:)

代理方法上打一個斷點,這樣你每次點按或者長按 Tab Item 的時候,Debugger 就會在這暫停,以供你做一系列檢查操作。比如我們現在列印出函數調用棧:

如圖是長按後列印出的調用棧。下面回答問題:

問題1:默認實現是直接對button addTarget的嗎?

是的,UIControl 默認都是使用這種方式來響應事件的。

問題2:如果不是那是什麼?

你可能會問,默認方式如何實現長按。實際上 addTarget 的方式也是可以選擇監聽何種事件的,顯然 UIKit 監聽了按下和抬起兩個事件,並且在按下時用 NSTimer 或者 RunLoop 的方式添加了一個定時器,當定時器 fired 時就直接執行 UITabBar 的私有方法 `_buttonDownDelayed: `,在這個方法中,事件得以繼續分發,最後到了 `UITabBarController` 里

問題3:我知道可以攔截點擊事件,有沒有辦法能把這個事件從UITabBarButton上完全移除?或者修改事件的類型,但是不知道觸發方法的名稱....

很簡單啊,找到 tabBar 這個 view,然後遍歷 subviews,如果這個 subview 是 UIControl 的派生類的話,直接 cast 過去執行 `removeTarget(nil, action: nil, for: .allEvents)`,這個按鈕就是個廢按鈕了,然後你可以隨便怎麼處置。

問題4:目前有沒有辦法查看這種控制項的源代碼?

Hopper Disassmbler,拖入 UIKit.framework,找到相應的類。(P.S. 有時你要學會看點彙編)


推薦閱讀:

學習手機客戶端 iOS 或者安卓軟體的開發,有哪些好的建議(包括入門書籍,開發經驗,行業相關信息)?
大家對同步推的客戶端公然上了App Store怎麼看?
帶交互的 iOS 產品原型可以用什麼軟體製作?
為什麼 iOS 中加粗字體需要重啟(Respring),而改變字型大小卻不用?
iOS 和 Android 到底哪個優秀?哪個更有前景?理由是什麼?

TAG:iOS | iOS開發 | 按鈕 | iOS開發者 |