在我的 Swift
应用程序中,我有一个 UITableView
和 UITextView
。这个想法很简单,当用户添加文本时 - 它应该出现在表格 View 的底部。
所以我有一个对象数组SingleMessage
:
var messages = [SingleMessage]()
当用户向 UITextView
添加文本时,我使用 Socket.IO
发送消息并接收它:
func messageArrived(_ notification: Notification) {
if let message = (notification as NSNotification).userInfo?["message"] as? SingleMessage {
DispatchQueue.main.async(execute: { () -> Void in
messages.append(message)
self.tview.reloadData()
self.scrollToBottom()
)}
}
}
我的函数 scrollToBottom()
包含以下代码:
if(self.messages.count > 0) {
let iPath = IndexPath(row: self.tview.numberOfRows(inSection: 0)-1, section: self.tview.numberOfSections-1)
self.tview.scrollToRow(at: iPath, at: UITableViewScrollPosition.bottom, animated: false)
}
然后我有 cellForRow
函数,它做了很多事情,比如为每个标签设置字体和文本等。
override func tableView(_ tview: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tview.dequeueReusableCell(withIdentifier: "chat") as! SingleCommentCell
if let msg:SingleMessage = self.messages[(indexPath as NSIndexPath).row] as? SingleMessage {
.
.
.
我的问题是,当我输入内容后,立即按下 send
按钮并再次开始输入 - 整个界面卡住了几秒钟,我什至看不到键盘的反馈。我认为问题在于 TableView 必须完全刷新。
我在 Chat 组件中使用上面的界面,因此不仅当用户连续快速键入多条消息时会出现问题,而且当有很多传入消息时也会出现问题。
有什么方法可以加快整个界面的速度,例如在表格 View 底部添加新单元格并避免刷新现有单元格?
与我的 UITableViewController
相关的其他功能是:
override func tableView(_ tview: UITableView, numberOfRowsInSection section: Int) -> Int {
return messages.count
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
然后我有:
override func viewDidLoad() {
super.viewDidLoad()
tview.separatorStyle = UITableViewCellSeparatorStyle.none
tview.backgroundColor = UIColor.clear
tview.delegate = self
tview.dataSource = self
self.tview.estimatedRowHeight = 100
NotificationCenter.default.addObserver(self, selector: #selector(ChatView.messageArrived(_:)), name: NSNotification.Name(rawValue: incomingMessage), object: nil)
}
最佳答案
reloadData
是一个非常昂贵的操作。它重建整个表。您最好更好地跟踪您的模型,在您想要执行这些操作时使用插入和删除行功能,并在它们发生变化时刷新各个行。
一个好的策略是保留旧模型,生成新模型,然后计算已创建、移动或删除的项目集,并为每种情况生成单独的表操作。这是一些示例代码:
- (void) setDevicesForKey: (NSString *) propertyKey
toDevices: (NSArray *) newDevices
{
NSArray *currentDevices = [self valueForKey: propertyKey];
NSUInteger tableSection = [self sectionForKey: propertyKey];
NSIndexSet *indexesOfItemsToRemove = [currentDevices indexesOfObjectsPassingTest: ^BOOL(DeviceItem * itemToCheck, NSUInteger idx, BOOL *stop) {
return ![newDevices containsObject: itemToCheck];
}];
NSIndexSet *indexesOfItemsToAdd = [newDevices indexesOfObjectsPassingTest:^BOOL(DeviceItem *itemToCheck, NSUInteger idx, BOOL *stop) {
return ![currentDevices containsObject: deviceItem];
}];
UITableView *tableView = [self tableView];
[tableView beginUpdates];
{
NSMutableArray *removeIndexPaths = [NSMutableArray array];
[indexesOfItemsToRemove enumerateIndexesUsingBlock: ^(NSUInteger idx, BOOL *stop) {
[removeIndexPaths addObject: [NSIndexPath indexPathForItem: idx inSection: tableSection]];
}];
[tableView deleteRowsAtIndexPaths: removeIndexPaths withRowAnimation: UITableViewRowAnimationAutomatic];
NSMutableArray *insertIndexPaths = [NSMutableArray array];
[indexesOfItemsToAdd enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
[insertIndexPaths addObject: [NSIndexPath indexPathForItem: idx inSection: tableSection]];
}];
[tableView insertRowsAtIndexPaths: insertIndexPaths withRowAnimation: UITableViewRowAnimationAutomatic];
[newDevices enumerateObjectsUsingBlock: ^(DeviceItem *itemToCheck, NSUInteger idx, BOOL *stop) {
if([currentDevices containsObject: itemToCheck])
{
NSUInteger oldIndex = [currentDevices indexOfObject: ticketToCheck];
NSUInteger newIndex = [newDevices indexOfObject: ticketToCheck];
if(oldIndex != newIndex)
{
NSIndexPath *fromIndexPath = [NSIndexPath indexPathForRow: oldIndex inSection: tableSection];
NSIndexPath *toIndexPath = [NSIndexPath indexPathForRow: newIndex inSection: tableSection];
[tableView moveRowAtIndexPath: fromIndexPath toIndexPath: toIndexPath];
}
}
}];
[self setValue: newDevices forKey: propertyKey];
}
[tableView endUpdates];
}
关于ios - 添加新内容并刷新 UITableView 会在 Swift 中卡住我的应用程序几秒钟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43764522/