Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated to swift 4. Added customization #42

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 44 additions & 22 deletions Source/ActionButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ open class ActionButton: NSObject {
showActive(true)
}
}
/// The blur effect style of the background when menu opens. Set it to nil to disable blur
public var backgroundBlurStyle: UIBlurEffectStyle? = .extraLight
var image: UIImage?

/// The button that will be presented to the user
fileprivate var floatButton: UIButton!
Expand All @@ -70,21 +73,24 @@ open class ActionButton: NSObject {
/// Blur effect that will be presented when the button is active
fileprivate var blurVisualEffect: UIVisualEffectView!

// Distance between each item action
fileprivate let itemOffset = -55
/// Distance between each item action
public var itemSpacing: CGFloat = 20

/// the float button's radius
fileprivate let floatButtonRadius = 50
/// The button offset from the bottom
fileprivate(set) public var buttonOffset: CGPoint = CGPoint(x: 15, y: 15)
/// the float button's size
fileprivate(set) public var floatButtonDiameter: CGFloat = 50

public init(attachedToView view: UIView, items: [ActionButtonItem]?) {
public init(attachedToView view: UIView, items: [ActionButtonItem]?, buttonSize: CGFloat = 50, buttonOffset: CGPoint = CGPoint(x: 15, y: 15)) {
super.init()

self.buttonOffset = buttonOffset
self.floatButtonDiameter = buttonSize
self.parentView = view
self.items = items
let bounds = self.parentView.bounds

self.floatButton = UIButton(type: .custom)
self.floatButton.layer.cornerRadius = CGFloat(floatButtonRadius / 2)
self.floatButton.layer.cornerRadius = CGFloat(floatButtonDiameter / 2)
self.floatButton.layer.shadowOpacity = 1
self.floatButton.layer.shadowRadius = 2
self.floatButton.layer.shadowOffset = CGSize(width: 1, height: 1)
Expand All @@ -97,13 +103,18 @@ open class ActionButton: NSObject {
self.floatButton.isUserInteractionEnabled = true
self.floatButton.translatesAutoresizingMaskIntoConstraints = false

floatButton.addTarget(self, action: #selector(dragEnter(_:)), for: .touchDragEnter)
floatButton.addTarget(self, action: #selector(dragExit(_:)), for: .touchDragExit)
floatButton.addTarget(self, action: #selector(touchUpOutside(_:)), for: .touchUpOutside)
self.floatButton.addTarget(self, action: #selector(ActionButton.buttonTapped(_:)), for: .touchUpInside)
self.floatButton.addTarget(self, action: #selector(ActionButton.buttonTouchDown(_:)), for: .touchDown)
self.parentView.addSubview(self.floatButton)

self.contentView = UIView(frame: bounds)
self.blurVisualEffect = UIVisualEffectView(effect: UIBlurEffect(style: .extraLight))
self.blurVisualEffect.frame = self.contentView.frame
self.blurVisualEffect.effect = nil
self.contentView.backgroundColor = UIColor.clear
self.contentView.addSubview(self.blurVisualEffect)

let tap = UITapGestureRecognizer(target: self, action: #selector(ActionButton.backgroundTapped(_:)))
Expand Down Expand Up @@ -136,32 +147,41 @@ open class ActionButton: NSObject {
*/
fileprivate func installConstraints() {
let views: [String: UIView] = ["floatButton":self.floatButton, "parentView":self.parentView]
let width = NSLayoutConstraint.constraints(withVisualFormat: "H:[floatButton(\(floatButtonRadius))]", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: views)
let height = NSLayoutConstraint.constraints(withVisualFormat: "V:[floatButton(\(floatButtonRadius))]", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: views)
let width = NSLayoutConstraint.constraints(withVisualFormat: "H:[floatButton(\(floatButtonDiameter))]", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: views)
let height = NSLayoutConstraint.constraints(withVisualFormat: "V:[floatButton(\(floatButtonDiameter))]", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: views)
self.floatButton.addConstraints(width)
self.floatButton.addConstraints(height)

let trailingSpacing = NSLayoutConstraint.constraints(withVisualFormat: "V:[floatButton]-15-|", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: views)
let bottomSpacing = NSLayoutConstraint.constraints(withVisualFormat: "H:[floatButton]-15-|", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: views)
let trailingSpacing = NSLayoutConstraint.constraints(withVisualFormat: "V:[floatButton]-\(buttonOffset.y)-|", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: views)
let bottomSpacing = NSLayoutConstraint.constraints(withVisualFormat: "H:[floatButton]-\(buttonOffset.x)-|", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: views)
self.parentView.addConstraints(trailingSpacing)
self.parentView.addConstraints(bottomSpacing)
}

//MARK: - Button Actions Methods
func buttonTapped(_ sender: UIControl) {
@objc func buttonTapped(_ sender: UIControl) {
animatePressingWithScale(1.0)

if let unwrappedAction = self.action {
unwrappedAction(self)
}
}
@objc private func dragEnter(_ sender: Any) {
animatePressingWithScale(0.9)
}
@objc private func dragExit(_ sender: Any) {
animatePressingWithScale(1.0)
}
@objc private func touchUpOutside(_ sender: UIControl) {
animatePressingWithScale(1.0)
}

func buttonTouchDown(_ sender: UIButton) {
@objc func buttonTouchDown(_ sender: UIButton) {
animatePressingWithScale(0.9)
}

//MARK: - Gesture Recognizer Methods
func backgroundTapped(_ gesture: UIGestureRecognizer) {
@objc func backgroundTapped(_ gesture: UIGestureRecognizer) {
if self.active {
self.toggle()
}
Expand All @@ -183,7 +203,7 @@ open class ActionButton: NSObject {
fileprivate func placeButtonItems() {
if let optionalItems = self.items {
for item in optionalItems {
item.view.center = CGPoint(x: self.floatButton.center.x - 83, y: self.floatButton.center.y)
item.view.center = CGPoint(x: self.floatButton.center.x - (item.viewSize.width/2 - item.buttonSize.width/2), y: self.floatButton.center.y)
item.view.removeFromSuperview()

self.contentView.addSubview(item.view)
Expand All @@ -205,7 +225,7 @@ open class ActionButton: NSObject {
}

fileprivate func animateMenu() {
let rotation = self.active ? 0 : CGFloat(M_PI_4)
let rotation = self.active ? 0 : CGFloat(Double.pi/4)

UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0.1, options: UIViewAnimationOptions.allowAnimatedContent, animations: {

Expand All @@ -223,19 +243,21 @@ open class ActionButton: NSObject {

fileprivate func showActive(_ active: Bool) {
if self.active == active {
self.contentView.alpha = 1.0

// self.contentView.alpha = 1.0
if let style = self.backgroundBlurStyle {
self.blurVisualEffect.effect = UIBlurEffect(style: style)
}
if let optionalItems = self.items {
for (index, item) in optionalItems.enumerated() {
let offset = index + 1
let translation = self.itemOffset * offset
item.view.transform = CGAffineTransform(translationX: 0, y: CGFloat(translation))
let translation = -1 * (itemSpacing + item.buttonSize.height) * CGFloat(offset)
item.view.transform = CGAffineTransform(translationX: 0, y: translation)
item.view.alpha = 1
}
}
} else {
self.contentView.alpha = 0.0

// self.contentView.alpha = 0.0
self.blurVisualEffect.effect = nil
if let optionalItems = self.items {
for item in optionalItems {
item.view.transform = CGAffineTransform(translationX: 0, y: 0)
Expand Down
31 changes: 22 additions & 9 deletions Source/ActionButtonItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ open class ActionButtonItem: NSObject {
/// The action the item should perform when tapped
open var action: ActionButtonItemAction?

/// Description of the item's action
/// Description of the item's action. This should not be changed if the text length changes as it does not trigger a resize of the item view
open var text: String {
get {
return self.label.text!
Expand All @@ -41,6 +41,15 @@ open class ActionButtonItem: NSObject {
self.label.text = newValue
}
}
/// The color of the item text
open var textColor: UIColor {
get {
return label.textColor
}
set {
label.textColor = newValue
}
}
/// View that will hold the item's button and label
internal var view: UIView!

Expand All @@ -54,21 +63,24 @@ open class ActionButtonItem: NSObject {
fileprivate var image: UIImage!

/// Size needed for the *view* property presente the item's content
fileprivate let viewSize = CGSize(width: 200, height: 35)
fileprivate(set) public var viewSize = CGSize(width: 200, height: 35)

/// Button's size by default the button is 35x35
fileprivate let buttonSize = CGSize(width: 35, height: 35)
fileprivate(set) public var buttonSize = CGSize(width: 35, height: 35)

fileprivate var labelBackground: UIView!
fileprivate let backgroundInset = CGSize(width: 10, height: 10)
/// The inset
let backgroundInset = CGSize(width: 10, height: 10)

/**
:param: title Title that will be presented when the item is active
:param: image Item's image used by the it's button
*/
public init(title optionalTitle: String?, image: UIImage?) {
public init(title optionalTitle: String?, image: UIImage?, buttonSize: CGSize = CGSize(width: 35, height: 35), viewSize: CGSize = CGSize(width: 200, height: 35), textFont: UIFont = UIFont.systemFont(ofSize: 14)) {
super.init()

self.buttonSize = buttonSize
self.viewSize = viewSize
self.viewSize.height = buttonSize.height
self.view = UIView(frame: CGRect(origin: CGPoint.zero, size: self.viewSize))
self.view.alpha = 0
self.view.isUserInteractionEnabled = true
Expand All @@ -88,10 +100,11 @@ open class ActionButtonItem: NSObject {

if let text = optionalTitle , text.trimmingCharacters(in: CharacterSet.whitespaces).isEmpty == false {
self.label = UILabel()
self.label.font = UIFont(name: "HelveticaNeue-Medium", size: 13)
self.label.font = textFont
self.label.textColor = UIColor.darkGray
self.label.textAlignment = .right
self.label.text = text
self.label.numberOfLines = 0
self.label.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(ActionButtonItem.labelTapped(_:))))
self.label.sizeToFit()

Expand Down Expand Up @@ -126,14 +139,14 @@ open class ActionButtonItem: NSObject {
}

//MARK: - Button Action Methods
func buttonPressed(_ sender: UIButton) {
@objc func buttonPressed(_ sender: UIButton) {
if let unwrappedAction = self.action {
unwrappedAction(self)
}
}

//MARK: - Gesture Recognizer Methods
func labelTapped(_ gesture: UIGestureRecognizer) {
@objc func labelTapped(_ gesture: UIGestureRecognizer) {
if let unwrappedAction = self.action {
unwrappedAction(self)
}
Expand Down