對於表格(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()
}
}