gpt4 book ai didi

ios - scrollToRowAtIndexPath :atScrollPosition causing table view to "jump"

转载 作者:IT王子 更新时间:2023-10-29 08:11:42 27 4
gpt4 key购买 nike

我的应用程序具有聊天功能,我正在像这样输入新消息:

[self.tableView beginUpdates];
[messages addObject:msg];
[self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:messages.count - 1 inSection:1]] withRowAnimation:UITableViewRowAnimationBottom];
[self.tableView endUpdates];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:messages.count - 1 inSection:1] atScrollPosition:UITableViewScrollPositionBottom animated:YES];

但是,当我添加一条新消息时,我的 TableView 会奇怪地“跳转”(无论是发送还是接收,两者的结果都相同):

enter image description here

为什么我会出现这种奇怪的“跳跃”?

最佳答案

好的,我明白了。正如您所说,问题与自动调整单元格有关。我使用了两个技巧让一切正常(我的代码是 Swift,但应该很容易转换回 ObjC):

1) 在采取进一步行动之前等待表格动画完成。这可以通过将更新表的代码包含在 CATransaction.begin()CATransaction.commit() 之间的 block 中来完成。我在 CATransaction 上设置了完成 block ——该代码将在动画完成后运行。

2) 强制表格 View 在滚动到底部之前呈现单元格。我通过少量增加表的 contentOffset 来实现。这会导致新插入的单元格出列,并计算其高度。滚动完成后(我使用上面的方法 (1) 等待它完成),我最终调用了 tableView.scrollToRowAtIndexPath

代码如下:

override func viewDidLoad() {
super.viewDidLoad()

// Use auto-sizing for rows
tableView.estimatedRowHeight = 40
tableView.rowHeight = UITableViewAutomaticDimension
tableView.dataSource = self
}

func chatManager(chatManager: ChatManager, didAddMessage message: ChatMessage) {
messages.append(message)

let indexPathToInsert = NSIndexPath(forRow: messages.count-1, inSection: 0)

CATransaction.begin()
CATransaction.setCompletionBlock({ () -> Void in
// This block runs after the animations between CATransaction.begin
// and CATransaction.commit are finished.
self.scrollToLastMessage()
})

tableView.beginUpdates()
tableView.insertRowsAtIndexPaths([indexPathToInsert], withRowAnimation: .Bottom)
tableView.endUpdates()

CATransaction.commit()
}

func scrollToLastMessage() {
let bottomRow = tableView.numberOfRowsInSection(0) - 1

let bottomMessageIndex = NSIndexPath(forRow: bottomRow, inSection: 0)

guard messages.count > 0
else { return }

CATransaction.begin()
CATransaction.setCompletionBlock({ () -> Void in

// Now we can scroll to the last row!
self.tableView.scrollToRowAtIndexPath(bottomMessageIndex, atScrollPosition: .Bottom, animated: true)
})

// scroll down by 1 point: this causes the newly added cell to be dequeued and rendered.
let contentOffset = tableView.contentOffset.y
let newContentOffset = CGPointMake(0, contentOffset + 1)
tableView.setContentOffset(newContentOffset, animated: true)

CATransaction.commit()
}

关于ios - scrollToRowAtIndexPath :atScrollPosition causing table view to "jump",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35291117/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com