二.系統(tǒng)自帶的下拉刷新:{
1. iOS6以后添加,refreshControl = UIRefreshControl()'繼承于UIControl';
2. 給下拉刷新添加事件:refreshControl?.addTarget(self, action: "loadData", forControlEvents: UIControlEvents.ValueChanged)
3. 有默認的寬和高;
4. 添加事件的時候使用UIControlEventValueChanged進行監(jiān)聽
}
三.下拉刷新邏輯:{
1. since_id = homeViewMode.list.first?.statusModel?.id ?? 0;
{
a. 第一次加載的時候,list中為空.則結(jié)果為0;
b. 再次加載的時候,list不為空.結(jié)果since_id獲取到list的第一個數(shù)據(jù),此時max_id = 0(菊花沒有轉(zhuǎn)動,不會給max_id賦值);
c. 將since_id(有值),max_id(無值)傳給loadData()方法,加載新數(shù)據(jù);
d. 在下載中:if max_id > 0 {//上拉加載
self.list = self.list + temp
} else {//下拉刷新
self.list = temp + self.list
}
}
}
四.KVO實現(xiàn){
1. 添加KVO:添加一個鍵值觀察者{
第一個參數(shù): 觀察者; 誰是觀察者,誰就要實現(xiàn) 一個方法
第二個參數(shù): 觀察對象的屬性
第三個參數(shù): 新值還是舊值
第四個參數(shù): 默認填 nil
tableView.addObserver(self, forKeyPath: "contentOffset", options: NSKeyValueObservingOptions.New, context: nil)}
2. KVO的第二步,實現(xiàn) 監(jiān)聽方法{
observeValueForKeyPath:是NSObject的方法
參數(shù):{
a. keyPath -- 觀察的屬性
b. object -- 觀察的對象}
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>)}}
五.自定義下拉刷新:{
1. 封裝下拉刷新的時候,應(yīng)將KVO封裝在刷新view中;
2. 在刷新view中,可通過'willMoveToSuperview'方法獲取父視圖"newSuperview",子控件將要添加到父類控件上去,會調(diào)用這個方法;
3. 為了提高兼容性,我們將"newSuperview"轉(zhuǎn)換成"UIScrollView",這樣所有的可滑動類都能使用下拉刷新;
4. 為了方便類調(diào)用,將"newSuperview"賦值給一個全局屬性;
5. 判斷"newSuperview"如果是"UIScrollView",則添加KVO;
6. "scrollView!.dragging":判斷scrollView是否是拖拽狀態(tài){
a. 不是拖拽狀態(tài),且狀態(tài)是釋放就刷新狀態(tài)進行刷新(也就是松手狀態(tài));
b. 是拖拽狀態(tài),則根據(jù)KVO的改變進行'三種狀態(tài)'的切換;
}
7. 三種狀態(tài):status{
y = scrollView?.contentOffset.y
a. 普通狀態(tài): y>-140 文字改成"下拉刷新";
b. 釋放的話就刷新:y<-140 文字改成"釋放加載";
c. 松手狀態(tài): y<-140 文字改成"加載中";
}
8. 為了便于管理,將'文字變化/箭頭變化/菊花轉(zhuǎn)動'封裝到status的didSet方法中,使用switch-case方法判斷;
9. 性能優(yōu)化:為了防止每次移動的時候都調(diào)用status的didSet方法,在判斷距離的同時對狀態(tài)進行判斷,只在臨界值的時候修改一
例:y < -140 && status == .Pulling!
10.箭頭恢復/旋轉(zhuǎn):
self.arrowImageView.transform = CGAffineTransformIdentity
self.arrowImageView.transform = CGAffineTransformMakeRotation(CGFloat(M_PI))
11. 與父控制器通信:{
a. 閉包/代理/通知;
b. UIControl特有的方法:{
子控制器中添加方法:
sendActionsForControlEvents(UIControlEvents.ValueChanged):向所有的actions發(fā)送相關(guān)的events
在父控制器中添加監(jiān)聽:
refreshView.addTarget(self, action: "loadData", forControlEvents: UIControlEvents.ValueChanged)
}
}
}