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

Make automatic closing of action button configurable #231

Merged
merged 2 commits into from
Feb 28, 2020
Merged
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
101 changes: 79 additions & 22 deletions Example/Tests/JJFloatingActionButtonSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ class JJFloatingActionButtonSpec: QuickSpec {

it("does not open") {
actionButton.open(animated: false)
expect(actionButton.buttonState).to(equal(JJFloatingActionButtonState.closed))
expect(actionButton.buttonState) == .closed
}

it("does not open when tapped") {
actionButton.sendActions(for: .touchUpInside)
expect(actionButton.buttonState).toNotEventually(equal(JJFloatingActionButtonState.open))
expect(actionButton.buttonState) == .closed
}

it("looks correct by default") {
Expand Down Expand Up @@ -206,14 +206,15 @@ class JJFloatingActionButtonSpec: QuickSpec {

it("opens when tapped") {
actionButton.sendActions(for: .touchUpInside)
expect(actionButton.buttonState).toEventually(equal(JJFloatingActionButtonState.open))
expect(actionButton.buttonState) == .opening
expect(actionButton.buttonState).toEventually(equal(.open))
}

it("opens when tapped twice") {
actionButton.sendActions(for: .touchUpInside)
actionButton.sendActions(for: .touchUpInside)
expect(actionButton.buttonState).toEventually(equal(JJFloatingActionButtonState.opening))
expect(actionButton.buttonState).toEventually(equal(JJFloatingActionButtonState.open))
expect(actionButton.buttonState) == .opening
expect(actionButton.buttonState).toEventually(equal(.open))
}

context("and is opened") {
Expand All @@ -222,7 +223,7 @@ class JJFloatingActionButtonSpec: QuickSpec {
}

it("has state open") {
expect(actionButton.buttonState) == JJFloatingActionButtonState.open
expect(actionButton.buttonState) == .open
}

it("items look correct") {
Expand All @@ -246,7 +247,7 @@ class JJFloatingActionButtonSpec: QuickSpec {

it("can't be opened again") {
actionButton.open(animated: true)
expect(actionButton.buttonState) != JJFloatingActionButtonState.opening
expect(actionButton.buttonState) != .opening
}

context("and overlay is tapped") {
Expand All @@ -255,7 +256,8 @@ class JJFloatingActionButtonSpec: QuickSpec {
}

it("closes") {
expect(actionButton.buttonState).toEventually(equal(JJFloatingActionButtonState.closed))
expect(actionButton.buttonState) == .closing
expect(actionButton.buttonState).toEventually(equal(.closed))
}
}

Expand All @@ -265,11 +267,13 @@ class JJFloatingActionButtonSpec: QuickSpec {
}

it("closes") {
expect(actionButton.buttonState).toEventually(equal(JJFloatingActionButtonState.closed))
expect(actionButton.buttonState) == .closing
expect(actionButton.buttonState).toEventually(equal(.closed))
}

it("does not perform action") {
expect(action).toNotEventually(equal("done!"))
waitUntil(timeout: 1.5)
expect(action) != "done!"
}
}

Expand All @@ -280,13 +284,57 @@ class JJFloatingActionButtonSpec: QuickSpec {
}

it("closes") {
expect(actionButton.buttonState).toEventually(equal(JJFloatingActionButtonState.closed))
expect(actionButton.buttonState) == .closing
expect(actionButton.buttonState).toEventually(equal(.closed))
}

it("performs action") {
expect(action).toEventually(equal("done!"))
}
}

context("with closeAutomatically disabled") {
beforeEach {
actionButton.closeAutomatically = false
}

context("and item is tapped") {
beforeEach {
let item = actionButton.items[0]
item.sendActions(for: .touchUpInside)
}

it("stays open") {
expect(actionButton.buttonState) == .open
}

it("performs action") {
expect(action).toEventually(equal("done!"))
}
}
}

context("with closeAutomatically enabled") {
beforeEach {
actionButton.closeAutomatically = true
}

context("and item is tapped") {
beforeEach {
let item = actionButton.items[0]
item.sendActions(for: .touchUpInside)
}

it("closes") {
expect(actionButton.buttonState) == .closing
expect(actionButton.buttonState).toEventually(equal(.closed))
}

it("performs action") {
expect(action).toEventually(equal("done!"))
}
}
}
}

context("and is opened and closed") {
Expand All @@ -301,7 +349,7 @@ class JJFloatingActionButtonSpec: QuickSpec {

it("can't be closed again") {
actionButton.close(animated: true)
expect(actionButton.buttonState) != JJFloatingActionButtonState.closing
expect(actionButton.buttonState) != .closing
}
}

Expand All @@ -311,11 +359,11 @@ class JJFloatingActionButtonSpec: QuickSpec {
}

it("has state opening") {
expect(actionButton.buttonState) == JJFloatingActionButtonState.opening
expect(actionButton.buttonState) == .opening
}

it("has eventually state open") {
expect(actionButton.buttonState).toEventually(equal(JJFloatingActionButtonState.open))
expect(actionButton.buttonState).toEventually(equal(.open))
}
}

Expand All @@ -326,11 +374,11 @@ class JJFloatingActionButtonSpec: QuickSpec {
}

it("has state closing") {
expect(actionButton.buttonState) == JJFloatingActionButtonState.closing
expect(actionButton.buttonState) == .closing
}

it("has eventually state closed") {
expect(actionButton.buttonState).toEventually(equal(JJFloatingActionButtonState.closed))
expect(actionButton.buttonState).toEventually(equal(.closed))
}
}

Expand Down Expand Up @@ -392,8 +440,8 @@ class JJFloatingActionButtonSpec: QuickSpec {
actionButton.sendActions(for: .touchUpInside)
}

it("does not open") {
expect(actionButton.buttonState).toNotEventually(equal(JJFloatingActionButtonState.open))
it("stays closed") {
expect(actionButton.buttonState) == .closed
}

it("performs action") {
Expand All @@ -407,7 +455,7 @@ class JJFloatingActionButtonSpec: QuickSpec {
}

it("has state closed") {
expect(actionButton.buttonState) == JJFloatingActionButtonState.closed
expect(actionButton.buttonState) == .closed
}

it("looks correct") {
Expand All @@ -422,7 +470,7 @@ class JJFloatingActionButtonSpec: QuickSpec {
}

it("opens") {
expect(actionButton.buttonState) == JJFloatingActionButtonState.open
expect(actionButton.buttonState) == .open
}

it("looks correct") {
Expand All @@ -446,9 +494,9 @@ class JJFloatingActionButtonSpec: QuickSpec {
actionButton.addItem(title: "item 2", image: #imageLiteral(resourceName: "Baloon").withRenderingMode(.alwaysTemplate))
}

it("does not open when tapped") {
it("stays closed") {
actionButton.sendActions(for: .touchUpInside)
expect(actionButton.buttonState).toNotEventually(equal(JJFloatingActionButtonState.open))
expect(actionButton.buttonState) == .closed
}
}
}
Expand Down Expand Up @@ -519,3 +567,12 @@ class JJFloatingActionButtonSpec: QuickSpec {
}
}
}

func waitUntil(timeout: TimeInterval = AsyncDefaults.Timeout) {
waitUntil(timeout: timeout + 1, action: { done in
DispatchQueue.global().async {
Thread.sleep(forTimeInterval: timeout)
done()
}
})
}
15 changes: 13 additions & 2 deletions Sources/JJFloatingActionButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ import UIKit
public var itemAnimationConfiguration: JJItemAnimationConfiguration = .popUp()

/// When enabled and only one action item is added, the floating action button will not open,
/// but the action from the action item will be executed direclty when the button is tapped.
/// but the action from the action item will be executed directly when the button is tapped.
/// Also the image of the floating action button will be replaced with the one from the action item.
///
/// Default is `true`.
Expand All @@ -173,6 +173,15 @@ import UIKit
}
}

/// When enabled, the floating action button will close after an action item was tapped,
/// otherwise the action button will stay open and has to be closed explicitly.
///
/// Default is `true`.
///
/// - SeeAlso: `close`
///
@objc @IBInspectable public var closeAutomatically: Bool = true

/// The current state of the floating action button.
/// Possible values are
/// - `.opening`
Expand Down Expand Up @@ -526,7 +535,9 @@ fileprivate extension JJFloatingActionButton {
}

@objc func itemWasTapped(sender: JJActionItem) {
close()
if closeAutomatically {
close()
}
sender.callAction()
}

Expand Down