如何在Swift中设置UITableViewCellStyleSubtitle和dequeueReusableCell?

时间:2014-06-05 14:01:20

标签: ios uitableview swift

我喜欢使用UITableView的{​​{1}}个subtitle个样式的单元格。

我原来的Objective-C代码是:

dequeueReusableCellWithIdentifier

在SO上搜索了几个static NSString* reuseIdentifier = @"Cell"; UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; if(!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier]; } 问题之后,我想在Swift中写这样的话:

UITableView

但这并不能说我想要 tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "Cell") let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell 风格。所以我尝试了这个:

subtitle

这给了我一个var cell :UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Cell") 单元格,但它不允许我subtitle

我已经研究了一些并查看了this video tutorial,但他创建了一个单独的dequeueReusableCellWithIdentifier subclass,我认为这是不必要的,因为我之前在Obj中完成了同样的效果-C。

有什么想法吗?感谢。

12 个答案:

答案 0 :(得分:65)

请记住,UITableView在函数中被定义为可选,这意味着您的初始单元格声明需要检查属性中的可选项。此外,返回的排队单元格也是可选的,因此请确保对UITableViewCell进行可选的强制转换。之后,我们可以强制解包,因为我们知道我们有一个单元格。

var cell:UITableViewCell? = 
tableView?.dequeueReusableCellWithIdentifier(reuseIdentifier) as? UITableViewCell
if (cell == nil)
{
   cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, 
                reuseIdentifier: reuseIdentifier)
}
// At this point, we definitely have a cell -- either dequeued or newly created,
// so let's force unwrap the optional into a UITableViewCell
cell!.detailTextLabel.text = "some text"

return cell

答案 1 :(得分:19)

基本上和其他答案一样,但我通过使用计算变量处理讨厌的选项(你不能从Swift中的nil返回-tableView:cellForRow:atIndexPath:):

Swift 3

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell: UITableViewCell = {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell") else {
            // Never fails:
            return UITableViewCell(style: UITableViewCellStyle.value1, reuseIdentifier: "UITableViewCell")
        }
        return cell
    }()

    // (cell is non-optional; no need to use ?. or !)

    // Configure your cell:
    cell.textLabel?.text       = "Key"
    cell.detailTextLabel?.text = "Value"

    return cell
}

修改

实际上,最好使用:tableView.dequeueReusableCell(withIdentifier:for:)来取消单元格。

如果没有人可以重用(这正​​是我的代码在上面明确指出的那个),该函数的后来变体会自动实例化一个新单元格,因此 never 返回nil

答案 2 :(得分:16)

如果你宁愿避免选择性,你可以创建一个UITableViewCell的子类,如下所示:

class SubtitleTableViewCell: UITableViewCell {

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

然后使用以下方式注册:

override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.register(SubtitleTableViewCell.self, forCellReuseIdentifier: reuseIdentifier)
}

这使您的单元格自定义代码非常好:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath)

    cell.textLabel?.text = "foo"
    cell.detailTextLabel?.text = "bar"

    return cell
}

答案 3 :(得分:10)

建立在记忆之上'通过清理Swift 2风格来回答......

let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) ?? UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: reuseIdentifier)

cell.detailTextLabel?.text = "some text"

return cell

斯威夫特3:

let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) ?? UITableViewCell(style: .subtitle, reuseIdentifier: cellIdentifier)

cell.detailTextLabel?.text = ""

return cell

答案 4 :(得分:5)

select * from users order by firstname ASC

答案 5 :(得分:3)

由于tableView.dequeueReusableCell(withIdentifier:, for:)返回非零单元格,if cell == nil检查始终为false。 但是我找到了一个解决方案,让默认样式单元格成为你想要的样式(value1,value2或subtitle),因为默认样式单元格detailTextLabel为零,所以检查detailTextLabel是否为&{ #39; s nil,然后创建新的样式单元格,并将其输出到单元格,如:

斯威夫特3:

var cell = tableView.dequeueReusableCell(withIdentifier: yourCellReuseIdentifier, for: indexPath)

if cell.detailTextLabel == nil {
    cell = UITableViewCell(style: .value1, reuseIdentifier: repeatCellReuseIdentifier)
}

cell.textLabel?.text = "Title"
cell.detailTextLabel?.text = "Detail"

return cell

这对我有用。

希望有所帮助。

答案 6 :(得分:2)

您可以使用与memmons略有不同的语法来防止强制解包:

let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) as? UITableViewCell ?? UITableViewCell(style: .Subtitle, 
            reuseIdentifier: reuseIdentifier)

cell.detailTextLabel?.text = "some text"

return cell

这是使用XCode 6.1 7,Swift 1.2 2.0语法,其中UITableView不再是可选的。

答案 7 :(得分:1)

如果您没有使用自己的自定义单元格。只需通过代码注册UITableViewCell即可。然后你可以选择代码。

另外选择故事板,选择你的TableViewCell - >转到属性检查器并选择所需的样式,如下所示。

enter image description here

答案 8 :(得分:0)

完全按照Michael G. Emmons的建议,但在Xcode 6.1中使用

if !cell { .....

我收到此错误:

  

可选类型' @ |值UITableViewCell?'不能用作布尔值;   测试'!= nil'代替

接受的语法是:

if cell == nil { ...

答案 9 :(得分:0)

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{

    var cell:UITableViewCell? =
        tableView.dequeueReusableCell(withIdentifier: "cell")
    if (cell != nil)
    {
        cell = UITableViewCell(style: UITableViewCellStyle.subtitle,
                               reuseIdentifier: "cell")
    }
    cell!.textLabel?.text = "ABC"
    cell!.detailTextLabel?.text = "XYZ"

    return cell!

  }

答案 10 :(得分:0)

确保您没有在表格视图中注册任何单元格。

如果这样做,dequeueReusableCellWithIdentifier将始终提供非可选单元格,因此UITableViewCellStyle.Subtitle将永远不会启动。

答案 11 :(得分:-1)

我邀请您在Github上查看这个小UITableView示例:https://github.com/YANGReal/UITableView-Swift

他们喜欢以下内容:

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
{
   let cell = tableView .dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
   cell.textLabel.text = String(format: "%i", indexPath.row+1)
   // set any other property of your cell here
   return cell
}