Swift:表格视图单元格单选(二)
效果前言前段时间写了一篇博客: 表格视图单元格单选(一),实现起来并不复杂,简单易懂。在实际开发中,可能会涉及到更为复杂的操作,比如多个 准备界面搭建与数据显示 这样的界面相信对大家而言,并不难,这里我不再做详细的讲解,值得一提的是数据源的创建,每一组的头部标题,我用一个数组 var questions: [String]?
var answers: [String:[String]]?
如果我用字典来存储数据,那字典的键我应该如何赋值呢?其实很简单,我们只需将 self.questions = ["您的性别是:","您意向工作地点是:","您是否参加公司内部培训:"]
self.answers = ["0":["男","女"],"1":["成都","上海","北京","深圳"],"2":["参加","不参加","不确定"]]
接下来需要做的事情就是自定义单元格( 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,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) {
}
}
表格视图数据源与代理的实现,如下所示: // MARK:UITableViewDataSource && UITableViewDelegate
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// 直接返回 answers 键值对个数即可,也可返回 questions 个数;
return (self.answers!.count)
}
func tableView(tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
// 根据 section 获取对应的 key
let key = "(section)"
// 根据 key 获取对应的数据(数组)
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")
}
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]
}
实现技术点:在这里我主要会用到闭包回调,在自定义的单元格中,用户点击按钮触发方法时,闭包函数会被调用,并将用户点击的单元格的 首先,我们需要在 typealias IndexPathClosure = (indexPath: NSIndexPath) ->Void
其次,声明一个闭包属性: var indexPathClosure: IndexPathClosure?
现在,要做的事情就是声明一个闭包函数了,闭包函数主要用于在 func getIndexWithClosure(closure: IndexPathClosure?) { self.indexPathClosure = closure }
闭包函数已经有了,那么何时调用闭包函数呢?当用户点击单元格的时候,闭包函数会被调用,因此,我们只需要到选择按钮触发方法中去处理逻辑就好了,在触发方法中,我们需要将单元格的 var indexPath: NSIndexPath?
func respondsToButton(sender: UIButton) {
sender.selected = true
if self.indexPathClosure != nil {
self.indexPathClosure!(indexPath: self.indexPath!)
}
}
现在在 func setChecked(checked: Bool) {
self.choiceBtn?.selected = checked
}
到了这一步,我们要做的事情就是切换到 cell?.indexPath = indexPath
其次,我需要在 var selectedIndexPath: NSIndexPath?
接下来我会去做一个操作,判断协议方法参数 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)
}
完整代码可能大家还比较模糊,这里我将贴上完整的代码供大家参考 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 = ["您的性别是:","您是否参加公司内部培训:"]
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,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,forControlEvents: UIControlEvents.TouchUpInside)
return choiceBtn
}()
self.contentView.addSubview(self.choiceBtn!)
self.displayLab = {
let displayLab = UILabel()
displayLab.bounds = CGRectMake(0,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
}
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |