Pull to refresh in Swift, easy to use, easy to customize(下拉刷新/QQ/淘宝/优酷/雅虎天气/大众点评)
Clone or download
Type Name Latest commit message Commit time
Failed to load latest commit information.
Demo Adapt swift 4.2 Oct 7, 2018
PullToRefreshKit.xcodeproj Adapt swift 4.2 Oct 7, 2018
PullToRefreshKit Add framework project Jun 30, 2017
Screenshot Update example gif Aug 29, 2016
Source Adapt swift 4.2 Oct 7, 2018
.gitignore Inital commit Jul 13, 2016
.swift-version fix:add swfit version file Mar 8, 2018
.travis.yml Release 0.8.0 Nov 10, 2017
CHANGELOG.md Rename Protocol function Nov 13, 2017
LICENSE Inital commit Jul 13, 2016
PullToRefreshKit.podspec v0.8.8 Oct 7, 2018
README.md Update README Oct 7, 2018



Apps Using Downloads Version Platform Language License

The example project contains some hot App refresh example.

Taobao YouKu QQ Video
Yahoo Weather Dian Ping QQ


  • iOS 8
  • Swift 4+
  • XCode 9+

For Swift 3, See branch Swift3



  • Pull to refresh.
  • Pull/Tap to load more.
  • Pull left/right to load more(Currently only support chinese)
  • Elastic refresh
  • Easy to customize
  • English and Chinese



pod "PullToRefreshKit"


github "LeoMobileDeveloper/PullToRefreshKit"


What is a container? A container is the object that hold the scrollView reference, most time it is a UIViewController object

Pull down to refresh

self.tableView.configRefreshHeader(container:self) { [weak self] in
    delay(2, closure: {
        self?.tableView.switchRefreshHeader(to: .normal(.success, 0.5))

If you do not want any delay:

self.tableView.switchRefreshHeader(to: .normal(.none, 0.0))

Pull up to load more

Support three mode to fire refresh action

  • Tap
  • Scroll
  • Scroll and Tap
self.tableView.configRefreshFooter(container:self) { [weak self] in
	delay(1.5, closure: {
	    self?.tableView.switchRefreshFooter(to: .normal)

Remove footer:

self.tableView.switchRefreshFooter(to: .removed)

No more Data

self.tableView.switchRefreshFooter(to: .noMoreData)

Pull left to exit

scrollView.configSideRefresh(with: DefaultRefreshLeft.left(), container:self, at: .left) {
   self.navigationController?.popViewController(animated: true)

Pull right to Pop

let right  = DefaultRefreshRight.right()
right.setText("👈滑动关闭", mode: .scrollToAction)
right.setText("松开关闭", mode: .releaseToAction)
right.textLabel.textColor = UIColor.orange
scrollView.configSideRefresh(with: right, container:self, at: .right) { [weak self] in
    self?.navigationController?.popViewController(animated: true)

Config the default refresh text

PullToRefershKit offer SetUp operator,for example

let header = DefaultRefreshHeader.header()
header.setText("Pull to refresh", mode: .pullToRefresh)
header.setText("Release to refresh", mode: .releaseToRefresh)
header.setText("Success", mode: .refreshSuccess)
header.setText("Refreshing...", mode: .refreshing)
header.setText("Failed", mode: .refreshFailure)
header.tintColor = UIColor.orange
header.imageRenderingWithTintColor = true
header.durationWhenHide = 0.4
self.tableView.configRefreshHeader(with: header,container:self) { [weak self] in
    delay(1.5, closure: {
        self?.models = (self?.models.map({_ in random100()}))!
        self?.tableView.switchRefreshHeader(to: .normal(.success, 0.3))


You just need to write a UIView sub class,and make it conforms to these protocols

  • RefreshableHeader
  • RefreshableFooter
  • RefreshableLeftRight

For exmaple,to create a custom header

    //Height of the refresh header
    func heightForHeader()->CGFloat
    //Distance from top when in refreshing state
    func heightForRefreshingState()->CGFloat
    //Will enter refreshing state,change view state to refreshing in this function
    func didBeginrefreshingState()

    //The refreshing task is end.Refresh header will hide.Tell user the refreshing result here.
    func didBeginHideAnimation(result:RefreshResult)
    //Refresh header is hidden,reset all to inital state here
    func didCompleteHideAnimation(result:RefreshResult)
    //Distance to drag to fire refresh action ,default is heightForRefreshingState
    optional func heightForFireRefreshing()->CGFloat
    //Percent change during scrolling
    optional func percentUpdateDuringScrolling(percent:CGFloat)
    //Duration of header hide animation
    optional func durationOfHideAnimation()->Double


Leo, leomobiledeveloper@gmail.com


PullToRefreshKit is available under the MIT license. See the LICENSE file for more info.