我正在尝试研究如何编辑我添加到UITableView单元格中的子视图的标签。这是代码:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
var cellTitleLabel = UILabel(frame: CGRect(x: 45,y: 2,width: 100,height: 20))
cellTitleLabel.textAlignment = NSTextAlignment.left
cellTitleLabel.text = "Title"
cellTitleLabel.font = UIFont(name: "Swiss721BT-Roman", size: 16)
cell.addSubview(cellTitleLabel)
return cell
}
现在我希望能够将字符串从“标题”更改为任何内容,但似乎我可以更新该文本的唯一方法是删除子视图,然后添加一个带有更新参数的新视图。是不可能做这样的事情:
cell.cellTitleLabel.text = "New Title"
谢谢,非常感谢任何帮助!
答案 0 :(得分:0)
每次调用cellForRowAt indexPath:
时都会调用tableView.reloadData()
函数。
尝试将标签文本设置为变量并刷新表格。 所以......
cellTitleLabel.text = "Title"
到
cellTitleLabel.text = myVar
然后更新myVar
并重新加载tableView
数据。
如果它是一个非常大的表,您可以通过仅刷新该行或节来节省资源。
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Top)
答案 1 :(得分:0)
我看到的问题是,当您加载单元格时,您正在创建UILabel
作为单元格的子视图,但您没有保留对该标签的任何引用。因此,单元格在初始化后不再具有任何名为cellTitleLabel
的属性。
我建议创建一个自定义的UITableViewCell
子类,如下所示:
import UIKit
class CustomTableViewCell: UITableViewCell {
var cellTitleLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization Code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func setCellContent(text: String) {
let cellTitleLabel = UILabel(frame: CGRect(x: 45,y: 2,width: 100,height: 20))
cellTitleLabel.textAlignment = NSTextAlignment.left
cellTitleLabel.text = text
cellTitleLabel.font = UIFont(name: "Swiss721BT-Roman", size: 16)
self.addSubview(cellTitleLabel)
self.cellTitleLabel = cellTitleLabel
}
}
然后在设置时调用cellForRowAtIndexPath
,您可以实例化自定义单元格
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomTableViewCell") as! CustomTableViewCell
cell.setCellContent(text: "Cell Title")
return cell
}
然后你有一个充满CustomTableViewCell
子类的表作为它的单元格,每个单元格都有一个名为UILabel
的{{1}}属性,您可以根据需要进行更改。
编辑: - 我忘了添加使用重用标识符注册单元格的部分。创建tableView时,请确保添加:
cellTitleLabel
答案 2 :(得分:0)
嗯,问题是,您的解决方案在多个级别上都是错误的。 Pierce的解决方案虽然被更好地分解,但也是错误的。
您看,问题是,每次出列单元格时都会添加新的子视图,但是您永远不会从层次结构中删除子视图。这意味着您有多个子视图堆叠在另一个子视图之上。
其次,你绝对应该使用自动布局,因为你的手机在不同的设备上看起来不太好。
第三,当你开始改变某些事情时,使用强制广播是失败的一种简短方法。不惜一切代价避免使用它们,而是使用纯可选代替。
最后,但并非最不重要,我建议使用Interface Builder来创建视图布局和层次结构。
至于解决方案,如果你创建了以下形式的单元子类,你的解决方案会好得多:
class CustomTableViewCell: UITableViewCell {
var titleLabel: UILabel? {
didSet {
titleLabel.map { self.addSubview($0) }
oldValue?.removeFromSuperview()
}
}
override func awakeFromNib() {
super.awakeFromNib()
let label = UILabel(frame: CGRect(x: 45,y: 2,width: 100,height: 20))
label.textAlignment = NSTextAlignment.left
label.font = UIFont(name: "Swiss721BT-Roman", size: 16)
self.titleLabel = label
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 100
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if let cell = cell as? CustomTableViewCell {
cell.titleLabel?.text = "Title"
}
return cell
}
}
但是,为了进一步改进,我建议使用IDPCastable cocoapod
之类的东西它允许您在没有强制转换的情况下简化匹配:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
return match(cell) { (c: CustomTableViewCell) in
c.titleLabel?.text = "Title"
}
}
而且,让我再次强调,界面构建器是可行的方法,自动布局是绝对必须的。
答案 3 :(得分:0)
1)你的问题是你总是在每次通话时向小区添加新的protocol
。您可以在3D Debug视图中看到越来越多的UILabel堆叠
2)你应该只在单元格的init中创建一次子视图和标签
3)我在表格中显示了多种类型的单元格。我创建了一个protocol UpdateableTableViewCell {
func configCell(with data:MyTableDataModel)
}
来将一个单元格的内部实现与调用tableViewController分离。现在您可以自由创建不同的单元格,每个单元格负责正确布局和更新内容:
class MyTinyTableViewCell: UITableViewCell, UpdateableTableViewCell {
let cellTitleLabel = UILabel()
//[...]
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setup()
}
func setup() {
cellTitleLabel.frame = : CGRect(x: 45,y: 2,width: 100,height: 20))
cellTitleLabel.textAlignment = NSTextAlignment.left
cellTitleLabel.font = UIFont(name: "Swiss721BT-Roman", size: 16)
self.contenView.addSubview(cellTitleLabel)
}
// implement protocol UpdateableTableViewCell
func configCell(with data:MyTableDataModel){
resetCell()
cellTitleLabel.text = data.description
}
///[...]
func resetCell(){
// reset here all other cell ui elements to default values
}
}
现在我所有不同的单元格都实现了这个协议:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellData:MyTableDataModel = myDataArray(indexPath.row)
// calculate the celltype depending on the current data in the cell
let cellTypeIdentifier = getCellTypeIdentifier(cellData)
if let cell = tableView.dequeueReusableCell(withIdentifier: cellTypeIdentifier, for: indexPath) as UpdateableTableViewCell {
cell.configCell(with: cellData)
}
}
现在我可以一步重用不同的细胞:
tableView.register(MyTinyTableViewCell.self, forCellReuseIdentifier: "tinyCell")
tableView.register(MyBigTableViewCell.self, forCellReuseIdentifier: "bigCell")
tableView.register(MyImageTableViewCell.self, forCellReuseIdentifier: "imageCell")
并且不要忘记在tableView上注册所有单元格:
protocol MyTableDataModel {
let description:String { get }
let title:String { get }
let imageUrl:String { get }
}
4)为了使其更加灵活,您还可以抽象数据模型和协议,以便您可以为您的单元格使用不同的模型。
type: book
book:
title: Dune
author: Frank Herbert
copyright: ${book.author} 1965
protaganist: ${characters.0.name}
media:
- hardcover
characters:
- name: Paul Atreides
occupation: Kwisatz Haderach
aliases:
- Usul
- Muad'Dib
- The Preacher
- name: Duncan Idaho
occupation: Swordmaster
summary: ${book.title} by ${book.author}
product-name: ${${type}.title}