如何显示最后一个tableView单元格没有滚动效果

时间:2016-11-17 19:37:58

标签: ios swift uitableview firebase firebase-realtime-database

我正在尝试使用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()viewDidLoadreloadData()之后将viewWillAppear函数调用放入viewDidAppear。没变。事实上,当我把它放在viewDidAppear以外的任何地方时,绝对没有任何反应。我必须像往常一样向下滚动

3 个答案:

答案 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

此外,请删除viewDidAppearviewWillAppear并改为实施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;
} 

只要用户没有手动滚动,就可以很好地插入任何新传入的消息,并将其他消息“向上”推送。