1. 程式人生 > >iOS中UITableView在檢視出現時自動滾動到底部(無痕,不閃動)

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 {

ifself.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)

                }

            }

        }

returnself.messageModelArray.count

    }

override func viewDidAppear(_ animated: Bool) {

        super.viewDidAppear(animated)

self.isScrollBottom = false

    }