Swift中的UITableView

DBo*_*yer 60 uitableview swift ios8

我正在努力弄清楚这段代码的错误.这目前在Objective-C中工作,但在Swift中,这只是在方法的第一行崩溃.它在控制台日志中显示错误消息:Bad_Instruction.

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!  {
        var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell

        if (cell == nil) {
            cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "Cell")
        }

        cell.textLabel.text = "TEXT"
        cell.detailTextLabel.text = "DETAIL TEXT"

        return cell
    }
Run Code Online (Sandbox Code Playgroud)

Sul*_*han 82

另请参阅matt的答案,其中包含解决方案的后半部分

让我们找到一个解决方案,而无需创建自定义子类或nib

真正的问题在于Swift区分了可以为empty(nil)的对象和不能为空的对象.如果您没有为标识符注册nib,则dequeueReusableCellWithIdentifier可以返回nil.

这意味着我们必须将变量声明为可选:

var cell : UITableViewCell?
Run Code Online (Sandbox Code Playgroud)

我们必须使用as?不投射as

//variable type is inferred
var cell = tableView.dequeueReusableCellWithIdentifier("CELL") as? UITableViewCell

if cell == nil {
    cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "CELL")
}

// we know that cell is not empty now so we use ! to force unwrapping but you could also define cell as
// let cell = (tableView.dequeue... as? UITableViewCell) ?? UITableViewCell(style: ...)

cell!.textLabel.text = "Baking Soda"
cell!.detailTextLabel.text = "1/2 cup"

cell!.textLabel.text = "Hello World"

return cell
Run Code Online (Sandbox Code Playgroud)


mat*_*att 63

Sulthan的答案很聪明,但真正的解决方案是:不要打电话dequeueReusableCellWithIdentifier.这是你一开始的错误.

这种方法已经过时了,我很惊讶它还没有被正式弃用; 没有任何可以容纳Swift(iOS 7或iOS 8)的系统无论出于何种目的都需要它.

相反,称之为现代方法dequeueReusableCellWithIdentifier:forIndexPath:.这样做的优点是不涉及任何选项 ; 保证您将返回一个单元格.所有的问号和惊叹号都会消失,你可以使用let而不是var因为细胞的存在得到保证,而你生活在一个方便,现代的世界里.

如果您不使用故事板,则必须事先在表中注册此标识符,注册类或笔尖.传统的做法是viewDidLoad,早在桌面视图中就存在了.

以下是使用自定义单元类的示例:

override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.registerClass(MyCell.self, forCellReuseIdentifier: "Cell")
}

// ...

override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath:indexPath) as MyCell
    // no "if" - the cell is guaranteed to exist
    // ... do stuff to the cell here ...
    cell.textLabel.text = // ... whatever
    // ...
    return cell
}
Run Code Online (Sandbox Code Playgroud)

但是如果你正在使用故事板(大多数人都这样做),你甚至不需要注册表视图viewDidLoad!只需在故事板中输入单元格标识符即可dequeueReusableCellWithIdentifier:forIndexPath:.

  • 如果reusableCell被称为"Cell",那么MyCell在您的示例中来自何处? (3认同)

小智 18

@Sulthan的回答是现货.一种可能的方便修改是将单元格转换为UITableViewCell!而不是UITableViewCell.

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
    var cell = tableView.dequeueReusableCellWithIdentifier("CELL") as UITableViewCell!
    if !cell {
        cell = UITableViewCell(style:.Default, reuseIdentifier: "CELL")
    }
    // setup cell without force unwrapping it
    cell.textLabel.text = "Swift"
    return cell
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以修改单元格变量,而不必每次都强行展开它.使用隐式展开的选项时要小心.您必须确定您访问的值具有值.

有关更多信息,请参阅Swift编程语言的"隐式解包选项"部分.


Osc*_*ros 8

试试这个:

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
    cell.textLabel.text = "\(indexPath.row)"

    return cell
}
Run Code Online (Sandbox Code Playgroud)

请注意,UITableViewCell在创建实例化时,您应该注册您和ID UITableView:

tableView.delegate = self
tableView.dataSource = self
tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "Cell")
Run Code Online (Sandbox Code Playgroud)

  • 是! 您不必再导入任何自定义类了!很美丽 :-) (3认同)
  • 如果您想要更改单元格样式.您只需创建一个自定义单元子类,并在init方法中使用所需的样式. (2认同)
  • 好吧,这对我来说很有意义.你是对的它完美地工作,幸运的是,swift使得将另一个子类潜入同一个文件变得更加容易 (2认同)

DBo*_*yer 8

以下是我为了让它正常工作所写的内容......

首先使用表视图注册表视图单元格

self.tableView.registerClass(MyTableViewCell.self, forCellReuseIdentifier: "Cell")
Run Code Online (Sandbox Code Playgroud)

然后配置cellForRowAtIndexPath

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!  {
    var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as MyTableViewCell

    cell.textLabel.text = "Cell Text"
    cell.detailTextLabel.text = "Cell Detail Text in Value 1 Style"

    return cell
}
Run Code Online (Sandbox Code Playgroud)

然后我在文件的底部定义了一个自定义单元子类写入(因为它现在变得如此简单)

class MyTableViewCell : UITableViewCell {

    init(style: UITableViewCellStyle, reuseIdentifier: String!) {
        super.init(style: UITableViewCellStyle.Value1, reuseIdentifier: reuseIdentifier)
    }

}
Run Code Online (Sandbox Code Playgroud)


dav*_*d72 5

这是在swift 2中定义表格单元格的简单方法

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let identifier = "cell"
    let cell = tableView.dequeueReusableCellWithIdentifier(identifier) ??
        UITableViewCell.init(style: UITableViewCellStyle.Default, reuseIdentifier: identifier)
    cell.textLabel!.text = "my text"
    return cell
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特3:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let identifier = "cell"
    let cell = tableView.dequeueReusableCell(withIdentifier: identifier) ??
        UITableViewCell(style: .default, reuseIdentifier: identifier)
    cell.textLabel!.text = "my text"
    return cell
}
Run Code Online (Sandbox Code Playgroud)