我正在尝试使用Swift创建评论/消息tableView
,并希望UITableViewController
在用户点击该消息时显示最后tableViewCell
"评论室&# 34;
我从远程源(本例中为Firebase)中提取数据以填充每个tableViewCells
。一旦我提取了所有数据,我就会为每个单元配置适当的信息。这样做没有任何错误。
但是,默认情况下,tableview
会在顶部显示单元格
我已尝试使用这些来使tableView
显示最后一个单元格,但它仍会执行可见的滚动"我想删除的效果。例如,使用iMessage应用程序,Instagram或Snapchat的直接消息传递功能。单击"聊天或评论室"后,生成的表(或collectionview
)会立即显示最后一个单元格,而不会明显滚动到它
以下是我的尝试:
var chatRoomMessages: [FIRDataSnapshot] = []
override func viewDidLoad() {
super.viewDidLoad()
fetchChatRoomCommentsFromServer(chatRoomId: self.chatRoomId) { (snap) in
self.chatRoomMessages.append(snap)
self.tableView.reloadData()
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
moveToLastComment()
}
func fetchChatRoomCommentsFromServer(chatRoomId: String, callback: @escaping (FIRDataSnapshot) -> ()) {
DataService.dataService.CHAT_ROOM_REF.child(chatRoomId).child("messages").observe(.childAdded, with: { (snapshot) in
DataService.dataService.MESSAGES_REF.child(snapshot.key).observe(.value, with: { (snap) in
callback(snap)
})
})
}
func moveToLastComment() {
if self.tableView.contentSize.height > self.tableView.frame.height {
// First figure out how many sections there are
let lastSectionIndex = self.tableView!.numberOfSections - 1
// Then grab the number of rows in the last section
let lastRowIndex = self.tableView!.numberOfRows(inSection: lastSectionIndex) - 1
// Now just construct the index path
let pathToLastRow = NSIndexPath(row: lastRowIndex, section: lastSectionIndex)
// Make the last row visible
self.tableView?.scrollToRow(at: pathToLastRow as IndexPath, at: UITableViewScrollPosition.bottom, animated: true)
}
}
消息正确加密,视图会按预期滚动到最后一个tableViewCell ....但是......我希望视图已经出现在最后一个单元格中。 除了三个应用示例之外,我还看到其他应用也做同样的事情。
非常感谢任何帮助
编辑:11月17日下午3:26
我还尝试在moveToLastComment()
,viewDidLoad
和reloadData()
之后将viewWillAppear
函数调用放入viewDidAppear
。没变。事实上,当我把它放在viewDidAppear
以外的任何地方时,绝对没有任何反应。我必须像往常一样向下滚动
答案 0 :(得分:1)
响应@shallowThought:同样,实现viewWillAppear对视图完全没有任何作用。没有任何动静。 TableViewController加载所有数据但仍保持在最顶层。但是,我确实尝试再次实现viewDidAppear和viewWillAppear。我相信viewWillAppear不能单独工作,因为当tableView本身没有“出现”或“加载”时你无法重新加载tableView。 viewWillAppear在获取数据,配置分隔符样式等方面似乎更有效。所以这就是我所做的:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setToolbarHidden(true, animated: true)
self.tableView.separatorStyle = .none
self.tableView.setNeedsLayout()
self.tableView.layoutIfNeeded()
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 80
NotificationCenter.default.addObserver(self, selector: #selector(SingleChatRoomTableViewController.keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(SingleChatRoomTableViewController.keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
DispatchQueue.global().async {
DataService.dataService.fetchChatRoomCommentsFromServer(chatRoomId: self.chatRoomId) { (snap) in
self.chatRoomMessages.append(snap)
}
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
DispatchQueue.main.async {
self.tableView.reloadData()
self.moveToLastComment()
}
}
这按照我的意图行事; tableview加载到最后一个单元格,没有明显滚动到该行或明显“传送”到该行。它是否可视地滚动或传送是在scrollToRow方法调用中指定true或false之间的区别。这种方式既不会,视图只是在最后一行等待而不显示用户。
但是......显示消息的实际单元格加载速度有些慢。也许这是由于Firebase的性质或我如何加载数据。 tableView本身似乎“知道”最后一个消息行的位置,但实际内容消息必须加载仍然可见。无论如何,这是另一个问题的主题。
答案 1 :(得分:0)
将动画设置为self.tableView?.scrollToRow(at: pathToLastRow as IndexPath, at: UITableViewScrollPosition.bottom, animated: false)
:
viewDidLoad
此外,请删除viewDidAppear
和viewWillAppear
并改为实施override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
fetchChatRoomCommentsFromServer(chatRoomId: self.chatRoomId) { (snap) in
self.chatRoomMessages.append(snap)
self.tableView.reloadData()
moveToLastComment()
}
}
:
function getReference(citation)
{
var url = "http://adsres.cfa.harvard.edu:5000/cgi-bin/refcgi.py?resolvethose=" + encodeURIComponent(citation);
$.ajax({
url: url,
data: encodeURIComponent(citation),
success: displayResult,
error: displayError
});
}
答案 2 :(得分:0)
我需要类似的行为,但是与不需要任何滚动代码的路径不同。在我的版本中,最新的消息(“评论”)总是插在列表的顶部。为了使它们出现在屏幕的底部,我设置了UITableView的转换:
self.tableView.transform = CGAffineTransformMakeScale(1, -1);
这是一个“颠倒”的桌面视图,这是不好的,因为所有的单元格内容也是颠倒的。你可以用以下方法解决这个问题:
- (void) tableView: (UITableView *) tableView willDisplayCell: (UITableViewCell *) cell forRowAtIndexPath:(NSIndexPath *) indexPath
{
cell.transform = self.tableView.transform;
}
只要用户没有手动滚动,就可以很好地插入任何新传入的消息,并将其他消息“向上”推送。