Swift中的UITableView

 1012720691_905e1e 发布于 2023-01-11 19:29

我正在努力弄清楚这段代码的错误.这目前在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
    }

Sulthan.. 82

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

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

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

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

var cell : UITableViewCell?

我们必须使用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


matt.. 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
}

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

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

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

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

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

    var cell : UITableViewCell?
    

    我们必须使用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
    

    2023-01-11 19:31 回答
  • 试试这个:

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

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

    tableView.delegate = self
    tableView.dataSource = self
    tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "Cell")
    

    2023-01-11 19:31 回答
  • 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
    }
    

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

    2023-01-11 19:32 回答
  • @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
    }
    

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

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

    2023-01-11 19:33 回答
  • 以下是我为了让它正常工作所写的内容......

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

    self.tableView.registerClass(MyTableViewCell.self, forCellReuseIdentifier: "Cell")
    

    然后配置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
    }
    

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

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

    2023-01-11 19:33 回答
  • 这是在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
    }
    

    斯威夫特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
    }
    

    2023-01-11 19:33 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有