打造輕量級 tableViewController 之抽離 DataSource/Delegate
前言
UITableView/UICollectionView 是我們開發中使用最為頻繁的兩個控制元件。關於其使用的實踐網上已經有很多優秀的總結了,所以我不打算再囉嗦了。今天要討論的問題基於 objc.io 的一遍文章 Lighter View Controllers,此文講述如何通過抽取頻繁出現的配置型別的程式碼到專門的一個 DataSource/Delegate 裡面來為 Controller 瘦身。我們從中受到了啟發,由於文中給出的 demo 不具有通用性,所以打算寫一個比較全面的封裝來組織 DataSource/Delegate 的程式碼。
我們先看一下平時都是怎麼使用 UITableView 的,一般我們需要做這樣幾件事:
-
註冊需要使用的 cell 的樣式到 UITableView
-
實現 UITableViewDataSource 的幾個方法來告訴 UITableView 什麼地方怎麼如何顯示 cell
-
實現 UITableViewDelegate 來告訴 UITableView 具體每個 cell 的高度,以及處理點選事件等
一般情況大致做的就這些。通常的做法就是直接設定當前 controller 為 tableView 的資料來源和事件回撥委託。這樣會造成很多 controller 有大致一致的程式碼。經驗告訴我們,大面積出現類似的程式碼就可以考慮把這些程式碼抽取出來封裝成一個更加通用的組織形式了。也就是我們要做的事情,其實就是對 UITableViewDataSource 和 UITableViewDelegate 的進一步拆分和封裝。
思考一下我們看到的 tableView 都包含哪些部分,展示了哪些元素。從 Apple 提供的 API 中我們可以看出大致包含 tableViewHeader/tableViewFooter,SectionHeaderView/SectionFooterView,SectionHeaderTitle/SectionFooterTitle,sectionIndex 以及最重要的 Cell。如果我們把這些東西都對映成為一個數據型別,然後直接讓 tableView 去取對應的部分資料然後渲染到介面上不就好了麼,每個頁面我們就不再關心如何去實現 UITableViewDataSource/UITableViewDelegate ,只需要告知必要的資訊,其餘重複性極高的事情就交給封裝的程式碼來做了,就像在配置介面一樣,真正實現「你們做 iOS 的不就是把服務端的資料顯示在介面上就好了麼」。
廢話了這麼多,直接上我們的解決方案吧!原始碼已經放到 GitHub 上了。下面主要說一下怎麼用。
https://github.com/cuzv/TinyCoordinator
程式碼組織
程式碼主要分為以下幾部分:
-
TCDataSourceProtocol: 對 UITableView 和 UICollectionView 按照介面劃分為幾個配置不同介面的模組,實現者根據需求實現各自的協議,來 “配置” 介面。
-
TCDataSource:DataSource 的基類,所有 UITableView 和 UICollectionView 的資料來源的基類,其中已經預設實現了重複率高的程式碼,其實就是對 UITableViewDataSource/UICollectionViewDataSource 的實現。還實現了 UITableview 的 Move/Edit 操作的輔助方法。UICollectionView的 Move 操作輔助方法等。
-
TCDelegate:Delegate 的基類,所有 UITableView 和 UICollectionView 的委託的基類,其中實現了與 UIScrollView 相關的一部分功能,比如 Cell的圖片懶載入。為子類實現一些輔助方法,比如基於 Autolayout 自動計算 Cell/SectionHeaderView/SectionFooterView 行高的輔助方法。
-
TCSectionDataMetric:UITableView/UICollectionView 各個分組的元件的資料封裝。包含 SectionHeaderView/SectionFooterView, SectionHeaderTitle/SectionFooterTitle 以及 Cell 等的資料。
-
TCGlobalDataMetric:對整個 UITableView/UICollectionView 各個元件的資料的封裝。其作為一個容器,裡面包含若干個 TCSectionDataMetric。
基本使用
下面直接以我工作的通用樣板來說明如何使用,一個場景的檔案目錄大致像這樣:
-
ProductViewController(基於 UITableView)
-
ProductViewModel(採用 RAC 來處理網路層邏輯)
-
ProductDataSource
-
ProductDelegate
-
Views
-
Model
基於這樣的架構,Controller 檔案程式碼一般保持在 200 到 300 行之間,其他檔案行數則更少。這樣一來程式碼清晰了,邏輯自然也比較容易釐清,修改功能也容易多了。至於維護那種開啟檔案一看就是上千行程式碼的情況,我的內心是崩潰的。
言歸正傳,來看一下相關類中的關鍵程式碼是怎樣的?
ProductViewController 中,初始化 DataSource 和 Delegate 並關聯到 tableView。
lazyvardataSource:ProductDataSource = {
ProductDataSource(tableView:self.tableView)
}()
lazyvardelegate:ProductDelegate = {
ProductDelegate(tableView:self.tableView)
}()
lazyvartableView:UITableView = {
lettableView = UITableView(frame:CGRectZero,style:.Plain)
...
returntableView
}()
lazyvarviewModel:ProductViewModel = {
ProductViewModel()
}()
override func viewDidLoad(){
super.viewDidLoad()
tableView.delegate = delegate
tableView.dataSource = dataSource
}
internal func methodTakeParamters<T,U>(paramterOne:T,paramterTwo:U){
navigationController.showViewController(vc,sender:self)
}
ProductDataSource 需要繼承自 TCDataSource。
finalclassShopSettingDataSource:TCDataSource{
}
/// 配置能夠顯示基本的 cell 需要的資訊
extensionShopSettingDataSource:TCDataSourceable{
/// 註冊 Cell 樣式到 tableView
func registerReusableCell(){
tableView?.registerClass(Cell1.self,forCellReuseIdentifier:Cell1.reuseIdentifier)
tableView?.registerClass(Cell2.self,forCellReuseIdentifier:Cell2.reuseIdentifier
相關推薦
打造輕量級 tableViewController 之抽離 DataSource/Delegate
前言 UITableView/UICollectionView 是我們開發中使用最為頻繁的兩個控制元件。關於其使用的實踐網上已經有很多優秀的總結了,所以我不打算再囉嗦了。今天要討論的問題基於 objc.io 的一遍文章 Lighter View Contro
webpack + vue之抽離css方法
大部分使用過webpack的朋友都知道,抽離css需要使用到webpack的外掛extract-text-webpack-plugin,vue也不例外。官方給的vue-loader的文件裡面有這樣的描述 module: { rules: [
小程式開發之檔案作用域(全域性變數)與模組化(utils抽離工具類)
檔案作用域 在 JavaScript 檔案中宣告的變數和函式只在該檔案中有效;不同的檔案中可以宣告相同名字的變數和函式,不會互相影響。 通過全域性函式 getApp() 可以獲取全域性的應用例項,如果需要全域性的資料可以在 App() 中設定, 例如: glob
Android源代碼之DeskClock (三) Proxy/Delegate Application 框架應用
源代碼 sna 還記得 java cep info avi 配置文件 cit 一.概述 當項目有加殼子,插件化或熱修復等需求的時候,能夠使用Proxy/Delegate Application框架的方式,在正常的模式中,一個程序一般僅僅有一個Appl
基於Mono和VSCode打造輕量級跨平臺IDE
ring linux ++ req ati args .html 有一個 asc ??近期Visual Studio推出Mac版本號的消息迅速在技術圈裏刷屏,當project師們最喜歡的筆記本電腦Mac,邂逅地球上最強大的集成開發環境Visual Stu
騰訊副總裁姚星:騰訊AI Lab將致力打造通往AGI之路
騰訊 AI 背景:3月15日,騰訊AI Lab第二屆學術論壇在深圳舉行,聚焦人工智能在醫療、遊戲、多媒體內容、人機交互等四大領域的跨界研究與應用。全球30位頂級AI專家出席,對多項前沿研究成果進行了深入探討與交流。今天,騰訊副總裁姚星在騰訊AI Lab主辦的第二屆學術論壇上表示,AI Lab未來將致力
爬取校園新聞首頁的新聞的詳情,使用正則表達式,函數抽離
嘗試 htm des script its etc 新聞 ttr sid 1. 用requests庫和BeautifulSoup庫,爬取校園新聞首頁新聞的標題、鏈接、正文、show-info。 2. 分析info字符串,獲取每篇新聞的發布時間,作者,來源,攝影等信息。 3.
使用正則表達式,取得點擊次數,函數抽離
fin imp 公網 bsp 表達式 detail col clas 學院 學會使用正則表達式 1. 用正則表達式判定郵箱是否輸入正確。 r = ‘(/w)+([\.\_\-]\w+)*@(\w)+((\.\w{2,3}){1,3})$‘ e = ‘62360887
PHP方便快捷的將二維數組中元素的某一列值抽離出來作為此二維數組內元素的key
列表 TP ech name 成績 img user 函數 emp 得益於PHP的強大的內置數組函數array_column();array_combine(); 舉個小栗子: <?php // 先查詢出用戶的基本信息 $userArray = [[‘id‘ =&g
asp.net core 2.1 將控制器抽離到類庫中
cat start service public 網站 類庫 class all app startup.cs的ConfigureServices中添加: public void ConfigureServices(IServiceCollection
javaweb閑暇小程序之抽簽程序
var pen ansi 數組 clear click encoding 圖片 and 學自潭州學院視頻 主程序頁面截圖 1 <%@ page language="java" contentType="text/html; charset=U
vue+element+axios+axios攔截+ajax請求抽離+less專案搭建
vue init webpack vue-pc cnpm i cnpm i element-ui -D cnpm install babel-plugin-component -D //按需引入 src/main.js import './conf
element抽離
src/main.js //按需匯入element import './config/element'; src/config/element.js import Vue from 'vue' import { Button, Select } fr
基於Vue-Cli 打包自動生成/抽離相關配置檔案
背景 基於Vue-cli 專案產品部署,涉及到的互動的地址等配置資訊,每次都要重新打包才能生效,極大的降低了效率。我們的目的是讓專案實施的小夥伴重新快樂起來。網上實現的方式,都是半自動化的,還需要重新修改。 需求點 配置化:打包後的配置檔案可二次修改 配置自動生成:vue-cli 提
樣式的層級關係,選擇器優先順序,樣式衝突,以及抽離樣式模組怎麼寫,說出思路,有無實踐經驗
1、樣式的層級關係:一個是權重,另一個就是共用樣式和私用樣式了,比如說兩個ul,它們的子元素除了背景色之外都一樣,那可以直接用li {}來定義相同的公用樣式,用 .ul_1 li {} , .ul_2 li {} 來定義不相同的樣式。可以根據元素之間的差別來選擇用哪種方法
Machine Learning 之 LOF離群點檢驗
#coding=utf-8 #本質是基於密度的檢測 缺點:計算量巨大 #優化 重複點計算 import math print sorted([1,3,2])[:1],[1,3,2][1:] class
C++純手工打造COM:COM之來龍去脈——元件如何被建立
本文意旨幫助初涉COM的學者能對COM元件的建立過程有一個清晰的瞭解。全文以《COM技術內幕》第7章的示例程式碼為藍本,稍做修改之後進行詳細介紹。如果你也閱讀過此書的相關內容,那麼理解起來將會更容易。 《COM技術內幕》這本書的示例程式碼編寫於1996年。時至今
webpack4 單獨抽離打包 css 的新實現
webpack4 單獨抽離打包 css 的新實現 前言 之前我們使用的打包 css 無非兩種方式:① 將 css 程式碼打包進 入口 js 檔案中;② 使用第三方外掛(extract-text-webpack-plugin)實現【注意,該外掛在 webpack4 中已經不推薦使用,而且會出現各種莫名其
RequireJS入門指南(二)-vue分頁模組抽離
vue實現分頁,模組化實現的碎碎念。 這篇講一下我是如何在專案中抽離出分頁模組的。 這段時間做的專案讓我很頭疼,因為前面寫程式碼的時候沒有考慮很多東西,寫到後面就發現程式碼越來越重。 而且在不同頁
vuex的使用、抽離非同步元件(一)
安裝好腳手架服務跑起來後,在src下新建vuex資料夾,vuex資料夾下新建js檔案並配置:我命名為index.js:import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); const store =