对于tableview中,在某个位置
可能是中间某个位置
也可能是最后
插入一行
然后最后是通过:
messageTableView.reloadData()
搞定了数据的刷新问题。
因为之前没发用:
reloadRowsAtIndexPaths
否则会出错:
现在还是希望去搞懂:
对于新的insert的row,
如何在reloadData之后
去scroll到对应位置
去参考:
[已解决]Swift中如何在TableView的最后添加一行cell并且滚动到底部
去试试:
结果直接去insert并scroll:
//first do reload table data // msgTVC.messageTableView.reloadData() //then do scroll dispatch_async(dispatch_get_main_queue(), { () -> Void in //scroll to that row msgTVC.messageTableView.beginUpdates() let insertedRowIndexPath:NSIndexPath = NSIndexPath(forRow: insertedRowIdx, inSection: 0) print("insertedRowIndexPath=\(insertedRowIndexPath)") msgTVC.messageTableView.insertRowsAtIndexPaths( [insertedRowIndexPath], withRowAnimation: UITableViewRowAnimation.Automatic) msgTVC.messageTableView.endUpdates() msgTVC.messageTableView.scrollToRowAtIndexPath(insertedRowIndexPath, atScrollPosition: UITableViewScrollPosition.Middle, animated: true) }) |
还是insert时就出错:
Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (2) must be equal to the number of rows contained in that section before the update (0), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).’ |
加了reloadData:
msgTVC.messageTableView.reloadData() |
也还是同样错误。
swift tableview insert row and scroll
ios – inserting row at bottom in uitableview swift – Stack Overflow
iphone – Keep uitableview static when inserting rows at the top – Stack Overflow
Inserting row at bottom in uitableview swift – www.scriptscoop.net
Programmatic UITableView Scrolling – Grok Swift
插入新的行对应的数据之后,再在主界面的线程中reloadData和滚动到对应的新插入的行
//method 1: insert data and reloadData, and scroll //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 } //reload table data dispatch_async(dispatch_get_main_queue(), { () -> Void in msgTVC.messageTableView.reloadData() let insertedRowIndexPath:NSIndexPath = NSIndexPath(forRow: insertedRowIdx, inSection: 0) print("insertedRowIndexPath=\(insertedRowIndexPath)") //scroll to that row msgTVC.messageTableView.scrollToRowAtIndexPath(insertedRowIndexPath, atScrollPosition: UITableViewScrollPosition.Middle, animated: true) }) |
再去插入数据源中新行的数据:messageList.insert或messageList.append
然后再去插入(界面中的)新的行:insertRowsAtIndexPaths
之后就可以(随意的,按照你所希望的)去滚动到对应的新插入的行了:
//method 2: insert data and row, then scroll //insert/append and scroll dispatch_async(dispatch_get_main_queue(), { () -> Void in //1. beginUpdates msgTVC.messageTableView.beginUpdates() //2. insert new data for tablview row if !hasInserted { }) |
两种方式,都不会再出现那种NSInternalInconsistencyException的错误了。
都可以正常刷新对应的新的列表的行,且滚动到对应的新插入的行的位置了。
beginUpdates+insertRowsAtIndexPaths+endUpdates
// insert new data for tablview row //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 } //method 3: insert data and row, then scroll //insert/append and scroll dispatch_async(dispatch_get_main_queue(), { () -> Void in //1. beginUpdates msgTVC.messageTableView.beginUpdates() //2. insert new row for tablview cell let insertedRowIndexPath:NSIndexPath = NSIndexPath(forRow: insertedRowIdx, inSection: 0) print("insertedRowIndexPath=\(insertedRowIndexPath)") msgTVC.messageTableView.insertRowsAtIndexPaths( [insertedRowIndexPath], withRowAnimation: UITableViewRowAnimation.Automatic) //3. endUpdates msgTVC.messageTableView.endUpdates() //scroll to that row msgTVC.messageTableView.scrollToRowAtIndexPath(insertedRowIndexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: false) }) |
insertedRowIndexPath=<NSIndexPath: 0xc000000000000016> {length = 2, path = 0 – 0} 2015-12-15 17:45:38.442 JianDao[34102:1771517] *** Terminating app due to uncaught exception ‘NSRangeException’, reason: ‘-[UITableView _contentOffsetForScrollingToRowAtIndexPath:atScrollPosition:]: row (0) beyond bounds (0) for section (0).’ *** First throw call stack: ( 0 CoreFoundation 0x000000010edd9e65 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x0000000111180deb objc_exception_throw + 48 2 CoreFoundation 0x000000010edd9d9d +[NSException raise:format:] + 205 3 UIKit 0x000000010fd9e059 -[UITableView _contentOffsetForScrollingToRowAtIndexPath:atScrollPosition:] + 1445 4 UIKit 0x000000010fd9ed7e -[UITableView scrollToRowAtIndexPath:atScrollPosition:animated:] + 39 5 JianDao 0x000000010e11b26c _TTSf2n_d_i___TFFC7JianDao26ConversationViewController22insertMessageAndScrollFS0_FTCS_7Message6msgTVCCS_26MessageTableViewController_T_U_FT_T_ + 748 |
swift scroll after insert new cell
swift scroll after insert cell
UITableView 在顶部insertRowsAtIndexPaths 后,如何保持当前位置不变 | iOS开发 – CocoaChina CocoaChina_让移动开发更简单
swift scrollToRowAtIndexPath insertRowsAtIndexPaths contentOffsetForScrollingToRowAtIndexPath
ios – Best way to select a row after inserting it? – Stack Overflow
UITableView _contentOffsetForScrollingToRowAtIndexPath:atScrollPosition: How to solve This issue?
swift scrollToRowAtIndexPath contentOffsetForScrollingToRowAtIndexPath
iphone – error with scrollToRowAtIndexPath – Stack Overflow
swift contentOffsetForScrollingToRowAtIndexPath
Ray Wenderlich | Tutorials for Developers and Gamers
说是collection view的bug
-》感觉此处好像也是UITableView的bug。。。
结果代码都改为了:
当list有row时,且确保要滚动的位置小于最大row:
//scroll to that row //Terminating app due to uncaught exception ‘NSRangeException’, reason: ‘-[UITableView _contentOffsetForScrollingToRowAtIndexPath:atScrollPosition:]: row (0) beyond bounds (0) for section (0).’ let messageListCount:Int = msgTVC.messageList.count print("messageListCount=\(messageListCount)") let curMaxRowNum:Int = msgTVC.tableView(msgTVC.messageTableView, numberOfRowsInSection: 0) print("curMaxRowNum=\(curMaxRowNum)") if curMaxRowNum > 0 { let curMaxRowIdx:Int = curMaxRowNum – 1 print("curMaxRowIdx=\(curMaxRowIdx)") if insertedRowIndexPath.row <= curMaxRowIdx { msgTVC.messageTableView.scrollToRowAtIndexPath(insertedRowIndexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: false) } } else { print("can not scroll to that row, due to still not updated table data") } |
然后确保list中count也是1了:
messageListCount=1 MessageTableViewController numberOfRowsInSection curMaxRowNum=1 (lldb) po msgTVC.messageList.count 1 curMaxRowIdx=0 |
却还是出错:
Terminating app due to uncaught exception ‘NSRangeException’, reason: ‘-[UITableView _contentOffsetForScrollingToRowAtIndexPath:atScrollPosition:]: row (0) beyond bounds (0) for section (0).’
swift row (0) beyond bounds (0) for section (0)
iphone – UITableView scrollToRowAtIndexPath – Stack Overflow
iphone – NSInternalInconsistencyException (invalid number of rows) – Stack Overflow
//method 1: insert data and reloadData, and scroll //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 } msgTVC.messageTableView.reloadData() //reload table data }) |