创建UITableViewCell子类

UITableView 会显示一列 UITableViewCell 对象。对于大部分应用 , 基础 UITableViewCell 的 textlabel 、 detailTextlabel 和 image View 就够用了。但是,如果要显示更多内容,或者定制布局,就需要创建 UITableViewCell 子类了。
向 UITableViewCell 子类的 contentView 添加子视图,可以定制界面。

注意:不要直接向UITableViewCell 添加子视图,而要添加到 contentView 上,因为有时 UITableViewCell 会改变 contentView 的大小 。
例如:当 UITableView 进入编辑模式时,为了显示删除按钮, contentView 的大小就会改变。如果直接向 UITableViewCell 添加子视图,删除按钮就可能被挡住。进入编辑模式时, UITableViewCell 是不能调整大小的(它需要保待与 UITableView 一样宽),但是 contentView 可以改变大小。

截屏2021-11-27 22.35.36.png
  1. 创建一个叫 ItemCell 的 Swift 文件。
  2. 使用 storyboard 配置 UITableViewCell 子类。
  • 打开 Main.storyboard,在文件大纲中选择 UITableViewCell 。 打开属性检视面板,把 Style(样式) 改为 Custom(定制),然后把 Identifier(标识)改为 ltemCell 。接着,打开标识检视面板。 在 Class输入框中输入 ItemCell

  • 把 prototype cell 的高度修改为 65 点 。可以直接在画布上修改,也可以选中 prototype cell 后在尺寸检视面板中修改 Row Height(行高)。

  • 拖三个 UILabel 对象到storyboard并添加约束。

  1. 打开 ItemCell.swift,添加三个插座变量的属性并与storyboard的Label进行关联。
    注意:ItemCell 的插座变量在子类视图中。 可以打开 Main.storyboard , 按住 Control 并点击文件大纲中的 ItemCell 。
class ItemCell: UITableViewCell{
    @IBOutlet var nameLabel: UILabel!
    @IBOutlet var serialNumberLabel: UILabel!
    @IBOutlet var valueLabel: UILabel!
    }
截屏2021-11-27 22.53.45.png
  1. 在 ItemViewController 的 tableView(_: cellForRowAtIndexPath: ) 方法中, UITableView 的每行都会获得一个 ItemCell 对象。现在使用了自定义的 UITableViewCell 子类,因此 UITableView 需要知道每行的高度。有几种方法可以完成这个任务 ,最简单的是给 UITableView 的rowHeight 属性设置一个常量值。本章后面会介绍其他方法。
    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.rowHeight = 65
    }
  1. 现在已在 UITableView 中注册过 ItemCell 了(在 storyboard 的原型 Cell 中),因此可 以通过 “ ItemCell" 标识来获得 ItemCell 了 。在 ItemsViewController.swift 中修改 tableView(_: cellForRowAtIndexPath: ) ,代码如下:
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //let cell = UITableViewCell(style: .value1, reuseIdentifier: "UItableViewCell")
        //let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath)  //创建一个新的 UITableViewCell 对象或重用一个 UITableViewCell 对象
        let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! ItemCell
        
        let item = itemStore.allItems[indexPath.row]  //将 tableview 中第n行的文字设置为第n个 item 对象的名字。
//        cell.textLabel?.text = item.name
//        cell.detailTextLabel?.text = "$\(item.valueInDollars)"
        cell.nameLabel.text = item.name
        cell.serialNumberLabel.text = item.serialNumber
        cell.valueLabel.text = "$\(item.valueInDollars)"
        return cell
    }
  • 以上代码首先更新了重用标识 ,指向了新的对象,然后,在方法末尾为 ItemCell 的每个 标签设置合适的值。

动态计算Cell高度

  • 使用自动布局来完成这个任务。 ItemCell 需要一个明确决定高度的约束,但是现在 ItemCell 还没有这个约束,读者需要在两个标签之间添加一个固定间距的约束。

  • 打开 Main.storyboard 。按住 Control,从 nameLabel 拖到 serialNumberlLabel后选择 Vertical Spacing (竖直间距)

  • 下面打开 ItemsViewController.swift,更新 viewDidLoad() 方法 ,让UITableView根据约束计算 ItemCell 的高度。

  override func viewDidLoad() {
        super.viewDidLoad()
        
        //tableView.rowHeight = 65
        tableView.rowHeight = UITableView.automaticDimension
        tableView.estimatedRowHeight = 65  //设置 estimatedRowHeight 属性可以让这些计算延后,直到用户滑动 UITableView 时才去计算。
    }
  • UITableViewAutomaticDimension 是 rowHeight 属性的默认值,虽然没有必要设置, 但是加上可以让代码更容易理解。

动态类型

支持动态类型的应用会自动缩放字体。本节将会让 ItemCell 支持动态类型。

  • 打开 Main.storyboard 。下面让标签不再使用固定的字体,而是使用文字样式。选中 nameLabel 和 valuelabel 后打开属性检视面板。点击 Font(字体)右边的文字图标,在 Font 中选择 Text Styles-Body。对 serialNumber 执行相同的操作,选择 Caption 1 文字样式。

  • 编译并运行应用(无论是使用任务切换器还是 Home 键切换回应用,都不会看到刚才的修改。下一 节会修复这个问题),再向 UITableView 中添加一些 Item , 就可以看到新的小文字样式了 。

响应用户的修改

当用户改变首选字体大小回到应用时, UITableView 应该重新加载数据。很不幸,标签并不知道新选择的字体大小,需要手动更新标签来修复这个问题 。

  • 打开 ItemCell. swift, 重载 awakeFromNib()方法来让标签自适应字体大小。
    override func awakeFromNib() {
        super.awakeFromNib()
        nameLabel.adjustsFontForContentSizeCategory = true
        serialNumberLabel.adjustsFontForContentSizeCategory = true
        valueLabel.adjustsFontForContentSizeCategory = true
    }
  • 当 ItemCell 从 storyboard 文件中加载完成后,就会调用 awakeFromNib() 方法。调用这个方法时,所有插座变量都已经有值了 。

  • 编译并运行应用,然后添加一些 Item。 到设置应用中把首选字体设置为最大。与之前的不同,现在通过任务切换器或者 Home 键切换回 Homepwner,UITableView 会使用新的首选字体更新界面。

L

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容