Skip to content
This repository was archived by the owner on Jul 1, 2020. It is now read-only.

Commit 8f35d79

Browse files
Add taobao refresh header
1 parent 538d569 commit 8f35d79

8 files changed

Lines changed: 259 additions & 10 deletions

PullToRefreshKit.xcodeproj/project.pbxproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
52261F101D36878A00161ADF /* banner1.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 52261F0E1D36878A00161ADF /* banner1.jpg */; };
1313
52261F111D36878A00161ADF /* banner2.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 52261F0F1D36878A00161ADF /* banner2.jpg */; };
1414
52261F131D36879C00161ADF /* DefaultBannerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52261F121D36879C00161ADF /* DefaultBannerController.swift */; };
15+
5238C7D11D373B3300B3B4FE /* DefaultScrollViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5238C7D01D373B3300B3B4FE /* DefaultScrollViewController.swift */; };
16+
5238C7D31D37427C00B3B4FE /* TaoBaoRefreshHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5238C7D21D37427C00B3B4FE /* TaoBaoRefreshHeader.swift */; };
17+
5238C7D51D37449800B3B4FE /* CustomHeaderTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5238C7D41D37449800B3B4FE /* CustomHeaderTableViewController.swift */; };
18+
5238C7F51D3758A900B3B4FE /* CustomFooterTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5238C7F41D3758A900B3B4FE /* CustomFooterTableViewController.swift */; };
1519
52BB29171D3639500091F36B /* arrow_down@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 52BB290E1D3639500091F36B /* arrow_down@3x.png */; };
1620
52BB29181D3639500091F36B /* arrow_left@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 52BB290F1D3639500091F36B /* arrow_left@3x.png */; };
1721
52BB29191D3639500091F36B /* arrow_right@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 52BB29101D3639500091F36B /* arrow_right@3x.png */; };
@@ -41,6 +45,10 @@
4145
52261F0E1D36878A00161ADF /* banner1.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = banner1.jpg; sourceTree = "<group>"; };
4246
52261F0F1D36878A00161ADF /* banner2.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = banner2.jpg; sourceTree = "<group>"; };
4347
52261F121D36879C00161ADF /* DefaultBannerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DefaultBannerController.swift; sourceTree = "<group>"; };
48+
5238C7D01D373B3300B3B4FE /* DefaultScrollViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DefaultScrollViewController.swift; sourceTree = "<group>"; };
49+
5238C7D21D37427C00B3B4FE /* TaoBaoRefreshHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TaoBaoRefreshHeader.swift; sourceTree = "<group>"; };
50+
5238C7D41D37449800B3B4FE /* CustomHeaderTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomHeaderTableViewController.swift; sourceTree = "<group>"; };
51+
5238C7F41D3758A900B3B4FE /* CustomFooterTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomFooterTableViewController.swift; sourceTree = "<group>"; };
4452
52BB290E1D3639500091F36B /* arrow_down@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "arrow_down@3x.png"; sourceTree = "<group>"; };
4553
52BB290F1D3639500091F36B /* arrow_left@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "arrow_left@3x.png"; sourceTree = "<group>"; };
4654
52BB29101D3639500091F36B /* arrow_right@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "arrow_right@3x.png"; sourceTree = "<group>"; };
@@ -119,6 +127,7 @@
119127
children = (
120128
52BB29311D364E490091F36B /* DefaultTableViewController.swift */,
121129
52261F0A1D36730F00161ADF /* DefaultCollectionViewController.swift */,
130+
5238C7D01D373B3300B3B4FE /* DefaultScrollViewController.swift */,
122131
52261F121D36879C00161ADF /* DefaultBannerController.swift */,
123132
52261F0C1D36832600161ADF /* ConfigHeaderFooterController.swift */,
124133
52C0E4871D3726EB00618231 /* ConfigBannerController.swift */,
@@ -129,6 +138,9 @@
129138
52BB292C1D364C390091F36B /* Custom */ = {
130139
isa = PBXGroup;
131140
children = (
141+
5238C7D21D37427C00B3B4FE /* TaoBaoRefreshHeader.swift */,
142+
5238C7D41D37449800B3B4FE /* CustomHeaderTableViewController.swift */,
143+
5238C7F41D3758A900B3B4FE /* CustomFooterTableViewController.swift */,
132144
);
133145
name = Custom;
134146
sourceTree = "<group>";
@@ -256,19 +268,23 @@
256268
buildActionMask = 2147483647;
257269
files = (
258270
52BB291E1D3639500091F36B /* PullToRefreshKit.swift in Sources */,
271+
5238C7F51D3758A900B3B4FE /* CustomFooterTableViewController.swift in Sources */,
259272
52BB291D1D3639500091F36B /* Left.swift in Sources */,
260273
52BB29281D3644D00091F36B /* SectionModel.swift in Sources */,
261274
52BB291F1D3639500091F36B /* Right.swift in Sources */,
262275
52BB291A1D3639500091F36B /* Const.swift in Sources */,
263276
52261F131D36879C00161ADF /* DefaultBannerController.swift in Sources */,
277+
5238C7D31D37427C00B3B4FE /* TaoBaoRefreshHeader.swift in Sources */,
264278
52E8FB421D336E26000D0BF1 /* MainViewController.swift in Sources */,
265279
52E8FB401D336E26000D0BF1 /* AppDelegate.swift in Sources */,
266280
52BB29341D3655B90091F36B /* Util.swift in Sources */,
281+
5238C7D51D37449800B3B4FE /* CustomHeaderTableViewController.swift in Sources */,
267282
52261F0B1D36730F00161ADF /* DefaultCollectionViewController.swift in Sources */,
268283
52261F0D1D36832600161ADF /* ConfigHeaderFooterController.swift in Sources */,
269284
52C0E4881D3726EB00618231 /* ConfigBannerController.swift in Sources */,
270285
52BB291C1D3639500091F36B /* Header.swift in Sources */,
271286
52BB29321D364E490091F36B /* DefaultTableViewController.swift in Sources */,
287+
5238C7D11D373B3300B3B4FE /* DefaultScrollViewController.swift in Sources */,
272288
52BB292E1D364C6D0091F36B /* RowModel.swift in Sources */,
273289
52BB291B1D3639500091F36B /* Footer.swift in Sources */,
274290
);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//
2+
// CustomFooterController.swift
3+
// PullToRefreshKit
4+
//
5+
// Created by huangwenchen on 16/7/14.
6+
// Copyright © 2016年 Leo. All rights reserved.
7+
//
8+
9+
import Foundation
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//
2+
// CustomHeaderTableViewController.swift
3+
// PullToRefreshKit
4+
//
5+
// Created by huangwenchen on 16/7/14.
6+
// Copyright © 2016年 Leo. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import UIKit
11+
class CustomHeaderTableViewController:UITableViewController{
12+
var models = [1,2,3,4,5,6,7,8,9,10]
13+
override func viewDidLoad() {
14+
super.viewDidLoad()
15+
self.tableView.tableFooterView = UIView(frame: CGRectZero)
16+
17+
let taobaoHeader = TaoBaoRefreshHeader(frame: CGRectMake(0,0,CGRectGetWidth(self.view.bounds),80))
18+
self.tableView.setUpHeaderRefresh(taobaoHeader) { [weak self] in
19+
delay(1.5, closure: {
20+
self?.models = (self?.models.map({_ in random100()}))!
21+
self?.tableView.reloadData()
22+
self?.tableView.endHeaderRefreshing(.Success)
23+
})
24+
}
25+
self.tableView.beginHeaderRefreshing()
26+
}
27+
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
28+
return models.count
29+
}
30+
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
31+
return 44.0
32+
}
33+
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
34+
var cell = tableView.dequeueReusableCellWithIdentifier("cell")
35+
if cell == nil {
36+
cell = UITableViewCell(style: .Default, reuseIdentifier: "cell")
37+
}
38+
cell?.textLabel?.text = "\(models[indexPath.row])"
39+
return cell!
40+
}
41+
deinit{
42+
print("Deinit of DefaultTableViewController")
43+
}
44+
}

PullToRefreshKit/DefaultCollectionViewController.swift

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,44 @@
77
//
88

99
import Foundation
10+
import UIKit
11+
12+
class DefaultCollectionViewController:UIViewController,UICollectionViewDataSource{
13+
var collectionView:UICollectionView?
14+
override func viewDidLoad() {
15+
self.view.backgroundColor = UIColor.whiteColor()
16+
self.setUpCollectionView()
17+
self.collectionView?.setUpHeaderRefresh({ [weak self] in
18+
delay(1.0, closure: {
19+
self?.collectionView?.endHeaderRefreshing(.Success)
20+
});
21+
})
22+
self.collectionView?.setUpFooterRefresh({ [weak self] in
23+
delay(1.0, closure: {
24+
self?.collectionView?.endFooterRefreshing()
25+
});
26+
})
27+
}
28+
func setUpCollectionView(){
29+
let flowLayout = UICollectionViewFlowLayout()
30+
flowLayout.scrollDirection = UICollectionViewScrollDirection.Vertical
31+
flowLayout.itemSize = CGSizeMake(100, 100)
32+
self.collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: flowLayout)
33+
self.collectionView?.backgroundColor = UIColor.whiteColor()
34+
self.collectionView?.dataSource = self
35+
self.view.addSubview(self.collectionView!)
36+
37+
self.collectionView?.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
38+
}
39+
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
40+
return 21
41+
}
42+
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
43+
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath)
44+
cell.backgroundColor = UIColor.lightGrayColor()
45+
return cell
46+
}
47+
deinit{
48+
print("Deinit of DefaultCollectionViewController")
49+
}
50+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//
2+
// DefaultScrollViewController.swift
3+
// PullToRefreshKit
4+
//
5+
// Created by huangwenchen on 16/7/14.
6+
// Copyright © 2016年 Leo. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import UIKit
11+
12+
class DefaultScrollViewController:UIViewController{
13+
var scrollView:UIScrollView?
14+
override func viewDidLoad() {
15+
super.viewDidLoad()
16+
self.view.backgroundColor = UIColor.whiteColor()
17+
self.automaticallyAdjustsScrollViewInsets = false
18+
setUpScrollView()
19+
scrollView?.setUpHeaderRefresh({ [weak self] in
20+
delay(1.0, closure: {
21+
self?.scrollView?.endHeaderRefreshing()
22+
})
23+
}).SetUp({ (header) in
24+
header.textLabel.textColor = UIColor.whiteColor()
25+
header.spinner.activityIndicatorViewStyle = .White
26+
})
27+
}
28+
func setUpScrollView(){
29+
self.scrollView = UIScrollView(frame: CGRectMake(0,0,300,300))
30+
self.scrollView?.backgroundColor = UIColor.lightGrayColor()
31+
self.scrollView?.center = self.view.center
32+
self.scrollView?.contentSize = CGSizeMake(300,600)
33+
self.view.addSubview(self.scrollView!)
34+
}
35+
}

PullToRefreshKit/MainViewController.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ class MainViewController: UITableViewController {
1515
let section0 = SectionModel(rowsCount: 4,
1616
sectionTitle:"默认",
1717
rowsTitles: ["Tableview","CollectionView","ScrollView","Banners"],
18-
rowsTargetControlerNames:["DefaultTableViewController","DefaultLeftController","DefaultRightController","DefaultBannerController",])
18+
rowsTargetControlerNames:["DefaultTableViewController","DefaultCollectionViewController","DefaultScrollViewController","DefaultBannerController",])
1919
let section1 = SectionModel(rowsCount: 2,
2020
sectionTitle:"属性配置",
2121
rowsTitles: ["配置Header/Footer属性","配置Left/Right属性"],
2222
rowsTargetControlerNames:["ConfigDefaultHeaderFooterController","ConfigBannerController"])
23-
let section2 = SectionModel(rowsCount: 4,
23+
let section2 = SectionModel(rowsCount: 1,
2424
sectionTitle:"自定义",
25-
rowsTitles: ["自定义header","自定义Footer","自定义left","自定义Right"],
26-
rowsTargetControlerNames:["DefaultHeaderController","DefaultFooterController","DefaultLeftController","DefaultRightController"])
25+
rowsTitles: ["淘宝下拉刷新",],
26+
rowsTargetControlerNames:["CustomHeaderTableViewController"])
2727
models.append(section0)
2828
models.append(section1)
2929
models.append(section2)

PullToRefreshKit/PullToRefreshKit.swift

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,24 +52,26 @@ extension NSObject: SetUp {}
5252
//Header
5353
extension UIScrollView{
5454
func setUpHeaderRefresh(action:()->())->DefaultRefreshHeader{
55+
let header = DefaultRefreshHeader(frame:CGRectMake(0,0,CGRectGetWidth(self.frame),PullToRefreshKitConst.defaultHeaderHeight))
56+
return setUpHeaderRefresh(header, action: action)
57+
}
58+
59+
func setUpHeaderRefresh<T:UIView where T:RefreshableHeader>(header:T,action:()->())->T{
5560
let oldContain = self.viewWithTag(PullToRefreshKitConst.headerTag)
5661
oldContain?.removeFromSuperview()
57-
let frame = CGRectMake(0,-1 * PullToRefreshKitConst.defaultHeaderHeight,CGRectGetWidth(self.frame), PullToRefreshKitConst.defaultHeaderHeight)
62+
let height = header.distanceToRefresh()
63+
let frame = CGRectMake(0,-1 * height,CGRectGetWidth(self.frame),height)
5864
let containComponent = RefreshHeaderContainer(frame: frame)
5965
containComponent.tag = PullToRefreshKitConst.headerTag
6066
containComponent.refreshAction = action
6167
self.addSubview(containComponent)
6268

63-
let header = DefaultRefreshHeader(frame: containComponent.bounds)
6469
containComponent.delegate = header
6570
header.autoresizingMask = [.FlexibleWidth,.FlexibleHeight]
71+
header.frame = containComponent.bounds
6672
containComponent.addSubview(header)
6773
return header
6874
}
69-
70-
func setUpHeaderRefresh<T:UIView where T:RefreshableHeader>(componnet:T,action:()->()){
71-
72-
}
7375
func beginHeaderRefreshing(){
7476
let header = self.viewWithTag(PullToRefreshKitConst.headerTag) as? RefreshHeaderContainer
7577
header?.beginRefreshing()
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
//
2+
// TaoBaoRefreshHeader.swift
3+
// PullToRefreshKit
4+
//
5+
// Created by huangwenchen on 16/7/14.
6+
// Copyright © 2016年 Leo. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import UIKit
11+
12+
class TaoBaoRefreshHeader:UIView,RefreshableHeader{
13+
private let circleLayer = CAShapeLayer()
14+
private let arrowLayer = CAShapeLayer()
15+
private let textLabel = UILabel()
16+
17+
override init(frame: CGRect) {
18+
super.init(frame: frame)
19+
setUpCircleLayer()
20+
setUpArrowLayer()
21+
textLabel.frame = CGRectMake(CGRectGetWidth(self.bounds)/2 - 30, CGRectGetHeight(self.bounds)/2 - 20,120, 40)
22+
textLabel.textAlignment = .Center
23+
textLabel.font = UIFont.systemFontOfSize(14)
24+
textLabel.text = "下拉即可刷新..."
25+
self.addSubview(textLabel)
26+
}
27+
func setUpArrowLayer(){
28+
let bezierPath = UIBezierPath()
29+
bezierPath.moveToPoint(CGPointMake(20, 10))
30+
bezierPath.addLineToPoint(CGPointMake(20, 30))
31+
bezierPath.addLineToPoint(CGPointMake(25,25))
32+
bezierPath.moveToPoint(CGPointMake(20, 30))
33+
bezierPath.addLineToPoint(CGPointMake(15, 25))
34+
self.arrowLayer.path = bezierPath.CGPath
35+
self.arrowLayer.strokeColor = UIColor.blackColor().CGColor
36+
self.arrowLayer.fillColor = UIColor.clearColor().CGColor
37+
self.arrowLayer.lineWidth = 1.0
38+
self.arrowLayer.lineCap = kCALineCapRound
39+
self.arrowLayer.bounds = CGRectMake(0, 0,40, 40)
40+
self.arrowLayer.position = CGPointMake(CGRectGetWidth(self.bounds)/2.0 - 60, CGRectGetHeight(self.bounds)/2.0)
41+
self.arrowLayer.anchorPoint = CGPointMake(0.5, 0.5)
42+
self.layer.addSublayer(self.arrowLayer)
43+
}
44+
func setUpCircleLayer(){
45+
let bezierPath = UIBezierPath(arcCenter: CGPointMake(20, 20),
46+
radius: 15.0,
47+
startAngle:CGFloat(-M_PI/2),
48+
endAngle: CGFloat(M_PI_2 * 3),
49+
clockwise: true)
50+
self.circleLayer.path = bezierPath.CGPath
51+
self.circleLayer.strokeColor = UIColor.blackColor().CGColor
52+
self.circleLayer.fillColor = UIColor.clearColor().CGColor
53+
self.circleLayer.strokeStart = 0.05
54+
self.circleLayer.strokeEnd = 0.05
55+
self.circleLayer.lineWidth = 1.0
56+
self.circleLayer.lineCap = kCALineCapRound
57+
self.circleLayer.bounds = CGRectMake(0, 0,40, 40)
58+
self.circleLayer.position = CGPointMake(CGRectGetWidth(self.bounds)/2.0 - 60, CGRectGetHeight(self.bounds)/2.0)
59+
self.circleLayer.anchorPoint = CGPointMake(0.5, 0.5)
60+
self.layer.addSublayer(self.circleLayer)
61+
}
62+
required init?(coder aDecoder: NSCoder) {
63+
fatalError("init(coder:) has not been implemented")
64+
}
65+
66+
// MARK: - RefreshableHeader -
67+
func distanceToRefresh()->CGFloat{
68+
return 60
69+
}
70+
func didBeginRefreshing(){
71+
72+
}
73+
func percentageChangedDuringDragging(percent:CGFloat){
74+
let adjustPercent = max(min(1.0, percent),0.0)
75+
self.circleLayer.strokeEnd = 0.05 + (0.95 - 0.05) * adjustPercent
76+
if adjustPercent == 1.0{
77+
textLabel.text = "释放即可刷新..."
78+
}else{
79+
textLabel.text = "下拉即可刷新..."
80+
}
81+
}
82+
func willBeginRefreshing(){
83+
self.circleLayer.strokeEnd = 0.95
84+
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
85+
rotateAnimation.toValue = NSNumber(double: M_PI * 2.0)
86+
rotateAnimation.duration = 0.6
87+
rotateAnimation.cumulative = true
88+
rotateAnimation.repeatCount = 10000000
89+
self.circleLayer.addAnimation(rotateAnimation, forKey: "rotate")
90+
self.arrowLayer.hidden = true
91+
textLabel.text = "刷新中..."
92+
}
93+
func willEndRefreshing(result:RefreshResult){
94+
self.circleLayer.strokeEnd = 0.05
95+
self.circleLayer.removeAllAnimations()
96+
}
97+
func didEndRefreshing(result:RefreshResult){
98+
self.circleLayer.strokeEnd = 0.05
99+
self.arrowLayer.hidden = false
100+
textLabel.text = "下拉即可刷新"
101+
}
102+
}

0 commit comments

Comments
 (0)