self.tableView.reloadData() 不工作
self.tableView.reloadData() not working
我知道有成千上万的 tableView.reloadData() 问题和答案,但其中 none 对我有用!有人可以告诉我如何正确重新加载数据吗?很难解释我的问题,所以我会向您展示我的代码。
这是我的 整个 文件:
import UIKit
import Foundation
class MainViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{
@IBOutlet weak var nameField: UITextField!
@IBOutlet weak var amountField: UITextField!
@IBOutlet weak var whoPaysLabel: UILabel!
@IBOutlet weak var statusLabel: UILabel!
@IBOutlet weak var datePicker: UIDatePicker!
var names:NSMutableArray = []
var amounts:NSMutableArray = []
var dates:NSMutableArray = []
var whoPays:NSMutableArray = []
var status:NSMutableArray = []
var arrayNumber:Int = -1
@IBOutlet weak var tableView: UITableView!
let textCellIdentifier = "EntityCell"
var entityCellArray:[String] = []
let newDate = NSDate()
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBAction func changeWhoPays(sender: UISwitch) {
if(sender.on){
whoPaysLabel.text = "\(nameField.text) pays you"
}else{
whoPaysLabel.text = "you pay \(nameField.text)"
}
}
@IBAction func changeStatus(sender: UISwitch) {
if sender.on{
statusLabel.text = "paid"
}else{
statusLabel.text = "not paid"
}
}
func createNewEntity(){
names.addObject(nameField.text)
if let amountField_ = amountField.text.toInt() {
amounts.addObject(amountField_)
}
dates.addObject(datePicker.date)
if whoPaysLabel.text == "\(nameField.text) pays you"{
whoPays.addObject("they pay")
}else{
whoPays.addObject("you pay")
}
status.addObject(statusLabel.text!)
arrayNumber++
entityCellArray.append("\(names[arrayNumber) - \(amounts[arrayNumber]) - \(dates[arrayNumber]) - \(status[arrayNumber])")
let created = UIAlertController(title: "success", message: "creation successful", preferredStyle: UIAlertControllerStyle.Alert)
created.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Cancel, handler: nil))
presentViewController(created, animated: true, completion: nil)
nameField.text = ""
amountField.text = " "
whoPaysLabel.text = "..."
datePicker.date = newDate
refreshTableView()
}
//test function, not to be implemented in app
func printCount(){
println(entityCellArray.count)
}
func refreshTableView(){
self.tableView?.reloadData()
}
@IBAction func createButtonPressed(sender: UIButton){
createNewEntity()
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Return the number of sections.
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
return entityCellArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath) as! UITableViewCell
cell.textLabel?.text = entityCellArray[indexPath.row]
return cell
}
}
旁注:我是 swift 的新手,我确信我的 tableView dataSource
和 delegate
设置正确。希望有人能指出我为得到这个错误所做的工作:[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
一般来说,您的代码看起来不错,您需要提供崩溃的地方以及不工作的地方。
[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
告诉你你的数组之一是空的。在崩溃的地方添加一个断点。
对于 reloadData() 问题,有成千上万的原因导致无法正常工作。但是你必须弄清楚你自己的。添加断点
numberOfRowsInSection
和 cellForRowAtIndexPath
在 reloadData()
被调用之后,看看它是否正确中断,你的数组是否有你想要的内容。如果断点不起作用,要么是您的数据源不正确,要么是您的 tableView 为 nil。关键是,你应该学会如何调试代码,断点真的是你使用的工具。
例如:
添加断点后,尝试打印self.tableView?.dataSource。如果你看到dataSource设置正确,那么我们可以确认必须调用numberOfRowsInSection
和cellForRowAtIndexPath
,现在你可以在numberOfRowsInSection
和cellForRowAtIndexPath
处添加断点,看看是什么坏了。
顺便说一句,我刚刚看到:
@IBOutlet weak var tableView: UITableView!
它是一个较弱的 属性,您可能需要在加载视图控制器后检查 self.tableView 是否存在。通常我们不会对 UIView 使用 weak 除非你知道你在做什么...你可以删除 'weak' 并比较结果。
不要滥用 weak 来提高内存效率,因为它有其局限性,除非您知道自己在做什么。
根据您的代码,这个错误“[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]
”应该来自`cell.textLabel?.text = entityCellArray[indexPath.row]。只需检查 cellForRowAtIndexPath 中的 entityCellArray 计数是否为 0。
如果 tableView
插座未接通,您的 reloadData
将无能为力。如果 tableView
是 nil
,可选链 self.tableView?.reloadData()
将不执行任何操作,因为您忘记连接插座。
此错误 [__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
表示您在数组中有 1 个项目,但您正试图访问索引 1
处的项目(这是第二个项目)。我怀疑您在这一行遇到了这个错误:
entityCellArray.append("\(names[arrayNumber) - \(amounts[arrayNumber]) - \(dates[arrayNumber]) - \(status[arrayNumber])")
你的一个数组怎么会相对于其他数组缺少一个元素?看这一行:
if let amountField_ = amountField.text.toInt() {
amounts.addObject(amountField_)
}
如果 amountField.text
没有转换为整数,那么 amounts
将比其他数组具有更少的元素,并且您将在 amounts
的范围之外进行索引。请注意,即使是前导或尾随 space 字符也会导致 toInt()
失败。您可以将上面的替换为:
// Use 0 if the field doesn't convert to Int
let amountField_ = amountField.text.toInt() ?? 0
amounts.addObject(amountField_)
我知道有成千上万的 tableView.reloadData() 问题和答案,但其中 none 对我有用!有人可以告诉我如何正确重新加载数据吗?很难解释我的问题,所以我会向您展示我的代码。 这是我的 整个 文件:
import UIKit
import Foundation
class MainViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{
@IBOutlet weak var nameField: UITextField!
@IBOutlet weak var amountField: UITextField!
@IBOutlet weak var whoPaysLabel: UILabel!
@IBOutlet weak var statusLabel: UILabel!
@IBOutlet weak var datePicker: UIDatePicker!
var names:NSMutableArray = []
var amounts:NSMutableArray = []
var dates:NSMutableArray = []
var whoPays:NSMutableArray = []
var status:NSMutableArray = []
var arrayNumber:Int = -1
@IBOutlet weak var tableView: UITableView!
let textCellIdentifier = "EntityCell"
var entityCellArray:[String] = []
let newDate = NSDate()
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBAction func changeWhoPays(sender: UISwitch) {
if(sender.on){
whoPaysLabel.text = "\(nameField.text) pays you"
}else{
whoPaysLabel.text = "you pay \(nameField.text)"
}
}
@IBAction func changeStatus(sender: UISwitch) {
if sender.on{
statusLabel.text = "paid"
}else{
statusLabel.text = "not paid"
}
}
func createNewEntity(){
names.addObject(nameField.text)
if let amountField_ = amountField.text.toInt() {
amounts.addObject(amountField_)
}
dates.addObject(datePicker.date)
if whoPaysLabel.text == "\(nameField.text) pays you"{
whoPays.addObject("they pay")
}else{
whoPays.addObject("you pay")
}
status.addObject(statusLabel.text!)
arrayNumber++
entityCellArray.append("\(names[arrayNumber) - \(amounts[arrayNumber]) - \(dates[arrayNumber]) - \(status[arrayNumber])")
let created = UIAlertController(title: "success", message: "creation successful", preferredStyle: UIAlertControllerStyle.Alert)
created.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Cancel, handler: nil))
presentViewController(created, animated: true, completion: nil)
nameField.text = ""
amountField.text = " "
whoPaysLabel.text = "..."
datePicker.date = newDate
refreshTableView()
}
//test function, not to be implemented in app
func printCount(){
println(entityCellArray.count)
}
func refreshTableView(){
self.tableView?.reloadData()
}
@IBAction func createButtonPressed(sender: UIButton){
createNewEntity()
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Return the number of sections.
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
return entityCellArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath) as! UITableViewCell
cell.textLabel?.text = entityCellArray[indexPath.row]
return cell
}
}
旁注:我是 swift 的新手,我确信我的 tableView dataSource
和 delegate
设置正确。希望有人能指出我为得到这个错误所做的工作:[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
一般来说,您的代码看起来不错,您需要提供崩溃的地方以及不工作的地方。
[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
告诉你你的数组之一是空的。在崩溃的地方添加一个断点。
对于 reloadData() 问题,有成千上万的原因导致无法正常工作。但是你必须弄清楚你自己的。添加断点
numberOfRowsInSection
和 cellForRowAtIndexPath
在 reloadData()
被调用之后,看看它是否正确中断,你的数组是否有你想要的内容。如果断点不起作用,要么是您的数据源不正确,要么是您的 tableView 为 nil。关键是,你应该学会如何调试代码,断点真的是你使用的工具。
例如:
添加断点后,尝试打印self.tableView?.dataSource。如果你看到dataSource设置正确,那么我们可以确认必须调用numberOfRowsInSection
和cellForRowAtIndexPath
,现在你可以在numberOfRowsInSection
和cellForRowAtIndexPath
处添加断点,看看是什么坏了。
顺便说一句,我刚刚看到:
@IBOutlet weak var tableView: UITableView!
它是一个较弱的 属性,您可能需要在加载视图控制器后检查 self.tableView 是否存在。通常我们不会对 UIView 使用 weak 除非你知道你在做什么...你可以删除 'weak' 并比较结果。
不要滥用 weak 来提高内存效率,因为它有其局限性,除非您知道自己在做什么。
根据您的代码,这个错误“[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]
”应该来自`cell.textLabel?.text = entityCellArray[indexPath.row]。只需检查 cellForRowAtIndexPath 中的 entityCellArray 计数是否为 0。
如果 tableView
插座未接通,您的 reloadData
将无能为力。如果 tableView
是 nil
,可选链 self.tableView?.reloadData()
将不执行任何操作,因为您忘记连接插座。
此错误 [__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
表示您在数组中有 1 个项目,但您正试图访问索引 1
处的项目(这是第二个项目)。我怀疑您在这一行遇到了这个错误:
entityCellArray.append("\(names[arrayNumber) - \(amounts[arrayNumber]) - \(dates[arrayNumber]) - \(status[arrayNumber])")
你的一个数组怎么会相对于其他数组缺少一个元素?看这一行:
if let amountField_ = amountField.text.toInt() {
amounts.addObject(amountField_)
}
如果 amountField.text
没有转换为整数,那么 amounts
将比其他数组具有更少的元素,并且您将在 amounts
的范围之外进行索引。请注意,即使是前导或尾随 space 字符也会导致 toInt()
失败。您可以将上面的替换为:
// Use 0 if the field doesn't convert to Int
let amountField_ = amountField.text.toInt() ?? 0
amounts.addObject(amountField_)