ZVRefreshing is a pure-swift and wieldy refresh component.
- iOS 8.0+
Swift Version | Repo Version |
---|---|
Swift 5.0 | > 2.2.0 |
Swift 4.2 | < 2.1.3 |
CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects.
You can install Cocoapod with the following command
$ sudo gem install cocoapods
To integrate ZVRefreshing
into your project using CocoaPods, specify it into your Podfile
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
target 'TargetName' do
use_frameworks!
pod 'ZVRefreshing' ~> '2.0.0'
end
Then,install your dependencies with CocoaPods.
$ pod install
Carthage is intended to be the simplest way to add frameworks to your application.
You can install Carthage with Homebrew using following command:
$ brew update
$ brew install carthage
To integrate ZVRefreshing
into your project using Carthage, specify it into your Cartfile
github "zevwings/ZVRefreshing" ~> 0.0.1
Then,build the framework with Carthage
using carthage update
and drag ZVRefreshing.framework
into your project.
The framework is under the Carthage/Build, and you should drag it into Target
-> Genral
-> Embedded Binaries
Download this project, And drag ZRefreshing.xcodeproj
into your own project.
In your target’s General tab, click the ’+’ button under Embedded Binaries
Select the ZRefreshing.framework
to Add to your platform.
You can use online demo on Appetize
When you need add a refresh widget, you can use import ZVRefreshing
There is three ways to initialize this widget.
- Target-Action
let header = ZVRefreshNormalHeader(target: NSObject, action: Selector)
self.tableView.header = header
- Block
let header = ZVRefreshNormalHeader(refreshHandler: { [weak self] in
// your codes
})
self.tableView.header = header
- None-parameters
let header = RefreshHeader()
self.tableView.header = header
if you initialize the widget by none-parameters way, you can add refresh handler block or target-action with following code:
- add a refresh handler
// add refresh handler
header?.refreshHandler = {
// your codes
}
- add a Target-Action
// add refresh target-action
header?.addTarget(Any?, action: Selector)
- add a Target-Action-UIControlEvents.valueChanged
// The ZVRefreshComponent extend from UIControl, When isRefreshing properties changed will send a UIControlEvents.valueChanged event.
header?.addTarget(Any, action: Selector, for: .valueChanged)
The functions is same for header and footer.
- beginRefreshing()
The widget begin enter into refreshing status.
self.tableView.header?.beginRefreshing()
- endRefreshing()
The widge begin enter into idle status.
self.tableView.header?.endRefreshing()
- setTitle(_:forState:)
To custom the title for widget, this function in
ZVRefreshStateHeader
.
header.setTitle("pull to refresh...", forState: .idle)
header.setTitle("release to refresh...", forState: .pulling)
header.setTitle("loading...", forState: .refreshing)
or
footer.setTitle("pull to refresh...", forState: .idle)
footer.setTitle("release to refresh...", forState: .pulling)
footer.setTitle("loading...", forState: .refreshing)
footer.setTitle("no more data", forState: .noMoreData)
- setImages(_:forState:)
To custom the images for widget, this function in
ZVRefreshAnimationHeader
, you can use it as following code, also you can extend a subclass, like Example
self.setImages(idleImages, forState: .idle)
self.setImages(refreshingImages, forState: .pulling)
self.setImages(refreshingImages, forState: .refreshing)
- lastUpdatedTimeKey
To storage the last time using this widget, if it dose not set, all your widget will shared a key
com.zevwings.refreshing.lastUpdateTime
header.lastUpdatedTimeKey = "custom last updated key"
- ignoredScrollViewContentInsetTop
when your table set contentInset
property, you should set it, for example:
self.tableView.contentInset = UIEdgeInsets(top: 30, left: 0, bottom:0, right: 0)
header.ignoredScrollViewContentInsetTop = 30
- lastUpdatedTimeLabel
To custom the UILabel
properties for lastUpdatedTimeLabel
, for example:
// hide the lastUpdatedTimeLabel
header.lastUpdatedTimeLabel.isHidden = true
or
// set the font for lastUpdatedTimeLabel
header.lastUpdatedTimeLabel.font = .systemFont(ofSize: 16.0)
- lastUpdatedTimeLabelText
To custom the format for showing last time.
header.lastUpdatedTimeLabelText = { date in
if let d = date {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
return "Last updated:\(formatter.string(from: d))"
}
return "There is no record"
}
- isAutomaticallyHidden
To set the automatically hidden for widget, default is
true
footer.isAutomaticallyHidden = false
- ignoredScrollViewContentInsetBottom
when your table set
contentInset
property, you should set it, for example:
self.tableView.contentInset = UIEdgeInsets(top:0, left: 0, bottom:30, right: 0)
footer.ignoredScrollViewContentInsetBottom = 30
- isAutomaticallyRefresh
To set the automatically refresh for widget, default is
true
, this property inZVRefreshAutoFooter
footer.isAutomaticallyRefresh = false
The following properties is same for header and footer.
- labelInsetLeft To set the empty width between activityIndicator an label.
header.labelInsetLeft = 32.0
-
activityIndicator To custom the properties for
activityIndicator
, the properties @see ZActivityIndicatorView -
tintColor To custom the color for all sub-widget.
header.tintColor = .black
- stateLabel
To custom the
UILabel
properties forstateLabel
, for example:
// hide the stateLabel
header.stateLabel.isHidden = true
or
// set the font for stateLabel
header.stateLabel.font = .systemFont(ofSize: 16.0)
- animationView
To custom the UIImageView
properties for stateLabel
, for example:
You can extend ZVRefreshComponent
or it's sub-class to custom your own refresh widget.
like Example.
- state
To custom you needed when refresh state changed.
open var state: ZVRefreshComponent.State
- pullingPercent
To custom you needed when widget position changed.
open var pullingPercent: CGFloat
- tintColor
To custom you own widget color.
open override var tintColor: UIColor!
- prepare
To define your own controls, call at init(frame: CGRect)
.
open func prepare() {}
- placeSubViews
To set your own constrols size and position, call at layoutSubviews()
.
open func placeSubViews() {}
- scrollViewContentOffsetDidChanged
To observe the UIScrollView.contentOffset, call at UIScrollView.contentOffset
value changed.
open func scrollViewContentOffsetDidChanged(_ change: [NSKeyValueChangeKey: Any]?) {}
- scrollViewContentSizeDidChanged
To observe the UIScrollView.contentSize, call at UIScrollView.contentSize
value changed.
open func scrollViewContentSizeDidChanged(_ change: [NSKeyValueChangeKey: Any]?) {}
- scrollViewPanStateDidChanged
To observe the UIScrollView.panGestureRecognizer.state, call at UIScrollView.panGestureRecognizer.state
value changed.
open func scrollViewPanStateDidChanged(_ change: [NSKeyValueChangeKey: Any]?) {}
If you want use RxSwift, refer to ZVRefreshing+Rx.swift.
Then, you can use the follow codes to start a refresh action.
Observable.just(true)
.asDriver(onErrorJustReturn: false)
.drive(flatHeader!.rx.isRefreshing)
.disposed(by: disposeBag)
Or, you can use this codes to observe the refreshing state.
flatHeader?.rx.refresh
.subscribe(onNext: { isRefreshing in
print("onNext isRefreshing : \(isRefreshing)")
}, onError: { err in
print("err : \(err)")
}, onCompleted: {
print("completed")
}, onDisposed: {
print("disposed")
}).disposed(by: disposeBag)
You can refer to the Example for more usage.
You can issue me on GitHub or send a emailzev.wings@gmail.com. If you have a good idea, tell me. thanks.
ZVRefreshing
distributed under the terms and conditions of the MIT License.