Material Design Floating Action Button in liquid state

Last update: Jun 15, 2022

LiquidFloatingActionButton

CI Status Version License Platform [Carthage compatible] (https://github.com/Carthage/Carthage)

LiquidFloatingActionButton is floating action button component of material design in liquid state, inspired by Material In a Liquid State. This is also spinner loader components in liquid state.

Demo

Features

  • liquid animation
  • Easily customizable
  • Objective-C compatible
  • Swift 2.0

You can play a demo with appetize.io

Usage

You just need implement LiquidFloatingActionButtonDataSource and LiquidFloatingActionButtonDelegate similar to well-known UIKit design.

let floatingActionButton = LiquidFloatingActionButton(frame: floatingFrame)
floatingActionButton.dataSource = self
floatingActionButton.delegate = self

LiquidFloatingActionButtonDataSource

func numberOfCells(liquidFloatingActionButton: LiquidFloatingActionButton) -> Int
func cellForIndex(index: Int) -> LiquidFloatingCell

LiquidFloatingActionButtonDelegate

optional func liquidFloatingActionButton(liquidFloatingActionButton: LiquidFloatingActionButton, didSelectItemAtIndex index: Int)

Easily customizable

Demo

Installation

LiquidFloatingActionButton is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "LiquidFloatingActionButton"

or, if you use Carthage, add the following line to your Carthage file.

github "yoavlt/LiquidFloatingActionButton"

License

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

GitHub

https://github.com/yoavlt/LiquidFloatingActionButton
Comments
  • 1. Scrolling with the Floating Button

    I just found out that, I've a floating button in a tableView. When I'm trying to scroll the tableView, the floating button doesn't scroll with tableView, it just stick to its position. How do I fix this problem? img_0101 img_0102

    Reviewed by jefferyleo at 2015-12-07 09:49
  • 2. Method does not override any method from its superclass

    Hey,

    Im getting no less than 7 fatal errors and 7 warnings when trying to build after importing. Im using Objective C, and importing the swift file into my app - but thats not the problem. the problems are all within the Pod project itself - i get 7 "Method does not override any method from its superclass" - is there a fix? or did i just suck at importing? :-)

    skaermbillede 2015-10-11 kl 17 21 49

    Reviewed by Big-al at 2015-10-11 15:24
  • 3. Can not run because library not loaded.

    I installed it by CocoaPods. I added the following line to your Podfile: pod 'LiquidFloatingActionButton', :git => 'https://github.com/yoavlt/LiquidFloatingActionButton.git', :branch => 'swift-2.0' And installed it. But run it, it must crash. This is a error: I want to help!!

    Reviewed by lynnx4869 at 2016-06-08 08:59
  • 4. Adding Tap Gesture recogniser

    I would like to know when the floating action cell is tapped so that i can close it programmatically. However, adding a tap gesture recognizer to the floating cell 'breaks' it. In the sense that it wont open. Is this a know issue? is there a fix around it?

    Reviewed by ank1t at 2015-09-27 05:47
  • 5. Doesn't work with AutoLayout.

    Hi,

    See the attached video... I changed your Example code to use AutoLayout... doesn't work well with animations!

    Animation Video --> http://cl.ly/151O3K0F3i03 Your Example code modified to worth with AutoLayout --> http://cl.ly/2N0T2t0s323g

    Reviewed by syedhassan at 2015-10-26 01:26
  • 6. After running pod install and building my project, I get a bunch of errors shown below

    screen shot 2016-04-19 at 9 01 30 pm

    As you can see there are 6 errors within the LiquidFloatingActionButton.swift file. I have also included the file below.

    // // LiquidFloatingActionButton.swift // Pods // // Created by Takuma Yoshida on 2015/08/25. // //

    import Foundation import QuartzCore

    // LiquidFloatingButton DataSource methods @objc public protocol LiquidFloatingActionButtonDataSource { func numberOfCells(liquidFloatingActionButton: LiquidFloatingActionButton) -> Int func cellForIndex(index: Int) -> LiquidFloatingCell }

    @objc public protocol LiquidFloatingActionButtonDelegate { // selected method optional func liquidFloatingActionButton(liquidFloatingActionButton: LiquidFloatingActionButton, didSelectItemAtIndex index: Int) }

    public enum LiquidFloatingActionButtonAnimateStyle : Int { case Up case Right case Left case Down }

    @IBDesignable public class LiquidFloatingActionButton : UIView {

    private let internalRadiusRatio: CGFloat = 20.0 / 56.0
    public var cellRadiusRatio: CGFloat      = 0.38
    public var animateStyle: LiquidFloatingActionButtonAnimateStyle = .Up {
        didSet {
            baseView.animateStyle = animateStyle
        }
    }
    public var enableShadow = true {
        didSet {
            setNeedsDisplay()
        }
    }
    
    public var delegate:   LiquidFloatingActionButtonDelegate?
    public var dataSource: LiquidFloatingActionButtonDataSource?
    
    public var responsible = true
    public var isOpening: Bool  {
        get {
            return !baseView.openingCells.isEmpty
        }
    }
    public private(set) var isClosed: Bool = true
    
    @IBInspectable public var color: UIColor = UIColor(red: 82 / 255.0, green: 112 / 255.0, blue: 235 / 255.0, alpha: 1.0) {
        didSet {
            baseView.color = color
        }
    }
    
    @IBInspectable public var image: UIImage? {
        didSet {
            if image != nil {
                plusLayer.contents = image!.CGImage
                plusLayer.path = nil
            }
        }
    }
    
    @IBInspectable public var rotationDegrees: CGFloat = 45.0
    
    private var plusLayer   = CAShapeLayer()
    private let circleLayer = CAShapeLayer()
    
    private var touching = false
    
    private var baseView = CircleLiquidBaseView()
    private let liquidView = UIView()
    
    public override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }
    
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }
    
    private func insertCell(cell: LiquidFloatingCell) {
        cell.color  = self.color
        cell.radius = self.frame.width * cellRadiusRatio
        cell.center = self.center.minus(self.frame.origin)
        cell.actionButton = self
        insertSubview(cell, aboveSubview: baseView)
    }
    
    private func cellArray() -> [LiquidFloatingCell] {
        var result: [LiquidFloatingCell] = []
        if let source = dataSource {
            for i in 0..<source.numberOfCells(self) {
                result.append(source.cellForIndex(i))
            }
        }
        return result
    }
    
    // open all cells
    public func open() {
    
        // rotate plus icon
        CATransaction.setAnimationDuration(0.8)
        self.plusLayer.transform = CATransform3DMakeRotation((CGFloat(M_PI) * rotationDegrees) / 180, 0, 0, 1)
    
        let cells = cellArray()
        for cell in cells {
            insertCell(cell)
        }
    
        self.baseView.open(cells)
    
        self.isClosed = false
    }
    
    // close all cells
    public func close() {
    
        // rotate plus icon
        CATransaction.setAnimationDuration(0.8)
        self.plusLayer.transform = CATransform3DMakeRotation(0, 0, 0, 1)
    
        self.baseView.close(cellArray())
    
        self.isClosed = true
    }
    
    // MARK: draw icon
    public override func drawRect(rect: CGRect) {
        drawCircle()
        drawShadow()
    }
    
    /// create, configure & draw the plus layer (override and create your own shape in subclass!)
    public func createPlusLayer(frame: CGRect) -> CAShapeLayer {
    
        // draw plus shape
        let plusLayer = CAShapeLayer()
        plusLayer.lineCap = kCALineCapRound
        plusLayer.strokeColor = UIColor.whiteColor().CGColor
        plusLayer.lineWidth = 3.0
    
        let path = UIBezierPath()
        path.moveToPoint(CGPoint(x: frame.width * internalRadiusRatio, y: frame.height * 0.5))
        path.addLineToPoint(CGPoint(x: frame.width * (1 - internalRadiusRatio), y: frame.height * 0.5))
        path.moveToPoint(CGPoint(x: frame.width * 0.5, y: frame.height * internalRadiusRatio))
        path.addLineToPoint(CGPoint(x: frame.width * 0.5, y: frame.height * (1 - internalRadiusRatio)))
    
        plusLayer.path = path.CGPath
        return plusLayer
    }
    
    private func drawCircle() {
        self.circleLayer.cornerRadius = self.frame.width * 0.5
        self.circleLayer.masksToBounds = true
        if touching && responsible {
            self.circleLayer.backgroundColor = self.color.white(0.5).CGColor
        } else {
            self.circleLayer.backgroundColor = self.color.CGColor
        }
    }
    
    private func drawShadow() {
        if enableShadow {
            circleLayer.appendShadow()
        }
    }
    
    // MARK: Events
    public override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.touching = true
        setNeedsDisplay()
    }
    
    public override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.touching = false
        setNeedsDisplay()
        didTapped()
    }
    
    public override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
        self.touching = false
        setNeedsDisplay()
    }
    
    public override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
        for cell in cellArray() {
            let pointForTargetView = cell.convertPoint(point, fromView: self)
    
            if (CGRectContainsPoint(cell.bounds, pointForTargetView)) {
                if cell.userInteractionEnabled {
                    return cell.hitTest(pointForTargetView, withEvent: event)
                }
            }
        }
    
        return super.hitTest(point, withEvent: event)
    }
    
    // MARK: private methods
    private func setup() {
        self.backgroundColor = UIColor.clearColor()
        self.clipsToBounds = false
    
        baseView.setup(self)
        addSubview(baseView)
    
        liquidView.frame = baseView.frame
        liquidView.userInteractionEnabled = false
        addSubview(liquidView)
    
        liquidView.layer.addSublayer(circleLayer)
        circleLayer.frame = liquidView.layer.bounds
    
        plusLayer = createPlusLayer(circleLayer.bounds)
        circleLayer.addSublayer(plusLayer)
        plusLayer.frame = circleLayer.bounds
    }
    
    private func didTapped() {
        if isClosed {
            open()
        } else {
            close()
        }
    }
    
    public func didTappedCell(target: LiquidFloatingCell) {
        if let _ = dataSource {
            let cells = cellArray()
            for i in 0..<cells.count {
                let cell = cells[i]
                if target === cell {
                    delegate?.liquidFloatingActionButton?(self, didSelectItemAtIndex: i)
                }
            }
        }
    }
    

    }

    class ActionBarBaseView : UIView { var opening = false func setup(actionButton: LiquidFloatingActionButton) { }

    func translateY(layer: CALayer, duration: CFTimeInterval, f: (CABasicAnimation) -> ()) {
        let translate = CABasicAnimation(keyPath: "transform.translation.y")
        f(translate)
        translate.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        translate.removedOnCompletion = false
        translate.fillMode = kCAFillModeForwards
        translate.duration = duration
        layer.addAnimation(translate, forKey: "transYAnim")
    }
    

    }

    class CircleLiquidBaseView : ActionBarBaseView {

    let openDuration: CGFloat  = 0.6
    let closeDuration: CGFloat = 0.2
    let viscosity: CGFloat     = 0.65
    var animateStyle: LiquidFloatingActionButtonAnimateStyle = .Up
    var color: UIColor = UIColor(red: 82 / 255.0, green: 112 / 255.0, blue: 235 / 255.0, alpha: 1.0) {
        didSet {
            engine?.color = color
            bigEngine?.color = color
        }
    }
    
    var baseLiquid: LiquittableCircle?
    var engine:     SimpleCircleLiquidEngine?
    var bigEngine:  SimpleCircleLiquidEngine?
    var enableShadow = true
    
    private var openingCells: [LiquidFloatingCell] = []
    private var keyDuration: CGFloat = 0
    private var displayLink: CADisplayLink?
    
    override func setup(actionButton: LiquidFloatingActionButton) {
        self.frame = actionButton.frame
        self.center = actionButton.center.minus(actionButton.frame.origin)
        self.animateStyle = actionButton.animateStyle
        let radius = min(self.frame.width, self.frame.height) * 0.5
        self.engine = SimpleCircleLiquidEngine(radiusThresh: radius * 0.73, angleThresh: 0.45)
        engine?.viscosity = viscosity
        self.bigEngine = SimpleCircleLiquidEngine(radiusThresh: radius, angleThresh: 0.55)
        bigEngine?.viscosity = viscosity
        self.engine?.color = actionButton.color
        self.bigEngine?.color = actionButton.color
    
        baseLiquid = LiquittableCircle(center: self.center.minus(self.frame.origin), radius: radius, color: actionButton.color)
        baseLiquid?.clipsToBounds = false
        baseLiquid?.layer.masksToBounds = false
    
        clipsToBounds = false
        layer.masksToBounds = false
        addSubview(baseLiquid!)
    }
    
    func open(cells: [LiquidFloatingCell]) {
        stop()
        displayLink = CADisplayLink(target: self, selector: #selector(CircleLiquidBaseView.didDisplayRefresh(_:)))
        displayLink?.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)
        opening = true
        for cell in cells {
            cell.layer.removeAllAnimations()
            cell.layer.eraseShadow()
            openingCells.append(cell)
        }
    }
    
    func close(cells: [LiquidFloatingCell]) {
        stop()
        opening = false
        displayLink = CADisplayLink(target: self, selector: #selector(CircleLiquidBaseView.didDisplayRefresh(_:)))
        displayLink?.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)
        for cell in cells {
            cell.layer.removeAllAnimations()
            cell.layer.eraseShadow()
            openingCells.append(cell)
            cell.userInteractionEnabled = false
        }
    }
    
    func didFinishUpdate() {
        if opening {
            for cell in openingCells {
                cell.userInteractionEnabled = true
            }
        } else {
            for cell in openingCells {
                cell.removeFromSuperview()
            }
        }
    }
    
    func update(delay: CGFloat, duration: CGFloat, f: (LiquidFloatingCell, Int, CGFloat) -> ()) {
        if openingCells.isEmpty {
            return
        }
    
        let maxDuration = duration + CGFloat(openingCells.count) * CGFloat(delay)
        let t = keyDuration
        let allRatio = easeInEaseOut(t / maxDuration)
    
        if allRatio >= 1.0 {
            didFinishUpdate()
            stop()
            return
        }
    
        engine?.clear()
        bigEngine?.clear()
        for i in 0..<openingCells.count {
            let liquidCell = openingCells[i]
            let cellDelay = CGFloat(delay) * CGFloat(i)
            let ratio = easeInEaseOut((t - cellDelay) / duration)
            f(liquidCell, i, ratio)
        }
    
        if let firstCell = openingCells.first {
            bigEngine?.push(baseLiquid!, other: firstCell)
        }
        for i in 1..<openingCells.count {
            let prev = openingCells[i - 1]
            let cell = openingCells[i]
            engine?.push(prev, other: cell)
        }
        engine?.draw(baseLiquid!)
        bigEngine?.draw(baseLiquid!)
    }
    
    func updateOpen() {
        update(0.1, duration: openDuration) { cell, i, ratio in
            let posRatio = ratio > CGFloat(i) / CGFloat(self.openingCells.count) ? ratio : 0
            let distance = (cell.frame.height * 0.5 + CGFloat(i + 1) * cell.frame.height * 1.5) * posRatio
            cell.center = self.center.plus(self.differencePoint(distance))
            cell.update(ratio, open: true)
        }
    }
    
    func updateClose() {
        update(0, duration: closeDuration) { cell, i, ratio in
            let distance = (cell.frame.height * 0.5 + CGFloat(i + 1) * cell.frame.height * 1.5) * (1 - ratio)
            cell.center = self.center.plus(self.differencePoint(distance))
            cell.update(ratio, open: false)
        }
    }
    
    func differencePoint(distance: CGFloat) -> CGPoint {
        switch animateStyle {
        case .Up:
            return CGPoint(x: 0, y: -distance)
        case .Right:
            return CGPoint(x: distance, y: 0)
        case .Left:
            return CGPoint(x: -distance, y: 0)
        case .Down:
            return CGPoint(x: 0, y: distance)
        }
    }
    
    func stop() {
        for cell in openingCells {
            if enableShadow {
                cell.layer.appendShadow()
            }
        }
        openingCells = []
        keyDuration = 0
        displayLink?.invalidate()
    }
    
    func easeInEaseOut(t: CGFloat) -> CGFloat {
        if t >= 1.0 {
            return 1.0
        }
        if t < 0 {
            return 0
        }
        return -1 * t * (t - 2)
    }
    
    func didDisplayRefresh(displayLink: CADisplayLink) {
        if opening {
            keyDuration += CGFloat(displayLink.duration)
            updateOpen()
        } else {
            keyDuration += CGFloat(displayLink.duration)
            updateClose()
        }
    }
    

    }

    public class LiquidFloatingCell : LiquittableCircle {

    let internalRatio: CGFloat = 0.75
    
    public var responsible = true
    public var imageView = UIImageView()
    weak var actionButton: LiquidFloatingActionButton?
    
    // for implement responsible color
    private var originalColor: UIColor
    
    public override var frame: CGRect {
        didSet {
            resizeSubviews()
        }
    }
    
    init(center: CGPoint, radius: CGFloat, color: UIColor, icon: UIImage) {
        self.originalColor = color
        super.init(center: center, radius: radius, color: color)
        setup(icon)
    }
    
    init(center: CGPoint, radius: CGFloat, color: UIColor, view: UIView) {
        self.originalColor = color
        super.init(center: center, radius: radius, color: color)
        setupView(view)
    }
    
    public init(icon: UIImage) {
        self.originalColor = UIColor.clearColor()
        super.init()
        setup(icon)
    }
    
    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func setup(image: UIImage, tintColor: UIColor = UIColor.whiteColor()) {
        imageView.image = image.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
        imageView.tintColor = tintColor
        setupView(imageView)
    }
    
    public func setupView(view: UIView) {
        userInteractionEnabled = false
        addSubview(view)
        resizeSubviews()
    }
    
    private func resizeSubviews() {
        let size = CGSize(width: frame.width * 0.5, height: frame.height * 0.5)
        imageView.frame = CGRect(x: frame.width - frame.width * internalRatio, y: frame.height - frame.height * internalRatio, width: size.width, height: size.height)
    }
    
    func update(key: CGFloat, open: Bool) {
        for subview in self.subviews {
            let ratio = max(2 * (key * key - 0.5), 0)
            subview.alpha = open ? ratio : -ratio
        }
    }
    
    public override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if responsible {
            originalColor = color
            color = originalColor.white(0.5)
            setNeedsDisplay()
        }
    }
    
    public override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
        if responsible {
            color = originalColor
            setNeedsDisplay()
        }
    }
    
    override public func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        color = originalColor
        actionButton?.didTappedCell(self)
    }
    

    }

    Reviewed by ChenCodes at 2016-04-20 04:03
  • 7. Can we change plus icon?

    Thank you for making this. I am using this button kinda side menu. So, i would like to change initial "plus" icon to something more like "list" type icon or something custom i want. I attempted to do that but failed. At least if you can tell where it is initialised, i would try to change.

    Reviewed by osmantuna at 2015-10-14 13:14
  • 8. installation use Carthage

    write github "yoavlt/LiquidFloatingActionButton" in Cartfile run command carthage update with error "Dependency "LiquidFloatingActionButton" has no shared framework schemes"

    Reviewed by afishhhhh at 2017-02-20 15:14
  • 9. Showing one extra circles while using in storyboard

    Please see the image for bug,

    screen shot 2016-04-01 at 12 30 00 pm

    I added a UIView in storyboard and set its class to LiquidFloatingActionButton. It is showing floating button but with an extra large circle besides it.

    Reviewed by vijaysanghavi at 2016-04-01 07:15
  • 10. Method does not override any method from its superclass

    After pod installation of LiquidFloatingButtonAction, I am getting "Method does not override any method from its superclass" error in my project multiple times. Can you please whats wrong with my project?

    Reviewed by artiy at 2015-12-15 09:30
  • 11. Does not compile on Xcode 7.1

    6 errors , 8 warnings on 0.1.2 which I thought was the swift 2.0 branch

    for example the 3 overrides below are failing with the following message: /Users/mark/xcode/X2/Pods/LiquidFloatingActionButton/Pod/Classes/LiquidFloatingActionButton.swift:542:26: Method does not override any method from its superclass

    ////////////////////////// // MARK: Events public override func touchesBegan(touches: Set, withEvent event: UIEvent) { self.touching = true setNeedsDisplay() }

    public override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
        self.touching = false
        setNeedsDisplay()
        didTapped()
    }
    
    public override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) {
        self.touching = false
        setNeedsDisplay()
    }
    
    Reviewed by markgk at 2015-11-04 08:37
  • 12. Not updated for pod install

    I have installed on pod.

    pod 'LiquidFloatingActionButton'

    so installed 1.2.0, but code is not compatible swift 5. pods lib have so many issue. so I have updated manually...

    How can I get latest version from pod install. Thanks in advance.

    Reviewed by darkhorse-coder at 2019-08-26 19:20
  • 13. How to use didTapped and didLongTapped

    Hello,

    I am developing an app in that I have to use two types of floating button in which one will normal that shown in the demo and one is only plus icon button so how to use didtapped of LiquidFloatingActionButton. I have seen #20 but I don't get anything. Also, add that in demo example.

    Reviewed by NikhilGangurde at 2019-07-23 08:57
An open-source library to use with SwiftUI, It allows you to create Floating menu action button.
An open-source library to use with SwiftUI, It allows you to create Floating menu action button.

Floating Menu Action Button Example Overview This is an open-source library to use with SwiftUI. It allows you to create Floating menu action button. Ins

Feb 14, 2022
Interactive and fully animated Material Design button for iOS developers.
Interactive and fully animated Material Design button for iOS developers.

WYMaterialButton Inspired by Google Material Design, written purely in Swift 3. WYMaterialButton implemented Material Design on iOS and add more dynam

Jan 23, 2022
Easily customizable floating button menu created with SwiftUI
Easily customizable floating button menu created with SwiftUI

FloatingButton Easily customizable floating button menu created with SwiftUI We are a development agency building phenomenal apps. Usage Create main b

Jun 24, 2022
Custom UIButton effect inspired by Google Material Design
Custom UIButton effect inspired by Google Material Design

ZFRippleButton iOS Custom UIButton effect inspired by Google Material Design written in Swift Usage Set the UIButton class in Nib to ZFRippleButton or

Jun 21, 2022
Multiple state tap-to-toggle UIButton (like old camera flash button)
Multiple state tap-to-toggle UIButton (like old camera flash button)

Multiple State Toggle UIButton A UIButton subclass that implements tap-to-toggle button text. (Like the camera flash and timer buttons) Usage Just cre

Mar 19, 2022
Customizable download button with progress and transition animations. It is based on Apple's App Store download button.
Customizable download button with progress and transition animations. It is based on Apple's App Store download button.

AHDownloadButton is a customizable download button similar to the download button in the latest version of Apple's App Store app (since iOS 11). It fe

Jun 19, 2022
Revamped Download Button. It's kinda a reverse engineering of Netflix's app download button.
Revamped Download Button. It's kinda a reverse engineering of Netflix's app download button.

NFDownloadButton Revamped Download Button Requirements Installation Usage License Requirements iOS 8.0+ Swift 4.2+ Xcode 10.0+ Installation CocoaPods

May 25, 2022
Flat design pressable button for iOS developers.
Flat design pressable button for iOS developers.

HTPressableButton HTPressableButton is designed for iOS developers to be able to spend time developing ideas, not building basic buttons. These stylis

May 16, 2022
Cute Animated Button written in Swift.
Cute Animated Button written in Swift.

DOFavoriteButton Cute Animated Button written in Swift. It could be just right for favorite buttons! Requirements iOS 7.0+ Swift 1.2 Installation Cart

Jun 16, 2022
Customizable and easy to use expandable button in Swift.
Customizable and easy to use expandable button in Swift.

ExpandableButton Requirements iOS 9.0+ Installation CocoaPods: Add the following line to your Podfile: pod 'ExpandableButton' #for swift less than 4.

May 9, 2022
IGStoryButtonKit provides an easy-to-use button with rich animation and multiple way inspired by instagram story/stories.
IGStoryButtonKit provides an easy-to-use button with rich animation and multiple way inspired by instagram story/stories.

Introduction Have you ever seen UI like instagram story, haven't you? Actually, features like instagram story have been implemented in many applicatio

Jun 14, 2022
LTHRadioButton - A radio button with a pretty animation
LTHRadioButton - A radio button with a pretty animation

LTHRadioButton Slightly inspired by Google's material radio button. The clip below has 3 sections: full speed, 25% and 10%, but after converting it to

Jun 13, 2022
Lickable-Button We made the buttons on the screen look so good you'll want to lick them

Lickable-Button We made the buttons on the screen look so good you'll want to lick them. - Steve Jobs A little SwiftUI button project at WWDC 2021 Lic

Dec 29, 2021
Craft that perfect SwiftUI button effect 👌🏼
Craft that perfect SwiftUI button effect 👌🏼

buttoncraft (SwiftUI 3.0 App) Experimenting with SwiftUI 3.0 whilst creating a practical app to craft that perfect button style. ✈️ Testflight https:/

Jun 18, 2022
iOS Pod for a Soft UI (Neumorphic) Button for UIKit written in Swift
iOS Pod for a Soft UI (Neumorphic) Button for UIKit written in Swift

iOS Pod for a Soft UI (Neumorphic) Button for UIKit written in Swift

Jun 6, 2022
Custom loading button with progress swiftui

CustomLoadingButton Simple Custom Loading Progress Button for SwiftUI Version 1.0.0 This version requires Xcode 11+ SwiftUI iOS 13+ macOS 10.15+ Insta

Oct 18, 2021
iOS 7-style bouncy button.

SSBouncyButton SSBouncyButton is simple button UI component with iOS 7-style bouncy animation. Take A Look Try It! pod 'SSBouncyButton', '~> 1.0' Use

Mar 19, 2022
Flat button with 9 different states using POP
Flat button with 9 different states using POP

VBFPopFlatButton Flat button with 21 different states and 2 types animated using pop. These are some examples of both types in different states: And h

Jun 17, 2022
Simple and customizable button in Swift
Simple and customizable button in Swift

SwiftyButton Maintainer(s): @nickm01 @pmacro @aryamansharda Simple and customizable button in Swift. Installation Cocoapods pod 'SwiftyButton' Cartha

May 8, 2022