Swift 3在索引路径中打破行的单元格

时间:2016-11-25 04:00:35

标签: swift firebase swift3

此代码来自一个现在无效的教程,它帮助我将数据加载到表视图中。由于本教程是用Swift 2.0编写的,我相信这在Swift 3中已经改变了。我知道覆盖函数本身已经改变了,我处理了。但现在,它给我带来Thread 1: EXC_BAD_INSTRUCTION(code=EXC_1386_INVOP, subcode=0x0)错误。

更新:我尝试过多种方法,包括为单元格创建自定义类。我仍然得到上面列出的相同错误,或者我的App Delegate文件的第一行有Thread 1: Signal SIGABRT错误。创建一个断点并没有帮助我,因为我知道错误的来源。

import UIKit
import Firebase
import FirebaseDatabase


struct postStruct {
    let title : String!
    let message : String!
}

class LoggedInController: UITableViewController {

    var posts = [postStruct]()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.delegate = self
        self.tableView.dataSource = self

        let databaseRef = FIRDatabase.database().reference()

        databaseRef.child("Posts").queryOrderedByKey().observe(.childAdded, with: {
            snapshot in

            let snapshotValue = snapshot.value as? NSDictionary
            let title = snapshotValue!["title"] as? String

            let message = snapshotValue!["message"] as? String

            self.posts.insert(postStruct(title: title, message: message), at: 0)
            self.tableView.reloadData()
        })

        post()
    }

    func post(){

        let title = "Title"
        let message = "Message"

        let post : [String : AnyObject] = ["title" : title as AnyObject,
                                           "message": message as AnyObject]

        let databaseRef = FIRDatabase.database().reference()

        databaseRef.child("Posts").childByAutoId().setValue(post)

    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return posts.count
    }

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

    let cell = tableView.dequeueReusableCell(withIdentifier: "PostCell")

    let label1 = cell?.viewWithTag(1) as! UILabel
    label1.text = posts[indexPath.row].message

    let label2 = cell?.viewWithTag(2) as! UILabel
    label2.text = posts[indexPath.row].message

    return cell!
    }
}

更新2:以下是我使用的新代码。它并不漂亮,只能获得冠军。

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return posts.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cell = tableView.dequeueReusableCell(withIdentifier: "Cell")

    if cell == nil {
        cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
        cell?.textLabel?.text = posts[indexPath.row].title
        cell?.detailTextLabel?.text = posts[indexPath.row].message
        return cell!
    } else {
        let label1 = cell?.viewWithTag(1) as? UILabel
        label1?.text = posts[indexPath.row].title

        let label2 = cell?.viewWithTag(2) as? UILabel
        label2?.text = posts[indexPath.row].message
        return cell!
    }
}

3 个答案:

答案 0 :(得分:0)

使用dequeueReusableCell,您正在访问不存在的单元格。要使代码工作,请更改以下行:

let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")

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

答案 1 :(得分:0)

试试这个

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
 {
    let cell:UITableViewCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as UITableViewCell!

    let label1 = cell.viewWithTag(1) as! UILabel
    label1.text = posts[indexPath.row].message

    let label2 = cell.viewWithTag(2) as! UILabel
    label2.text = posts[indexPath.row].message

    return cell
}

被修改

确定你做了这些事

<强>的UITableViewController

viewDidLoad()

self.tableView.register(UITableViewCell.self,     forCellReuseIdentifier:"catCell" )
let catNib : UINib = UINib.init(nibName: "TableViewCategoryCell",  bundle: nil)
self.tableView.register(catNib, forCellReuseIdentifier: "TableViewCategoryCell")

cellForRowAt indexPath

let cell : OPM_AlarmTableViewCategoryCell = tableView.dequeueReusableCell(withIdentifier:"OPM_AlarmTableViewCategoryCell" ) as! OPM_AlarmTableViewCategoryCell!
cell.categoryLabel?.text = "Some Text"
return cell

<强> UITableviewCell.XIB 希望你做了这些事     Custom Class     TableViewCell     Outlet

<强>的UITableViewCell     Tableviewcell code 确保出现点,以便@IBOutlet与...连接 xib标签

答案 2 :(得分:0)

好的,这段代码let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")会生成一个名为cell的可选项,它可能包含也可能不包含UITableViewCell的有效实例。 Swift中的Optionals是一种防范零值的方法,你可以在这里阅读更多关于选项的内容:Optionals

在您的表视图要加载其数据的第一次运行时,它会调用UITableViewDataSource所需的所有方法。第一次运行是关键的,因为UITableViewCell的任何实例都没有表格视图可以使 出列。要解决您的问题,您必须执行与以下代码类似的操作:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return posts.count
    }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cell = tableView.dequeueReusableCell(withIdentifier: "cell")

    if cell == nil {
        cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
        cell?.textLabel?.text = "New value"
        cell?.detailTextLabel?.text = "New value"
        return cell!
    } else {
        cell?.textLabel?.text = "" //reset value
        cell?.detailTextLabel?.text = "" // resetValue
        cell?.textLabel?.text = "New value"
        cell?.detailTextLabel?.text = "New value"
        return cell!
    }
}

类似于上面的代码通常用于以编程方式添加UITableViewCell的实例。但是,如果使用接口构建器添加原型单元格,请使用let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)方法将单元格出列,在这种情况下,它不会返回可选项,并且您不需要执行所有if / else块。 我想提到的关于你的代码的其他东西是找到子视图购买他们的ID将不会产生非常面向对象的代码,并且可能是编译器无法找到子视图的错误源。更好的方法是使用其中一个UITableViewCell的内置实例,例如.default,或者你可以将所述类子类化,并创建自己的自定义单元格。

希望这有帮助!