iOS中UITableView在视图出现时自动滚动到底部(无痕,不闪动)

现在在做一个类似聊天的界面,需求是当进入聊天列表的时候,tableView自动滚动到最后一条聊天记录。


首先,tableView滚动到底部通用的是这两种方法:

1.tableView.setContentOffset(CGPoint(x:0, y:tableView.contentSize.height - tableView.bounds.size.height), animated: false)

2.if self.messageModelArray.count > 0 {

     tableView.scrollToRow(at: IndexPath(row: self.messageModelArray.count - 1, section: 0), at: .bottom,                                  animated: false)

    }

开始想用第一种方法实现来,但是tableView的contenSize是随着加载cell的个数而发生变化的,所以选择的第二种方法。

那么在什么时机去调用tableView的scrollToRow方法呢,这是重点。首先在viewDidLoad和viewWillAppear方法中肯定是不行的,因为tableView还没有加载完成。另外,在viewDidAppear方法中倒是可以实现,但是会有一个明显的滑动过程,即使animated设置为false也会有滑动的过程,用户体验不好。

最后想到的办法是在numberOfRowsInSection方法中去调用tableView的scrollToRow方法,并且加一个判断,只有在初始化的时候去调用,之后再reload的时候就不调用了。这里需要加一个延时,否则会造成死循环,为啥会造成死循环还没有搞明白,尴尬。。。 最后贴代码,如下:

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        

        if self.isScrollBottom { //只在初始化的时候执行

            let popTime = DispatchTime.now() + 0.005 //延迟执行5毫秒

            DispatchQueue.main.asyncAfter(deadline: popTime) {

                if self.messageModelArray.count > 0 {

                    tableView.scrollToRow(at: IndexPath(row: self.messageModelArray.count - 1, section: 0), at: .bottom, animated: false)

                }

            }

        }

       

        return self.messageModelArray.count

    }


override func viewDidAppear(_ animated: Bool) {

        super.viewDidAppear(animated)

    

        self.isScrollBottom = false

    }



你可能感兴趣的:(iOS中UITableView在视图出现时自动滚动到底部(无痕,不闪动))