CircleProgressButton
CircleProgressButton copied to clipboard
UIView based circle button with CAShapeLayer based progress stroke.
CircleProgressButton
UIView based circle button with CAShapeLayer based progress stroke.
Requirements
- iOS9+
- Swift4.2
How to use
Customize Appearance
Colors and icon images are fully customizable. Either override or set preferred values.
Actually there's no default
appearance, so have fun.👋
open var defaultImage: UIImage?
open var inProgressImage: UIImage?
open var suspendedImage: UIImage?
open var completedImage: UIImage?
open var inProgressStrokeColor: UIColor?
open var suspendedStrokeColor: UIColor?
open var completedStrokeColor: UIColor?
open var strokeMode: StrokeMode = .fill
open var touchedAlpha: CGFloat = 0.5
public var animated: Bool = true
UIImage's contentMode
is .center
. Make sure you provide correct size of image.
Update progress and state
-
state
: updates color and icon image -
progress
: updates stroke progress -
reset()
: mutates both state and progress -
complete()
: mutates both state and progress
It is possible to update progress while suspended.
state
is read-only. Update via suspend()
, resume()
, complete()
and reset()
.
Disable/Enable Animations
By default implicit CALayer's animations are enabled. You can disable or enable this behavior either by
- mutating
animationEnableOptions
property - Use
CircleProgressButton#animate(animationEnableOption:_:)
orCircleProgressButton#performWithoutAnimation(animationEnableOption:_:)
Handle Tap
private var token: CircleProgressButton.DisposeToken?
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
token = button.onTap { state in
switch state {
case .inProgress:
print("suspend")
self.suspendJob()
case .completed:
print("delete")
self.cancelJob()
case .default:
print("start")
self.resumeJob()
case .suspended:
print("resume")
self.resumeJob()
}
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
token?.dispose()
}
Using on UITableViewCell or UICollectionViewCell
Make sure you layout before letting CircleProgressButton
to calculate the circleWidth
.
SeeAlso:
- Example
- https://github.com/toshi0383/CircleProgressButton/issues/7
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell") as! TableViewCell
// IMPORTANT:
// frame is .zero after the first initialization of this cell.
// Make sure layout before letting CircleProgressButton.framework to calculate the `circleWidth`.
cell.layoutIfNeeded()
cell.circleProgressButton.progress = 50
cell.circleProgressButton.resume()
return cell
}
Using RxSwift
override func viewDidLoad() {
super.viewDidLoad()
button.tapGesture.rx.event
.subscribe(...)
// ...
}
For advanced touch interaction..
Feel free to assign your UIGestureRecognizerDelegate
.
button.tapGesture.delegate = self
License
MIT