優雅的使用UITableView
痛點
在我們iOS開發中
UITableView
幾乎是所有App都會使用的一個UI控制元件,因為業務的需要,我們常常會註冊多種Cell,然後在
中就會很自然的寫出一堆類似這樣的程式碼:
事件處理的程式碼大概是這樣的:
這似乎沒有什麼問題,程式碼很乾淨,邏輯也比較清晰。
但是你維護幾個版本之後,或者遇到了一個 善變的產品經理。
你會發現,這樣的程式碼維護起來真的很危險,稍微一不注意就出錯了,這裡用的
type
作為判斷條件可能相較與
indexPath
要好一點。
如果使用
indexPath
作為判斷條件,如果你的cell順序有變化,或者有改動,那麼你可能至少需要維護以下幾個地方:
- 你的模型陣列
- cell dequeue的判斷條件
- 事件處理的判斷條件
- 。。。。
維護的東西越多,意味著你出錯的機率是越大的。
那有沒有什麼好的方法處理這類程式碼?
分析
其實我們仔細想想,無論一個多麼複雜的
UITableView
,與之對應的其實只要一個
模型陣列。
那麼我們如果維護好了
模型陣列,是不是就維護好了
UITableView
中所有的cell,這是顯而易見的。
如果我們的
UITableView
中有
N種cell樣式,那麼
模型陣列中肯定也會有
N種模型。
也就是說每種cell與每種模型是一一配對的,常規的模型與cell繫結是如上述的思路。
上述的思路,顯然不是我們想要的,維護起來太不便,而且耦合性也比較大。
想一想展示一個
UITableView
的過程
- 發起網路請求
- JSON to Model,構造 模型陣列
- 資料填充
大致就是這三步吧。
其實在第二步構造 模型陣列時,我們是不是就可以確定好UI的樣式了?
如果這裡想不明白,再看看我們上面的分析,一種 cell樣式對應著一種 模型,那麼我們知道了 模型,是不是就知道了 cell樣式
如果你還是不大清楚,那們就進入實戰部分
實戰
先看這樣一個簡單的頁面,你肯定會說:朋友,你TM在逗我們,這和
UITableView
有毛關係?
這個介面需要
UITableView
?
沒錯,這個介面在
UIViewController
中直接構建就可以了。
請再看下面
是不是感覺都很類似,但是又有很多不同的地方。
方案
- 一個一個VC的寫。
缺點:
有很多重複程式碼,而且後期的改動需要維護的地方,做不到高內聚。
-
抽象一個父類
缺點:
雖然三個VC看似UI上有很多共同之處,但是其中的業務處理完全不同的
-
抽象一個 UIHelper用於構建UI
缺點:
這種方案看似很好了,但是你看如果在一個介面中,如果新增一個或者減少一個控制元件,又得重新做約束了,這也顯然不是我們想要的。
下面看看透過
UITableView
構建的UI
展示
SignInVC 中的程式碼:
PasswordSignVC 中的程式碼:
再看cell的dequeue程式碼
資料的繫結,全部分散到了每個cell中。
Row.h的程式碼
Row.m的程式碼
整個
Row的程式碼不過100行,把所有的處理都內聚在了一起,我們只要維護好模型陣列就能很好的管理
UITableView
UI是構建完成了,但是我相信其中有兩個問題你肯定比較關心
- Cell 高度計算
- Cell上事件的回撥
Cell 高度計算
在iOS8之後
UITableView
中推出了Self-sizing的功能,所以Cell的高度改變
如果你對這塊不熟悉,請 跳轉。如果你想對Auto Layout有一個提高建議看看 Auto Layout Guide, 如果你想知道
systemLayoutSizeFittingSize
的作用,請看 深入理解Auto Layout 第一彈
Cell上事件的回撥
有人肯定會不屑這裡,但是我想說:如果不用 block、 代理、 觀察者。
怎麼把cell上button的事件回撥到VC中(button沒有暴露給外部)?
我們先看新增Action的方法
這裡需要這三個引數:
- target(action的相應者)
- action(點選按鈕相應的方法)
- controlEvents(這個一般為UIControlEventTouchUpInside)
只要我們找到了 target,把 action寫到 target裡這個action繫結是不是就完成了。
target其實就是我們的VC,我們只要把VC傳遞給Cell即可,但是這樣是不是Cell又和VC耦合了啊。這個用block,delegate沒什麼區別吧!
現在我們需要解決的問題就是找到Cell的VC,大功即可告成。
這是就需要一個重要的概念閃亮登場iOS 響應鏈(Responder Chain)
這裡就不展開了,但是你一定要去了解這個。
響應鏈可以解決的問題:
- 擴大相應區域
- 超出父類檢視相應依然可以傳遞
- 垮圖層傳遞事件
找到
UIView
的
UIViewController
ButtonCell事件繫結程式碼:
這裡我們還是要用一個協議的:
注意
用這個協議主要是方便程式碼的閱讀,而且在Swift中是必須使用協議的,因為編譯時找不到這個方法。
可以看到ButtonCell的程式碼中並沒有這樣一段程式碼
或者
這樣我們的ButtonCell不會和VC耦合,修改起來真的很方便
尾巴
以上思路大概就介紹完了,這只是Detail部分,List部分我會在demo中給出
關於Detail和List的概念我會在第三節中介紹,第二節是Swift版的思路,Swift可以用到泛型,程式碼更優雅。
Demo
推薦?:
如果你想一起進階,不妨新增一下交流群 1012951431
面試題資料或者相關學習資料都在群檔案中 進群即可下載!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69971523/viewspace-2690586/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 優雅的使用UITableView(Swift 中)UIViewSwift
- 優雅的使用UITableView(OC 上)UIView
- 如何優雅的對UITableView進行解耦UIView解耦
- 如何優雅地動態插入資料到UITableViewUIView
- 如何優雅的使用介面
- 如何優雅的使用MyBatis?MyBatis
- UITableView優化UIView優化
- 如何優雅的使用Mock ServerMockServer
- Laravel如何優雅的使用SwooleLaravel
- 如何優雅使用 vuexVue
- UItableView效能優化UIView優化
- Java 如何優雅的使用註解Java
- React中如何優雅的使用UEditorReact
- 優雅的在 react 中使用 TypeScriptReactTypeScript
- 優雅的使用路由模型繫結路由模型
- Yii 中優雅的使用事件事件
- 優雅的在vue中使用TypeScriptVueTypeScript
- iOS中優雅的使用iconfontiOS
- Swift中安全優雅的使用UserDefaultsSwift
- 不使用@Value的優雅寫法
- 如何優雅地使用 macOSMac
- 如何優雅地使用 GitGit
- Swift iOS: UITableView的使用SwiftiOSUIView
- MacOS下如何優雅的使用冰蠍Mac
- 如何優雅的使用執行緒池執行緒
- 更優雅的在 mpvue 中使用 canvasVueCanvas
- 優雅的使用 Brew 切換 Go 版本Go
- 使用 Alfred 在 markdown 中優雅的使用圖片Alfred
- 優雅通過HttpClientFactory使用HttpClientHTTPclient
- Linux 優雅使用哲學Linux
- 優雅的PromiseKitPromise
- UITableView優化那點事UIView優化
- iOS中UITableView效能優化iOSUIView優化
- 如何優雅的搞垮伺服器,再優雅的救活伺服器
- Flutter如何優雅的使用typedef回撥方法Flutter
- 如何使用Git 優雅的版本回退呢?Git
- 幾個優雅的JavaScript運算子使用技巧JavaScript
- 如何優雅的設計和使用快取?快取