零行程式碼為 App 新增異常載入佔點陣圖

發表於2016-12-13

前文提要

近期準備重構專案,需要重寫一些通用模組,正巧需要設定App異常載入佔點陣圖的問題,心血來潮設想是否可以零行程式碼解決此問題,特在此分享實現思路。

思路分享

對於App佔點陣圖,通常需要考慮的控制元件有tableView、collectionView和webView,異常載入情況區分為無資料和網路異常等。

既然要實現零程式碼形式,因此就不能繼承原始類重寫或新增方法等方式,而是通過對對應控制元件新增類別(分類)來實現。

簡單來說,以tableView為例實現思路為每當tableView呼叫reloadData進行重新整理時,檢測此時tableView行數,若行數不為零,正常顯示資料。若行數為零,說明無資料顯示佔點陣圖。

新增佔點陣圖的方式有很多種,例如藉助tableView的backgroundView或直接以addSubView的方式新增,這裡採用的為addSubView方式,儘量避免原生屬性的佔用。

對於檢測tableView資料是否為空,藉助tableView的代理dataSource即可。核心程式碼如下,依次獲取tableView所具有的組數與行數,通過isEmpty這個flag標示最後確定是否新增佔點陣圖。

相應的對於CollectionView亦可通過numberOfSectionsInCollectionView:collectionView:numberOfItemsInSection獲取其組數和行數,這裡就不一一贅述。

需要注意的為webView佔點陣圖是否顯示的判斷,一種情況為webView呼叫其webView: didFailLoadWithError:方法,第二種為webView完成載入顯示為空的情況。但存在的一個問題是,webView沒有必選的協議方法,或可能根本沒有設定代理。因此無法很好的判斷webView是否響應其協議方法。因此該demo暫時沒有新增webView的佔點陣圖,如果有好的想法可以評論指出。

接下來說最重要的一步,如何實現零行程式碼新增佔點陣圖呢?

其實實現思路非常簡單,如果可以讓tableView在執行reloadData時自動檢測其行數就可以了。也就是我們需要在reloadData原有方法的基礎上新增checkEmpty此方法。

這裡又能體現到Runtime Method Swizzling的作用了,我們可以通過Method Swizzling替換reloadData方法,給予它新的實現。核心程式碼如下:

這樣就可以實現reloadData的同時檢測行數從而判斷是否顯示佔點陣圖的功能。
這裡採用了上篇文章《Runtime Method Swizzling開發例項彙總》的程式碼用例類NSObject+Swizzling.h,因此該篇文章也算上篇文章的延續,為Runtime Method Swizzling的另一種用例。感興趣的朋友可以前往閱讀更多的實用用例。

為實現零程式碼的效果,程式碼中已新增了placeholder檢視的預設樣式,如圖所示:

111767950-359ca5b4d9ce8452
佔點陣圖樣式

若要實現效果圖中點選圖示重新重新整理效果,需要讓tableView呼叫reloadBlock,因為資料的重新整理大多是不同的,所以具體重新整理執行程式碼還是需要自己手動設定的。若不需要,則無需新增此操作。

如果需要自定製佔位檢視樣式也非常簡單,因佔點陣圖樣式比較統一,所以可直接修改SurePlaceholderView佔點陣圖類以達到自己想要的效果,再而在UITableView+Sure_Placeholder.hUICollectionView+Sure_Placeholder.hUIWebView+Sure_Placeholder.h類別中均外漏了placeholderView屬性,將其賦值為新的檢視亦可。

以tableView為例,可以通過如下方式進行修改

同樣的對於無資料與無網路的效果切換,也可以通過網路是否可用的標示來進行展示不同的佔點陣圖。例如

為方便大家閱讀和修改,demo已上傳github。

下載連結如下:
零行程式碼為App新增無資料佔點陣圖?

既然為零程式碼,因此使用方法將Sure_Placeholder資料夾拖入工程即可。有任何問題大家可以評論指出。

參考連結:
《一行程式碼完成“空TableView佔位檢視”管理》

相關文章