對於表格(tableView)來說,下拉刷新數據、上拉加載數據應該是兩個最常用的數據更新操作了。對於前者,我原來寫過一篇相關的文章:Swift - 下拉刷新數據的功能實現(使用UIRefreshControl)。本次我來講講後者的實現。
說是上拉加載數據,其實就是當我們將表格內容滾動到最後一行時,系統就會自動獲取新的內容並添加到列表尾部(具體效果可以參考百度貼吧的App)。下面我們通過一個小樣例來演示上拉加載的實現。
1,樣例效果圖
(1)當初次進入程序時,先加載前20條數據。
(2)當 tableView 滾動條移到底部時,會看到表格底部有正在加載的提示,並繼續加載接下來的20條數據。
(3)數據加載完畢後,會把新數據添加到表格底部。
(4)如果表格再次滾到底部,則循環上面的操作,繼續加載新數據。
2,實現原理
(1)上拉加載的關鍵點在於判斷何時開始加載新數據。這裡我們在最後一條數據項顯示出來的時候就自動開始加載。也就是當用戶上拉表格,等到看到最後一條數據的時候就加載。
(2)同時我們在表格的 tableFooterView 中添加一個提示視圖,用來告訴用戶數據正在加載中。
(3)每次收到數據後,就將新數據並到本地的數據集合中,再調用 tableView的reloadData() 方法重新刷新下表格數據。
(4)這裡要注意每次發起請求的時候要做個保護,保證在原來的請求沒有返回時就不會發起新的請求。防止用戶在最後一頁來回滾動造成多次請求。
(5)實際的項目這些數據是通過網絡請求的。這裡就直接本地生成,並使用計時器加個延時,可以更好地看到效果。
3,完整代碼
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
//表格視圖
@IBOutlet weak var tableView: UITableView!
//數據集合
var dataArray = [String]()
//表格底部用來提示數據加載的視圖
var loadMoreView:UIView?
//計數器(用來做延時模擬網絡加載效果)
var timer: NSTimer!
//用了記錄當前是否允許加載新數據(正則加載的時候會將其設為false,放置重復加載)
var loadMoreEnable = true
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
//上拉刷新
self.setupInfiniteScrollingView()
self.tableView.tableFooterView = self.loadMoreView
//首次加載數據
loadMore()
}
//上拉刷新視圖
private func setupInfiniteScrollingView() {
self.loadMoreView = UIView(frame: CGRectMake(0, self.tableView.contentSize.height,
self.tableView.bounds.size.width, 60))
self.loadMoreView!.autoresizingMask = UIViewAutoresizing.FlexibleWidth
self.loadMoreView!.backgroundColor = UIColor.orangeColor()
//添加中間的環形進度條
let activityViewIndicator = UIActivityIndicatorView(activityIndicatorStyle: .White)
activityViewIndicator.color = UIColor.darkGrayColor()
let indicatorX = self.loadMoreView!.frame.size.width/2-activityViewIndicator.frame.width/2
let indicatorY = self.loadMoreView!.frame.size.height/2-activityViewIndicator.frame.height/2
activityViewIndicator.frame = CGRectMake(indicatorX, indicatorY,
activityViewIndicator.frame.width,
activityViewIndicator.frame.height)
activityViewIndicator.startAnimating()
self.loadMoreView!.addSubview(activityViewIndicator)
}
// 返回記錄數
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataArray.count;
}
//單元格數據設置
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)
-> UITableViewCell {
//設置單元格數據
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
cell.textLabel?.text = self.dataArray[indexPath.row]
//當下拉到底部,執行loadMore()
if (loadMoreEnable && indexPath.row == self.dataArray.count-1) {
loadMore()
}
return cell
}
//加載更多數據
func loadMore(){
print("加載新數據!")
loadMoreEnable = false
timer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self,
selector: #selector(ViewController.timeOut), userInfo: nil, repeats: true)
}
//計時器時間到
func timeOut() {
let start = self.dataArray.count + 1
//隨機添加10條新數據(時間是當前時間)
for i in start..<start+20 {
self.dataArray.append("新聞標題\(i)")
}
self.tableView.reloadData()
loadMoreEnable = true
timer.invalidate()
timer = nil
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}