uitableview add new row
swift uitableview add new row
ios uitableview add new row
Insert Table Row | Ryan Wright
ios – How to add item to UITableView? – Stack Overflow
好像主要的还是:
tableView.beginUpdates() tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Bottom) tableView.endUpdates() |
然后,到时候记得去:
给自己的函数insertMessageAndScroll去添加lock
self.insertLock.lock() //insert row dispatch_async(dispatch_get_main_queue(), { () -> Void in let insertedRowIndexPath:NSIndexPath = NSIndexPath(forRow: insertedRowIdx, inSection: 0) msgTVC.messageTableView.beginUpdates() msgTVC.messageTableView.insertRowsAtIndexPaths([insertedRowIndexPath], withRowAnimation: UITableViewRowAnimation.Bottom) msgTVC.messageTableView.endUpdates() }) |
但是还是不行。
换成reload,结果还是出错
//insert row dispatch_async(dispatch_get_main_queue(), { () -> Void in //not reload for only 1 row if insertedRowIdx > 0 { let insertedRowIndexPath:NSIndexPath = NSIndexPath(forRow: insertedRowIdx, inSection: 0) msgTVC.messageTableView.beginUpdates() // msgTVC.messageTableView.insertRowsAtIndexPaths([insertedRowIndexPath], withRowAnimation: UITableViewRowAnimation.Bottom) msgTVC.messageTableView.reloadRowsAtIndexPaths([insertedRowIndexPath], withRowAnimation: UITableViewRowAnimation.Bottom) msgTVC.messageTableView.endUpdates() } }) |
insertrowsatindexpaths crash
->
还是之前的问题:
要确保:
insert data
和
insert row(insertRowsAtIndexPaths)
不仅保持数量上的一致
还要确保在同一个线程,即insertRowsAtIndexPaths所要求的主线程中
这样才不会出现:
insertRowsAtIndexPaths时,在其他线程中,其实已经改变了dataList了。。
-》导致data和row不一致,导致出错
[总结]
最后用代码:
//method 1: insert data and reloadData, and scroll dispatch_async(dispatch_get_main_queue(), { () -> Void in //insert to correct position according datetime var insertedRowIdx:Int = 0 var hasInserted:Bool = false for (curIdx, curMessage) in msgTVC.messageList.enumerate() { // print("[\(curIdx)] newMessage.timestamp=\(newMessage.timestamp), curMessage.timestamp=\(curMessage.timestamp), newMessage.text=\(newMessage.text)") if newMessage.timestamp < curMessage.timestamp { msgTVC.messageList.insert(newMessage, atIndex: curIdx) insertedRowIdx = curIdx hasInserted = true break } } if !hasInserted { msgTVC.messageList.append(newMessage) insertedRowIdx = msgTVC.messageList.count – 1 hasInserted = true } //update timestamp string if insertedRowIdx > 0 { let prevMessage = msgTVC.messageList[insertedRowIdx – 1] newMessage.timestampStr = generateTimestampStr(newMessage.timestamp, prevTimestamp: prevMessage.timestamp) } else { newMessage.timestampStr = generateTimestampStr(newMessage.timestamp, prevTimestamp: nil) } // print("insertedRowIdx=\(insertedRowIdx)") //insert row let insertedRowIndexPath:NSIndexPath = NSIndexPath(forRow: insertedRowIdx, inSection: 0) msgTVC.messageTableView.beginUpdates() msgTVC.messageTableView.insertRowsAtIndexPaths([insertedRowIndexPath], withRowAnimation: UITableViewRowAnimation.Bottom) msgTVC.messageTableView.endUpdates() if isCurrentShowingVc(msgTVC) { //only when current vc, then scroll to that row msgTVC.messageTableView.scrollToRowAtIndexPath(insertedRowIndexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: true) } }) |
确保了:
先去更新数据:
messageList.insert或messageList.append
紧接着,在同一线程中,去插入行:
messageTableView.insertRowsAtIndexPaths
注:
此处的同一个线程,意味着:都在主线程dispatch_get_main_queue
因为insertRowsAtIndexPaths要求必须处于主线程