欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Swift實現(xiàn)表格視圖單元格單選(2)

 更新時間:2022年01月26日 15:37:00   作者:Hierarch_Lee  
這篇文章主要為大家詳細介紹了Swift實現(xiàn)表格視圖單元格單選的第二篇,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了Swift實現(xiàn)表格視圖單元格單選的具體代碼,供大家參考,具體內(nèi)容如下

效果

前言

前段時間寫了一篇博客: 表格視圖單元格單選(一),實現(xiàn)起來并不復(fù)雜,簡單易懂。在實際開發(fā)中,可能會涉及到更為復(fù)雜的操作,比如多個section 下的單選,如上面展示的效果,當(dāng)我們有這樣的需求的時候,該如何實現(xiàn)呢?因為,在上篇文章中我所用的控件都是單元格自帶的imageView以及textLabel,本文我將主要分享自定義選擇按鈕以及在多個section下實現(xiàn)單選的方法。

準(zhǔn)備

界面搭建與數(shù)據(jù)顯示

這樣的界面相信對大家而言,并不難,這里我不再做詳細的講解,值得一提的是數(shù)據(jù)源的創(chuàng)建,每一組的頭部標(biāo)題,我用一個數(shù)組questions存儲,類型為:[String]?,由于每一組中,單元格內(nèi)容不一致,因此建議用字典存儲。如下所示:

var questions: [String]?
var answers: ? [String:[String]]?

如果我用字典來存儲數(shù)據(jù),那字典的鍵我應(yīng)該如何賦值呢?其實很簡單,我們只需將section的值作為key 就Ok了,這樣做的好處在于,我可以根據(jù)用戶點擊的 section來處理對應(yīng)的數(shù)據(jù),我們知道,表格視圖的section 從 0 開始,因此字典賦值可以像下面提供的代碼一樣賦值,但要注意,answers的值需與questions里面的問題一致,才能滿足實際的需求。

self.questions = ["您的性別是:",
? ? ? ? ? ? ? ? ? "您意向工作地點是:",
? ? ? ? ? ? ? ? ? "您是否參加公司內(nèi)部培訓(xùn):"]

self.answers = ["0":["男", "女"],
? ? ? ? ? ? ? ? "1":["成都", "上海", "北京", "深圳"],
? ? ? ? ? ? ? ? "2":["參加", "不參加","不確定"]]

接下來需要做的事情就是自定義單元格(UITableViewCell)了,比較簡單,直接上代碼,代碼中涉及到的圖片素材可到阿里矢量圖中下載:

import UIKit

class CustomTableViewCell: UITableViewCell {

? ? var choiceBtn: UIButton?
? ? var displayLab: UILabel?

? ? override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
? ? ? ? super.init(style: style, reuseIdentifier: reuseIdentifier)

? ? ? ? self.initializeUserInterface()

? ? }

? ? required init?(coder aDecoder: NSCoder) {
? ? ? ? fatalError("init(coder:) has not been implemented")
? ? }

? ? // MARK:Initialize methods
? ? func initializeUserInterface() {

? ? ? ? self.choiceBtn = {
? ? ? ? ? ? let choiceBtn = UIButton(type: UIButtonType.Custom)
? ? ? ? ? ? choiceBtn.bounds = CGRectMake(0, 0, 30, 30)
? ? ? ? ? ? choiceBtn.center = CGPointMake(20, 22)
? ? ? ? ? ? choiceBtn.setBackgroundImage(UIImage(named: "iconfont-select.png"), forState: UIControlState.Normal)
? ? ? ? ? ? choiceBtn.setBackgroundImage(UIImage(named: "iconfont-selected.png"), forState: UIControlState.Selected)
? ? ? ? ? ? choiceBtn.addTarget(self, action: Selector("respondsToButton:"), forControlEvents: UIControlEvents.TouchUpInside)
? ? ? ? ? ? return choiceBtn
? ? ? ? ? ? }()
? ? ? ? self.contentView.addSubview(self.choiceBtn!)

? ? ? ? self.displayLab = {
? ? ? ? ? ? let displayLab = UILabel()
? ? ? ? ? ? displayLab.bounds = CGRectMake(0, 0, 100, 30)
? ? ? ? ? ? displayLab.center = CGPointMake(CGRectGetMaxX(self.choiceBtn!.frame) + 60, CGRectGetMidY(self.choiceBtn!.frame))
? ? ? ? ? ? displayLab.textAlignment = NSTextAlignment.Left
? ? ? ? ? ? return displayLab
? ? ? ? ? ? }()
? ? ? ? self.contentView.addSubview(self.displayLab!)

? ? }

? ? // MARK:Events
? ? func respondsToButton(sender: UIButton) {

? ? }
}

表格視圖數(shù)據(jù)源與代理的實現(xiàn),如下所示:

// MARK:UITableViewDataSource && UITableViewDelegate

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
? ? // 直接返回 answers 鍵值對個數(shù)即可,也可返回 questions 個數(shù);
? ? return (self.answers!.count)
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

? ? // 根據(jù) section 獲取對應(yīng)的 key
? ? let key = "\(section)"
? ? // 根據(jù) key 獲取對應(yīng)的數(shù)據(jù)(數(shù)組)
? ? let answers = self.answers![key]
? ? // 直接返回數(shù)據(jù)條數(shù),就是需要的行數(shù)
? ? return answers!.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
? ? var cell: CustomTableViewCell? = tableView.dequeueReusableCellWithIdentifier("cell") as? CustomTableViewCell

? ? if cell == nil {
? ? ? ? cell = CustomTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
? ? }

? ? let key = "\(indexPath.section)"
? ? let answers = self.answers![key]


? ? cell!.selectionStyle = UITableViewCellSelectionStyle.None

? ? return cell!
}

func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
? ? return 40
}

func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
? ? return self.questions![section]
}

實現(xiàn)

技術(shù)點:在這里我主要會用到閉包回調(diào),在自定義的單元格中,用戶點擊按鈕觸發(fā)方法時,閉包函數(shù)會被調(diào)用,并將用戶點擊的單元格的indexPath進行傳遞,然后根據(jù)indexPath進行處理,具體的實現(xiàn)方式,下面會慢慢講到,閉包類似于Objective-C中的Block,有興趣的朋友可深入了解Swift中的閉包使用。

首先,我們需要在CustomTableViewCell.swift文件中,聲明一個閉包類型:

typealias IndexPathClosure = (indexPath: NSIndexPath) ->Void

其次,聲明一個閉包屬性:

var indexPathClosure: IndexPathClosure?

現(xiàn)在,要做的事情就是聲明一個閉包函數(shù)了,閉包函數(shù)主要用于在ViewController.swift文件中調(diào)用并且將需要傳遞的數(shù)據(jù)傳遞到ViewController.swift文件中。

func getIndexWithClosure(closure: IndexPathClosure?) {
? ? ? ? self.indexPathClosure = closure
? ? }

閉包函數(shù)已經(jīng)有了,那么何時調(diào)用閉包函數(shù)呢?當(dāng)用戶點擊單元格的時候,閉包函數(shù)會被調(diào)用,因此,我們只需要到選擇按鈕觸發(fā)方法中去處理邏輯就好了,在觸發(fā)方法中,我們需要將單元格的indexPath屬性傳遞出去,但是,UITableViewCell并無indexPath屬性,那應(yīng)該怎么辦呢?我們可以為它創(chuàng)建一個indexPath屬性,在配置表格視圖協(xié)議方法cellForRowAtIndexPath:時,我們賦值單元格的indexPath屬性就OK了。

var indexPath: NSIndexPath?
func respondsToButton(sender: UIButton) {
? ? sender.selected = true
? ? if self.indexPathClosure != nil {
? ? ? ? self.indexPathClosure!(indexPath: self.indexPath!)
? ? }
}

現(xiàn)在在CustomTableViewCell.swift文件里面的操作就差不多了,但是,還缺少一步,我還需要定制一個方法,用于設(shè)置按鈕的狀態(tài):

func setChecked(checked: Bool) {

? ? self.choiceBtn?.selected = checked

}

到了這一步,我們要做的事情就是切換到ViewController.swift文件中,找到表格視圖協(xié)議方法cellForRowAtIndexPath:,主要的邏輯就在這個方法中處理,首先我們需要做的事情就是賦值自定義單元格的indexPath屬性:

cell?.indexPath = indexPath

其次,我需要在ViewController.swift文件中,聲明一個selectedIndexPath屬性用于記錄用戶當(dāng)前選中的單元格位置:

var selectedIndexPath: NSIndexPath?

接下來我會去做一個操作,判斷協(xié)議方法參數(shù)indexPath.row,是否與selectedIndexPath.row一致,如果一致,則設(shè)為選中,否則設(shè)為未選中,這里可用三目運算符:

self.selectedIndexPath?.row == indexPath.row ? cell?.setChecked(true) : cell?.setChecked(false)

這里大家可能會有疑問,那就是為什么只判斷row呢?不用判斷section嗎?當(dāng)然不用,因為在刷新表格視圖的時候我并沒有調(diào)用reloadData方法,而是指定刷新某一組(section)就可以了,如果全部刷新,則無法保留上一組用戶選擇的信息,這將不是我們所需要的。

接下來,將是最后一步,調(diào)用回調(diào)方法,該方法會在每一次用戶點擊單元格的時候調(diào)用,并且返回用戶當(dāng)前點擊的單元格的indexPath,在這里,我們需要將返回的indexPath賦值給selectedIndexPath屬性。并且刷新指定section就OK了,代碼如下:

cell!.getIndexWithClosure { (indexPath) -> Void in

? ? self.selectedIndexPath = indexPath
? ? print("您選擇的答案是:\(answers![indexPath.row])")

? ? tableView.reloadSections(NSIndexSet(index: self.selectedIndexPath!.section), withRowAnimation: UITableViewRowAnimation.Automatic) ??
}

完整代碼

可能大家還比較模糊,這里我將貼上完整的代碼供大家參考

ViewController.swift文件

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{

? ? var tableView: UITableView?
? ? var questions: [String]?
? ? var answers: [String:[String]]?


? ? var selectedIndexPath: NSIndexPath?

? ? override func viewDidLoad() {
? ? ? ? super.viewDidLoad()
? ? ? ? self.initializeDatasource()
? ? ? ? self.initializeUserInterface()
? ? ? ? // Do any additional setup after loading the view, typically from a nib.
? ? }

? ? // MARK:Initialize methods
? ? func initializeDatasource() {
? ? ? ? self.questions = ["您的性別是:", "您意向工作地點是:", "您是否參加公司內(nèi)部培訓(xùn):"]

? ? ? ? self.answers = ["0":["男", "女"],
? ? ? ? ? ? ? ? ? ? ? ? "1":["成都", "上海", "北京", "深圳"],
? ? ? ? ? ? ? ? ? ? ? ? "2":["參加","不參加","不確定"]]

? ? }

? ? func initializeUserInterface() {
? ? ? ? self.title = "多組單選"
? ? ? ? self.automaticallyAdjustsScrollViewInsets = false

? ? ? ? // table view
? ? ? ? self.tableView = {
? ? ? ? ? ? let tableView = UITableView(frame: CGRectMake(0, 64, CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds)), style: UITableViewStyle.Grouped)
? ? ? ? ? ? tableView.dataSource = self
? ? ? ? ? ? tableView.delegate = self
? ? ? ? ? ? return tableView
? ? ? ? ? ? }()
? ? ? ? self.view.addSubview(self.tableView!)

? ? }

? ? // MARK:UITableViewDataSource && UITableViewDelegate

? ? func numberOfSectionsInTableView(tableView: UITableView) -> Int {
? ? ? ? return (self.answers!.count)
? ? }

? ? func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

? ? ? ? let key = "\(section)"
? ? ? ? let answers = self.answers![key]
? ? ? ? return answers!.count
? ? }

? ? func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
? ? ? ? var cell: CustomTableViewCell? = tableView.dequeueReusableCellWithIdentifier("cell") as? CustomTableViewCell

? ? ? ? if cell == nil {
? ? ? ? ? ? cell = CustomTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
? ? ? ? }

? ? ? ? cell?.indexPath = indexPath

? ? ? ? let key = "\(indexPath.section)"
? ? ? ? let answers = self.answers![key]

? ? ? ? self.selectedIndexPath?.row == indexPath.row ? cell?.setChecked(true) : cell?.setChecked(false)

? ? ? ? cell!.getIndexWithClosure { (indexPath) -> Void in

? ? ? ? ? ? self.selectedIndexPath = indexPath

? ? ? ? ? ? print("您選擇的答案是:\(answers![indexPath.row])")

? ? ? ? ? ? tableView.reloadSections(NSIndexSet(index: self.selectedIndexPath!.section), withRowAnimation: UITableViewRowAnimation.Automatic)

? ? ? ? }

? ? ? ? cell!.displayLab?.text = answers![indexPath.row]
? ? ? ? cell!.selectionStyle = UITableViewCellSelectionStyle.None

? ? ? ? return cell!
? ? }

? ? func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
? ? ? ? return 40
? ? }

? ? func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
? ? ? ? return self.questions![section]
? ? }

}

CustomTableViewCell.swift文件

import UIKit

typealias IndexPathClosure = (indexPath: NSIndexPath) ->Void

class CustomTableViewCell: UITableViewCell {

? ? var choiceBtn: UIButton?
? ? var displayLab: UILabel?

? ? var indexPath: NSIndexPath?

? ? var indexPathClosure: IndexPathClosure?

? ? override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
? ? ? ? super.init(style: style, reuseIdentifier: reuseIdentifier)

? ? ? ? self.initializeUserInterface()

? ? }

? ? required init?(coder aDecoder: NSCoder) {
? ? ? ? fatalError("init(coder:) has not been implemented")
? ? }

? ? // MARK:Initialize methods
? ? func initializeUserInterface() {

? ? ? ? self.choiceBtn = {
? ? ? ? ? ? let choiceBtn = UIButton(type: UIButtonType.Custom)
? ? ? ? ? ? choiceBtn.bounds = CGRectMake(0, 0, 30, 30)
? ? ? ? ? ? choiceBtn.center = CGPointMake(20, 22)
? ? ? ? ? ? choiceBtn.setBackgroundImage(UIImage(named: "iconfont-select"), forState: UIControlState.Normal)
? ? ? ? ? ? choiceBtn.setBackgroundImage(UIImage(named: "iconfont-selected"), forState: UIControlState.Selected)
? ? ? ? ? ? choiceBtn.addTarget(self, action: Selector("respondsToButton:"), forControlEvents: UIControlEvents.TouchUpInside)
? ? ? ? ? ? return choiceBtn
? ? ? ? ? ? }()
? ? ? ? self.contentView.addSubview(self.choiceBtn!)

? ? ? ? self.displayLab = {
? ? ? ? ? ? let displayLab = UILabel()
? ? ? ? ? ? displayLab.bounds = CGRectMake(0, 0, 100, 30)
? ? ? ? ? ? displayLab.center = CGPointMake(CGRectGetMaxX(self.choiceBtn!.frame) + 60, CGRectGetMidY(self.choiceBtn!.frame))
? ? ? ? ? ? displayLab.textAlignment = NSTextAlignment.Left
? ? ? ? ? ? return displayLab
? ? ? ? ? ? }()
? ? ? ? self.contentView.addSubview(self.displayLab!)

? ? }

? ? // MARK:Events
? ? func respondsToButton(sender: UIButton) {
? ? ? ? sender.selected = true
? ? ? ? if self.indexPathClosure != nil {
? ? ? ? ? ? self.indexPathClosure!(indexPath: self.indexPath!)
? ? ? ? }
? ? }


? ? // MARK:Private
? ? func setChecked(checked: Bool) {

? ? ? ? self.choiceBtn?.selected = checked

? ? }

? ? func getIndexWithClosure(closure: IndexPathClosure?) {
? ? ? ? self.indexPathClosure = closure
? ? }
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • RxSwift發(fā)送及訂閱 Subjects、Variables代碼示例

    RxSwift發(fā)送及訂閱 Subjects、Variables代碼示例

    這篇文章主要介紹了RxSwift發(fā)送及訂閱 Subjects、Variables代碼示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-12-12
  • swift 字符串String的使用方法

    swift 字符串String的使用方法

    這篇文章主要介紹了swift 字符串String的使用方法的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • 分析Swift性能高效的原因

    分析Swift性能高效的原因

    絕大多數(shù)公司選擇Swift語言開發(fā)iOS應(yīng)用,主要原因是因為Swift相比Objc有更快的運行效率,更加安全的類型檢測,更多現(xiàn)代語言的特性提升開發(fā)效率;這一系列的優(yōu)點使Swift語言的熱度越來越高。
    2020-10-10
  • Swift方法調(diào)度之類的普通方法底層探究

    Swift方法調(diào)度之類的普通方法底層探究

    這篇文章主要介紹了Swift-方法調(diào)度-類的普通方法底層探究,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-11-11
  • Swift能代替Objective-C嗎?

    Swift能代替Objective-C嗎?

    這是我在網(wǎng)上上看到的答案,復(fù)制粘貼過來和大家分享一下,因為我和很多人一樣很關(guān)心Swift的出現(xiàn)對Mac開發(fā)的影響和對Objective-C的影響。
    2014-09-09
  • Swift中的常量和變量簡單概述

    Swift中的常量和變量簡單概述

    這篇文章主要介紹了Swift中的常量和變量簡單概述的相關(guān)資料,非常具有參考借鑒價值,感興趣的朋友一起學(xué)習(xí)吧
    2016-05-05
  • Swift與C語言指針結(jié)合使用實例

    Swift與C語言指針結(jié)合使用實例

    這篇文章主要介紹了Swift與C語言指針結(jié)合使用實例,本文講解了用以輸入/輸出的參數(shù)指針、作為數(shù)組使用的參數(shù)指針、用作字符串參數(shù)的指針、指針參數(shù)轉(zhuǎn)換的安全性等內(nèi)容,需要的朋友可以參考下
    2015-05-05
  • Swift Access Control訪問控制與斷言詳細介紹

    Swift Access Control訪問控制與斷言詳細介紹

    這篇文章主要介紹了Swift Access Control訪問控制與斷言,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-09-09
  • swift版webview加載網(wǎng)頁進度條效果

    swift版webview加載網(wǎng)頁進度條效果

    這篇文章主要為大家詳細介紹了swift實現(xiàn)webview加載網(wǎng)頁進度條效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • Swift教程之集合類型詳解

    Swift教程之集合類型詳解

    這篇文章主要介紹了Swift教程之集合類型詳解,Swift 提供兩種集合類型來存儲集合,數(shù)組和字典,本文詳細講解了數(shù)組的創(chuàng)建、讀取和修改數(shù)組、遍歷數(shù)組以及集合的操作等內(nèi)容,需要的朋友可以參考下
    2015-01-01

最新評論