iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >Swift实现表格视图单元格单选(2)
  • 403
分享到

Swift实现表格视图单元格单选(2)

2024-04-02 19:04:59 403人浏览 泡泡鱼
摘要

本文实例为大家分享了Swift实现表格视图单元格单选的具体代码,供大家参考,具体内容如下 效果 前言 前段时间写了一篇博客: 表格视图单元格单选(一),实现起来并不复杂,简单易懂。

本文实例为大家分享了Swift实现表格视图单元格单选的具体代码,供大家参考,具体内容如下

效果

前言

前段时间写了一篇博客: 表格视图单元格单选(一),实现起来并不复杂,简单易懂。在实际开发中,可能会涉及到更为复杂的操作,比如多个section 下的单选,如上面展示的效果,当我们有这样的需求的时候,该如何实现呢?因为,在上篇文章中我所用的控件都是单元格自带的imageView以及textLabel,本文我将主要分享自定义选择按钮以及在多个section下实现单选的方法。

准备

界面搭建与数据显示

这样的界面相信对大家而言,并不难,这里我不再做详细的讲解,值得一提的是数据源的创建,每一组的头部标题,我用一个数组questions存储,类型为:[String]?,由于每一组中,单元格内容不一致,因此建议用字典存储。如下所示:

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

如果我用字典来存储数据,那字典的键我应该如何赋值呢?其实很简单,我们只需将section的值作为key 就Ok了,这样做的好处在于,我可以根据用户点击的 section来处理对应的数据,我们知道,表格视图的section 从 0 开始,因此字典赋值可以像下面提供的代码一样赋值,但要注意,answers的值需与questions里面的问题一致,才能满足实际的需求。

self.questions = ["您的性别是:",
                  "您意向工作地点是:",
                  "您是否参加公司内部培训:"]

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) {

    }
}

表格视图数据源与代理的实现,如下所示:

// 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]
}

实现

技术点:在这里我主要会用到闭包回调,在自定义的单元格中,用户点击按钮触发方法时,闭包函数会被调用,并将用户点击的单元格的indexPath进行传递,然后根据indexPath进行处理,具体的实现方式,下面会慢慢讲到,闭包类似于Objective-C中的Block,有兴趣的朋友可深入了解Swift中的闭包使用。

首先,我们需要在CustomTableViewCell.swift文件中,声明一个闭包类型:

typealias IndexPathClosure = (indexPath: NSIndexPath) ->Void

其次,声明一个闭包属性:

var indexPathClosure: IndexPathClosure?

现在,要做的事情就是声明一个闭包函数了,闭包函数主要用于在ViewController.swift文件中调用并且将需要传递的数据传递到ViewController.swift文件中。

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

闭包函数已经有了,那么何时调用闭包函数呢?当用户点击单元格的时候,闭包函数会被调用,因此,我们只需要到选择按钮触发方法中去处理逻辑就好了,在触发方法中,我们需要将单元格的indexPath属性传递出去,但是,UITableViewCell并无indexPath属性,那应该怎么办呢?我们可以为它创建一个indexPath属性,在配置表格视图协议方法cellForRowAtIndexPath:时,我们赋值单元格的indexPath属性就OK了。

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

现在在CustomTableViewCell.swift文件里面的操作就差不多了,但是,还缺少一步,我还需要定制一个方法,用于设置按钮的状态:

func setChecked(checked: Bool) {

    self.choiceBtn?.selected = checked

}

到了这一步,我们要做的事情就是切换到ViewController.swift文件中,找到表格视图协议方法cellForRowAtIndexPath:,主要的逻辑就在这个方法中处理,首先我们需要做的事情就是赋值自定义单元格的indexPath属性:

cell?.indexPath = indexPath

其次,我需要在ViewController.swift文件中,声明一个selectedIndexPath属性用于记录用户当前选中的单元格位置:

var selectedIndexPath: NSIndexPath?

接下来我会去做一个操作,判断协议方法参数indexPath.row,是否与selectedIndexPath.row一致,如果一致,则设为选中,否则设为未选中,这里可用三目运算符:

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

这里大家可能会有疑问,那就是为什么只判断row呢?不用判断section吗?当然不用,因为在刷新表格视图的时候我并没有调用reloadData方法,而是指定刷新某一组(section)就可以了,如果全部刷新,则无法保留上一组用户选择的信息,这将不是我们所需要的。

接下来,将是最后一步,调用回调方法,该方法会在每一次用户点击单元格的时候调用,并且返回用户当前点击的单元格的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 = ["您的性别是:", "您意向工作地点是:", "您是否参加公司内部培训:"]

        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
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: Swift实现表格视图单元格单选(2)

本文链接: https://www.lsjlt.com/news/163866.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Swift实现表格视图单元格单选(2)
    本文实例为大家分享了Swift实现表格视图单元格单选的具体代码,供大家参考,具体内容如下 效果 前言 前段时间写了一篇博客: 表格视图单元格单选(一),实现起来并不复杂,简单易懂。...
    99+
    2024-04-02
  • Swift实现表格视图单元格单选(1)
    本文实例为大家分享了Swift实现表格视图单元格单选的具体代码,供大家参考,具体内容如下 效果展示 前言 最近一个朋友问我,如何实现表格视图的单选?因为我之前用Objective-...
    99+
    2024-04-02
  • Swift实现表格视图单元格多选
    本文实例为大家分享了Swift实现表格视图单元格多选的具体代码,供大家参考,具体内容如下 效果 前言 这段时间比较忙,没太多的时间写博客,前段时间写了一些关于表格视图单选的文章,想...
    99+
    2024-04-02
  • Swift使用表格组件实现单列表
    本文实例为大家分享了Swift使用表格组件实现单列表的具体代码,供大家参考,具体内容如下 1、样例说明: (1)列表内容从Controls.plist文件中读取,类型为Array 。...
    99+
    2024-04-02
  • Vue+Element实现表格单元格编辑
    前言 Element的表格组件并没有给出明确的点击单个单元格进行的编辑的方案,我仔细阅读了官方的文档后,发现这个操作还是可以实现的。 实现原理 1、利用Table组件的cell-cl...
    99+
    2024-04-02
  • css如何实现表格单元格等宽
    这篇文章将为大家详细讲解有关css如何实现表格单元格等宽,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。表格单元格等宽表格工作起来很麻烦,所以务必尽量使用 table-layout: fixed 来保持单元...
    99+
    2023-06-05
  • css如何实现等宽表格单元格
    这篇文章给大家分享的是有关css如何实现等宽表格单元格的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。等宽表格单元格表格可能很难处理,所以尝试使用table-layout:fixed来保持单元格相等宽度:.cale...
    99+
    2023-06-27
  • Swift如何使用表格组件实现单列表
    本篇文章给大家分享的是有关Swift如何使用表格组件实现单列表,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1、样例说明:(1)列表内容从Controls.plist文件中读取...
    99+
    2023-06-29
  • css表格的单元格不换行怎么实现
    本教程操作环境:Windows10系统、CSS3版、DELL G3电脑css表格的单元格不换行怎么实现?css表格文字不换行设置:很多时候,我们在项目开发中会出现,单元格内容由于太多导致的换行问题,让表格显得非常的丑陋。下面我们来看一下使用...
    99+
    2023-05-14
    css 单元格
  • element-ui表格如何实现单元格可编辑
    这篇文章主要介绍element-ui表格如何实现单元格可编辑,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!如下所示:<template>  <el-tab...
    99+
    2024-04-02
  • css表格的单元格不换行如何实现
    本文小编为大家详细介绍“css表格的单元格不换行如何实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“css表格的单元格不换行如何实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。css表格的单元格不换行的实现...
    99+
    2023-07-05
  • C#实现拆分合并Word表格中的单元格
    目录程序环境在Word表格中合并单元格完整代码效果图在Word表格中拆分单元格完整代码效果图我们在使用Word制作表格时,由于表格较为复杂,只是简单的插入行、列并不能满足我们的需要。...
    99+
    2022-12-22
    C#拆分合并Word表格单元格 C#拆分单元格 C#合并单元格
  • Python——openpyxl读取Excel表格(读取、单元格修改、单元格加底色)
    🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手 🏳️‍🌈 博客主页:一晌小贪欢的博客主页 👍 ...
    99+
    2023-10-26
    python excel 开发语言 python办公自动化 自动化
  • 【PHPWord】PHPWord动态生成表格table | 单元格横向合并、单元格纵向合并、单元格边框样式、单元格垂直水平居中
    目录 一、前言 二、生成表格 1.生成基础表格 2.表格样式 1.表格样式 ...
    99+
    2023-10-04
    php html 前端
  • vue 表格单选按钮的实现方式
    目录vue实现表格单选按钮表格中有两个单选按钮切换互不影响项目场景问题描述原因分析解决方案vue实现表格单选按钮 return{ orderNo:'', columns: [ ...
    99+
    2024-04-02
  • element table 表格控件实现单选功能
    项目中实现 table 表格控件单选功能,如图: 基本代码如下: 1、template 代码中: <el-table :data="tableData" bo...
    99+
    2024-04-02
  • antdvue表格可编辑单元格以及求和实现方式
    目录antd vue表格可编辑单元格以及求和实现antd vue 表格可编辑问题总结antd vue表格可编辑单元格以及求和实现 1、参照官网根据自己需要添加可编辑单元格组件 新建E...
    99+
    2023-05-17
    antd vue表格可编辑单元格 antd vue表格求和 antd vue表格可编辑
  • 手机excel表格单元格怎么合并
    本篇内容介绍了“手机excel表格单元格怎么合并”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!手机excel表格合并单元格的方法:首先我们选...
    99+
    2023-07-02
  • 普通填报表单元格如何实现数据二次筛选
    这期内容当中小编将会给大家带来有关普通填报表单元格如何实现数据二次筛选,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。问题:普通浏览式报表可以这样 =employee.select(编号, 部门 ==“综合...
    99+
    2023-06-03
  • wps合并单元格内容都保留在一个单元格怎么实现
    这篇文章主要讲解了“wps合并单元格内容都保留在一个单元格怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“wps合并单元格内容都保留在一个单元格怎么实现”吧!wps合并单元格内容都保留...
    99+
    2023-07-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作