UITableViewAgent:一個閉包搞定UITableView的代理實現(xiàn)

示例程序

要運行示例項目缎玫,克隆倉庫硬纤,并首先從Example目錄運行' pod install '。

安裝與使用

UITableViewAgent可以通過CocoaPods獲得赃磨。安裝
在你的Podfile中添加以下代碼:

pod 'UITableViewAgent'

運行條件:iOS 9.0+ (Swift 5+)

UITableViewAgent可以承擔UITableViewDataSource和UITableDelegate的指責筝家,讓TableView的編碼變得更加容易和充滿樂趣。為什么要使用UITableViewAgent呢邻辉?請看下文溪王。

使用UITableViewDataSource和UITableViewDelegate實現(xiàn)TableView數(shù)據(jù)呈現(xiàn)

讓我們來看看傳統(tǒng)的TableView編碼:

  • 設置tableView的代理
tableView.dataSource = self
tableView.delegate = self    
  • 代理回調(diào)
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if section == 0 {
        return self.news.newslist?.count ?? 0
    } else if section == 1 {
        return 1
    } else {
        return 10
    }
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if indexPath.section == 0 {
        return UITableView.automaticDimension
    } else if indexPath.section == 1 {
        return 80.0
    } else {
        return 100.0
    }
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if indexPath.section == 0 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "NewsListTableViewCell", for: IndexPath) as! NewsListTableViewCell
        cell.lblTitle.text = self.news.newslist![indexPath.row].title
        cell.lblSubTitle.text = self.news.newslist![indexPath.row].source
        return cell
    } else if indexPath.section == 1 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "AppliancesTableViewCell", for: IndexPath) as! AppliancesTableViewCell.self
        cell.lblName.text = self.appliances!.name
        cell.lblColor.text = self.appliances!.color
        cell.lblPrice.text = "\(self.appliances!.price)"
        return cell
    } else {
        let cell = tableView.dequeueReusableCell(withIdentifier: "PersonTCell.self", for: IndexPath) as! PersonTCell
        cell.lblName.text = "人物 - \(indexPath.row)"
        return cell
    }
}

嗯...這里實現(xiàn)了一個多類型Cell和多種數(shù)據(jù)的TableView列表展示,這里沒有列舉出Header與Footer的復用值骇,也沒有列出Cell選中某行時的回調(diào)莹菱。
類似這樣的代碼實現(xiàn)有諸多的缺點

  • 代碼量大:實現(xiàn)簡單的功能需要大量代碼,影響開發(fā)效率雷客。
  • 靈活性差:配置數(shù)據(jù)和UI不夠靈活芒珠,多個類的復用視圖的處理需要繁瑣判斷桥狡,開發(fā)者需要自行計算索引值已經(jīng)行數(shù)等不必要的數(shù)據(jù)搅裙。
  • 可閱讀性差:為了遵守TableView的代理函數(shù),形式上寫入大量代碼裹芝,卻沒有直觀地凸顯出數(shù)據(jù)和UI部逮。

使用UITableViewAgent實現(xiàn)TableView數(shù)據(jù)呈現(xiàn)

定制Cell數(shù)據(jù)行

tableViewAgent = UITableViewAgent(tableView: tableView, display: UITableViewDisplay({ sections in
    sections.append(UITableViewSectionDisplay({ rows in
        for i in 0..<10 {
            rows.append(UITableViewRowDisplay(cellHeight: 60, cellType: UITableViewCell.self, reuseType: .anyClass) { tableView, indexPath, cell in
                cell.textLabel?.text = "row: _ \(i)"
            } didSelectRowAtIndexPath: {[weak self] tableView, indexPath, cell in
                guard let self = self else { return }
                let vc = TraditionalListViewController()
                self.navigationController?.pushViewController(vc, animated: true)
            })
        }
    }))
}))

只需要這里少許的代碼即可實現(xiàn)10行行高為50.0像素點,類型為UITableViewCell的Cell,選中某一行時嫂易,通過其中didSelectRowAtIndexPath回調(diào)方法實現(xiàn)響應的操作兄朋。
當然,功能遠遠不只這么簡單怜械,若需要比較復雜的需求颅和,它的優(yōu)勢將體現(xiàn)得更加明顯傅事。

比如:

  • Cell行數(shù)免計算靈活配置
  • 各行Cell高度靈活配置
  • 各行Cell類型與復用形式靈活配置
  • 各行Cell的數(shù)據(jù)展示靈活配置
  • 各行Cell點擊響應事件的靈活配置
// 添加一行Cell展示動物信息
rows.append(UITableViewRowDisplay(cellHeight: 100, cellType: PersonTCell.self, reuseType: .nib) { tableView, indexPath, cell in
    cell.name.text = "Panda"
    cell.country.text = "China"
} didSelectRowAtIndexPath: { tableView, indexPath, cell  in
    // 選中動物Cell后回調(diào)
    tableView.deselectRow(at: indexPath, animated: true)
    print("Animal is selected:", tableView, indexPath, cell)
})

// 添加若干行Cell展示人物信息
for (i, person) in persons.enumerated() {
    rows.append(UITableViewRowDisplay(cellHeight: 60, cellType: PersonCell.self, reuseType: .anyClass) { tableView, indexPath, cell in
        cell.numberLabel.text = "Number is: \(i)"
        cell.nameLabel.text = person.name
        cell.genderLabel.text = person.gender
    }
}

// 添加電器Cell展示電視信息
rows.append(UITableViewRowDisplay(cellHeight: 120, cellType: AppliancesTableViewCell.self, reuseType: .nib) { tableView, indexPath, cell in
    cell.lblName.text = "TV"
} didSelectRowAtIndexPath: { tableView, indexPath, cell  in
// 選中電器Cell后回調(diào)
    tableView.deselectRow(at: indexPath, animated: true)
    print("This is a TV")
})

定制數(shù)據(jù)組

下列是展示一個新聞相關(guān)的組:

// 增加新聞section, header高度45,不允許自動行高(自動行高需要Cell的約束支持峡扩,即內(nèi)容決定Cell高度)蹭越,header復用形式為XIB,類型為NewsListTableHeaderView
sections.append(UITableViewSectionDisplay(headerHeight: 45.0, isAutoHeaderHeight: false, headerReuse:.nib(NewsListTableHeaderView.self, { tabelView, section, header in
// 給header設置標題
    header.lblName.text = "News Header"
}), { rows in
    // row.append(XXX)
    // row.append(XXX)
}, footerHeight: 50.0, isAutoFooterHeight: false, footerReuse: .anyClass(NewsListTableFooterView.self, { tableView, section, footer in
// footer高度50教届,不允許自動行高响鹃,header復用形式為anyClass,類型為NewsListTableFooterView,設置文本標簽展示內(nèi)容
    footer.lblDesc.text = "News Footer"
})))

header和footer的復用參數(shù)(headerHeight和footerReuse)可以設定類型如下:

  • .anyClass: 純代碼型視圖案训,繼承自UIView买置。
  • .nib: XIB型視圖,繼承自UITableHeaderFooterView强霎。
  • .none: 不設定Header或Footer忿项。

作者

Chen Bo(陳波), cba023@hotmail.com

證書

UITableViewAgent在MIT許可下可用。查看許可文件以獲得更多信息脆栋。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末倦卖,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子椿争,更是在濱河造成了極大的恐慌怕膛,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秦踪,死亡現(xiàn)場離奇詭異褐捻,居然都是意外死亡,警方通過查閱死者的電腦和手機椅邓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門柠逞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人景馁,你說我怎么就攤上這事板壮。” “怎么了合住?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵绰精,是天一觀的道長。 經(jīng)常有香客問我透葛,道長笨使,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任僚害,我火速辦了婚禮硫椰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己靶草,他們只是感情好蹄胰,可當我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著奕翔,像睡著了一般烤送。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上糠悯,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天帮坚,我揣著相機與錄音,去河邊找鬼互艾。 笑死试和,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的纫普。 我是一名探鬼主播阅悍,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼昨稼!你這毒婦竟也來了节视?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤假栓,失蹤者是張志新(化名)和其女友劉穎寻行,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體匾荆,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡拌蜘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了牙丽。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片简卧。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖烤芦,靈堂內(nèi)的尸體忽然破棺而出举娩,到底是詐尸還是另有隱情,我是刑警寧澤构罗,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布铜涉,位于F島的核電站,受9級特大地震影響绰播,放射性物質(zhì)發(fā)生泄漏骄噪。R本人自食惡果不足惜尚困,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一蠢箩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦谬泌、人聲如沸滔韵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽陪蜻。三九已至,卻和暖如春贱鼻,著一層夾襖步出監(jiān)牢的瞬間宴卖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工邻悬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留症昏,地道東北人。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓父丰,卻偏偏與公主長得像肝谭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蛾扇,可洞房花燭夜當晚...
    茶點故事閱讀 42,828評論 2 345