最近爲公司項目中添加自動加載更多功能,因而將公司裏下拉刷新和加載更多功能單獨抽出來,放在UITableView的category中,能夠作到無侵入添加這些功能,使得不少老代碼只須要幾句代碼,便可實現這些功能。具體代碼及使用方法:UITableView+PullData,其實實現邏輯很簡單,基本看完代碼就能徹底理解,可是在實現的時候,遇到了一些問題,下面內容主要講講我是如何去解決這些問題的。git
首先,公司以前代碼就實現了下拉刷新和上拉加載更多功能,是經過繼承基類UITableView,在子類中添加屬性enablePullDataRefresh、enablePullDataLoadMore、pullDataDelegate、pullDataTableViewIsRefreshing、pullDataTableViewIsLoadingMore及代理方法去實現,具體的實現和個人代碼基本一致,用子類的方式不是很優雅,每一個想實現這個功能都須要用子類建立實例。若是用category的方式,就能夠作到徹底不用改變原有代碼,只須要設置tableview的屬性值,就能夠實現功能,這裏用的老思路,也沒有遇到大問題,只有一些小問題,簡單優化了下。github
主要的坑在自動加載更多上,自動加載更多就是在滑動UI TableView的時候,當快到底部時,提早本身去發起加載後面數據的請求並添加到數據源上,讓用戶沒有感知的狀況加載了新數據。post
能夠想到要提早加載數據,何時發起請求呢?經過什麼方式去獲取條件是否知足呢?預加載與智能預加載(iOS)這篇博客講了一種Threshold方式,能夠經過Threshold值來肯定觸發條件,由scrollViewDidScroll去獲取條件。因而很快就實現了自動加載功能,可是會有一個問題,每一個想實現自動加載更多功能,都須要實現UITableView的scrollViewDidScroll代理方法,連代理方法裏的代碼都幾乎同樣,這樣的實現方式不是太好看。優化
既然把觸發自動加載更多的條件及監測方式放在UITableView的代理上,不是很好,換個方式實現吧。scrollViewDidScroll代理方法都會伴隨着contentOffset發生變化,咱們能夠經過監聽contentOffset的值來判斷條件是否成立,當條件知足的時候讓tableView加載更多數據,天然會想到用KVO觀察contentOffset的值發生變化,而後一系列判斷是否知足條件。爲了無侵入的設置自動加載更多,讓tableview本身觀察本身的contentOffset,當loadMoreStyle = TableViewLoadMoreStyleAuto時添加KVO觀察,loadMoreStyle = TableViewLoadMoreStyleDefault時移除KVO觀察。那麼問題就來了,若是子類tableView本身也使用KVO會致使父類裏的不執行,好吧,我想到若是要繼承UITableView,就須要在+(void)load裏去hook這個- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context方法,我用宏定義去幫助如何去hook,只須要在繼承的時候寫上方法+ (void)load {AutoLoadMoreMacro};,問題好像是解決了,可是問題又來了,大神說KVO不能夠屢次移除觀察者等問題,若是我屢次設置loadMoreStyle = TableViewLoadMoreStyleDefault就會出現問題,不得已又放棄KVO這種方式。線程
既然知道contentOffset值會變,KVO觀察不能夠,索性直接hook setContentOffset方法,在裏面去判斷是否知足自動加載更多條件,判斷條件就是經過contentOffset.y和contentSize.height值作比較,當差值小到一個值,去執行加載更多,這樣基本實現了自動加載,終於能夠舒口氣了,可是又發現一個問題,每次加載的時候都會觸發兩次,檢查各個條件都是正確的,setContentOffset也是主線程裏執行,懷疑可能setContentOffset裏contentOffset.y和contentSize.height值作比較這種方式會有抖動,因而又要換個方式,直接拿數據源比較吧,tableView能夠獲取numberOfRowInSection,還有indexPathsForVisibleRows屬性,能夠經過比較可見的row和總row值比較來肯定觸發條件,可是這麼作,只能讓tableview只有一個section。代理
以上就是我作自動加載更多遇到的問題,但願你們能夠多多交流,發現一些不足,以及給予一些更好的實現方式。繼承