Xcode -(Swift版)Storyboard教程 1.5:使用原型单元格的子类
引言
1 - 经过前三节的探究,这个表视图用起来已经相当不错了,但我不大喜欢用 tag 来获取原型单元格的子视图。如果可能的话,把这些 label 于 outlet 连接并使用相应属性要优雅得多。事实是可行的
详细操作
1 - 在项目中以 Cocoa Touch Class 模板添加一个新文件,命名为 PlayerCell 并令其继承 UITableViewCell。不要选中创建 XIB 的选项,因为Storyboard里已经有表项了。在 PlayerCell 类的类定义下面添加以下属性
1 @IBOutlet weak var gameLabel: UILabel! 2 @IBOutlet weak var nameLabel: UILabel! 3 @IBOutlet weak var ratingImageView: UIImageView!
说明:这些变量都是 IBOutlet,它们可以在 Storyboard 中与场景建立连接
2 - 回到 Main.storyboard,选中原型表项 PlayerCell,并在身份检查器中把它的 class 改成 PlayerCell。现在每当通过 dequeueReusableCell 向表视图请求一个新表项时,它会返回 PlayerCell 实例而不是 UITableViewCell
注: - 这里我们把类名跟重用标识符设置成一样了,都是 PlayerCell。这只是因为个人喜欢保持一致,类名跟重用标识符毫不相干,如果你愿意,也可以起不同的名字
3 - 下面令 label 以及 image view 与 outlet 连接。在 Storyboard 中切到连接检查器(Connections inspector),然后在面板或文档大纲中选择 Player Cell,把连接检查器中的 nameLabel outlet 拖到 Name label 对象上。对gameLabel 和 ratingImageView执行同样操作
注: - 控件要连接的是表项,而不是视图控制器!当你的数据源向表视图通过 dequeueReusableCell 索求一个新表项的时候,表视图并不是把原型表项交给你,而是复制一份给你(或是之前被纳入回收空间的一个已有表项)
- 这就意味着在同一时间不止有一个 PlayerCell 的实例,如果把表项中的 label 连接到了视图控制器的 outlet 上,不同的 label 拷贝会试图使用同一个 outlet,这是自找麻烦。(另一方面,把原型表项连接到视图控制器的action上是可行的,当你的表项中含有自定义按钮或者是其他 UIControl 时可能会用到)
- 除使用连接检查器之外,你也可以按住 control 从 PlayerCell 拖到控件上,然后在弹出的选单中选择 outlet 名称
4 - 现在已经绑定属性,可以稍微简化数据源的代码。在 PlayersViewController 中如下修改 tableView(_:cellForRowAtIndexPath:)方法
1 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 2 3 let cell = tableView.dequeueReusableCell(withIdentifier: "PlayerCell", for: indexPath) 4 as! PlayerCell 5 6 let player = players[indexPath.row] as Player 7 cell.nameLabel.text = player.name 8 cell.gameLabel.text = player.game 9 cell.ratingImageView.image = imageForRating(rating: player.rating) 10 return cell 11 }
5 - 这就更像样了。把从 dequeueReusableCell 接收的对象转为一个 PlayerCell,然后就可以使用连接到 label 和图片视图的属性。这样使用原型表项,表视图不像以前那么乱了。运行 App 试试看,看起来应该和之前一样,但在幕后,现在使用的已经是你自己的单元格子类了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)