iOS開發UIScrollView的底層實現

發表於2016-08-17

起始

做開發也有一段時間了,經歷了第一次完成專案的激動,也經歷了天天呼叫系統的API的枯燥,於是就有了探索底層實現的想法。

關於scrollView的思考

在iOS開發中我們會大量用到scrollView這個控制元件,我們使用的tableView/collectionview/textView都繼承自它。scrollView的頻繁使用讓我對它的底層實現產生了興趣,它到底是如何工作的?如何實現一個scrollView?讀完本篇部落格,相信你一定也可以自己實現一個簡易的scrollView。

我們首先來思考以下幾個問題:

  • scrollView繼承自誰,它如何檢測到手指滑動?
  • scrollView如何實現滾動?
  • scrollView裡的各種屬性是如何實現的?如contentSize/contentOffSet……

通過一步步解決上邊的問題,我們就能實現一個自己的scrollView。

一步一步實現scrollView

1.毫無疑問我們都知道scrollView繼承自UIView,檢測手指滑動應該是在view上放置了一個手勢識別,實現程式碼如下:

2.要搞清楚第二個問題,首先我們必須理解frame和bounds的概念。

提到它們,大家都知道frame是相對於父檢視座標系來說自己的位置和尺寸,bounds相對於自身座標系來說的位置和尺寸,並且origin一般為(0,0)。但是bounds的origin有什麼用處?改變它會出現什麼效果呢?

當我們嘗試改變bounds的origin時,我們就會發現檢視本身沒有發生變化,但是它的子檢視的位置卻發生了變化,why???其實當我們改變bounds的origin的時候,檢視本身位置沒有變化,但是由於origin的值是基於自身的座標系,所以自身座標系的位置被我們改變了。而子檢視的frame正是基於父檢視的座標系,當我們更改父檢視bounds中origin的時候子檢視的位置就發生了變化,這就是實現scrollView的關鍵點!!!

是不是很好理解?
基於這點我們很容易實現一個簡單的最初級版本的scrollView,程式碼如下:

3.理解了上邊內容的關鍵點,下邊我們將對我們實現的scrollView做一個簡單的優化。

通過contentSize限制scrollView的內部空間,實現程式碼如下

通過contentOffset設定scrollView的初始偏移量,相信大家已經懂了如何設定偏移量了吧?沒錯我們只需設定view自身bounds的origin是實現程式碼如下:

防止scrollView的子檢視超出scrollView

總結

UIScrollView還有很多其它強大的功能,以上我們只是完成了一個特別簡單的scrollView,以後如果有時間我會對它進行完善。當然如果你有興趣,你完全可以對它進行擴充套件,下載地址放在這裡。同時我也會繼續研究UIKit中其它控制元件的底層實現,歡迎您的持續關注!

相關文章