2016-11-25 168 views
0

此代码来自现在非活动的教程,它帮助我将数据加载到表格视图。由于本教程是用Swift 2.0编写的,我相信这在Swift 3中有所改变。我知道override函数本身发生了变化,我处理了这个函数。但现在,它给我带来了一个Thread 1: EXC_BAD_INSTRUCTION(code=EXC_1386_INVOP, subcode=0x0)错误。Swift 3在索引路径中为行打破单元格

更新:我尝试过多种方法,包括为单元格创建自定义类。我仍然得到了上面列出的同样的错误,或者在我的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! 
    } 
} 
+0

请看[这里](https://developer.apple.com/reference/uikit/uitableview/1614983-cellforrow)我相信唯一改变的就是func的方法签名,所以只需要输入'cellFor '和自动完成会弹出可能的东西 – Honey

+0

最有效的解决方案是在Interface Builder中使用IBOutlets创建**自定义**单元。至少从Xcode 6开始,'viewWithTag'方式已经过时了。 – vadian

+0

@vadian我已经将单元格类型设置为自定义。我不确定如何用IBOutlets来做到这一点。 –

回答

0

使用dequeueReusableCell,您正在访问不存在的单元。为了使您的工作代码更改下面一行:

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

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

这给我一个线程1:信号SIGABRT在我的应用程序委托文件的第一行。 –

+0

@SteveHalla发布完整代码 –

+0

查看有关问题的更新代码。 –

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与 厦门国际银行标签

+0

这给了我一个'致命的错误:意外地发现零,同时展开一个可选的值'let cell:UITableViewCell = self.tableView.dequeueReusableCell(withIdentifier:cellReuseIdentifier)as UITableViewCell!' –

+0

只要告诉我,如果你使用的故事板或不。 – Koushik

+0

我要制作原型单元格。 –

0

确定这码let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")产生一个可选的叫cell,可能会或可能不会包含的UITableViewCell的AA有效实例连接。当你的表视图要加载其数据调用你的UITableViewDataSource所需的全部方法Optionals

在第一次运行:在斯威夫特选配的,以防止零值的方法,你可以阅读更多关于选配这里。第一次运行是关键的,因为没有任何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,或者一次性可以继承该类并创建自己的自定义单元格。

希望这有助于!

+0

编辑代码确保您使用更新版本 –

+0

这样做但是我确实尝试了你的代码,但是它在我的应用程序代理中返回了一个'​​线程1:信号SIGABRT'错误 –

+0

标签can也可以通过编程来设置,看来这里的问题并不是创建单元格,因为我提供的代码非常标准,应用程序委托运行时错误是一个非常通用的错误,因此我建议在代码上设置一个断点以停止执行就在应用程序崩溃之前,要做到这一点,选择你的断点导航器,在左下角你会看到一个+符号点击它并选择一个异常断点。提供了进一步修改折点的选项。所有的默认设置都可以。再次运行您的代码并查看代码中断的位置。 @SteveHalla –

相关问题