Skip to content

Commit 6b92e72

Browse files
authored
Add handlers and update docs (#29)
1 parent 04c9602 commit 6b92e72

File tree

16 files changed

+424
-121
lines changed

16 files changed

+424
-121
lines changed

Drops.podspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'Drops'
3-
s.version = '1.3.0'
3+
s.version = '1.4.0'
44
s.summary = 'A µFramework for showing iOS 13 like system alerts'
55
s.description = <<-DESC
66
A µFramework for showing alerts like the one used when copying from pasteboard or connecting Apple pencil.

Drops.xcodeproj/project.pbxproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,7 @@
774774
"@executable_path/Frameworks",
775775
"@loader_path/Frameworks",
776776
);
777-
MARKETING_VERSION = 1.3.0;
777+
MARKETING_VERSION = 1.4.0;
778778
PRODUCT_BUNDLE_IDENTIFIER = com.omaralbeik.drops;
779779
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
780780
SKIP_INSTALL = YES;
@@ -803,7 +803,7 @@
803803
"@executable_path/Frameworks",
804804
"@loader_path/Frameworks",
805805
);
806-
MARKETING_VERSION = 1.3.0;
806+
MARKETING_VERSION = 1.4.0;
807807
PRODUCT_BUNDLE_IDENTIFIER = com.omaralbeik.drops;
808808
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
809809
SKIP_INSTALL = YES;

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ The [Swift Package Manager](https://swift.org/package-manager/) is a tool for ma
119119

120120
```swift
121121
dependencies: [
122-
.package(url: "https://github.com/omaralbeik/Drops.git", from: "1.3.0")
122+
.package(url: "https://github.com/omaralbeik/Drops.git", from: "1.4.0")
123123
]
124124
```
125125

@@ -134,7 +134,7 @@ $ swift build
134134
To integrate Drops into your Xcode project using [CocoaPods](https://cocoapods.org), specify it in your Podfile:
135135

136136
```rb
137-
pod 'Drops', :git => 'https://github.com/omaralbeik/Drops.git', :tag => '1.3.0'
137+
pod 'Drops', :git => 'https://github.com/omaralbeik/Drops.git', :tag => '1.4.0'
138138
```
139139

140140
### Carthage

Sources/Drop.swift

+7-5
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,17 @@
2323

2424
import UIKit
2525

26-
@available(iOSApplicationExtension, unavailable)
2726
/// An object representing a drop.
27+
@available(iOSApplicationExtension, unavailable)
2828
public struct Drop: ExpressibleByStringLiteral {
2929
/// Create a new drop.
3030
/// - Parameters:
3131
/// - title: Title.
32-
/// - titleNumberOfLines: Maximum number of lines that `title` can occupy. Defaults to `1`. A value of 0 means no limit.
32+
/// - titleNumberOfLines: Maximum number of lines that `title` can occupy. Defaults to `1`.
33+
/// A value of 0 means no limit.
3334
/// - subtitle: Optional subtitle. Defaults to `nil`.
34-
/// - subtitleNumberOfLines: Maximum number of lines that `subtitle` can occupy. Defaults to `1`. A value of 0 means no limit.
35+
/// - subtitleNumberOfLines: Maximum number of lines that `subtitle` can occupy. Defaults to `1`.
36+
/// A value of 0 means no limit.
3537
/// - icon: Optional icon.
3638
/// - action: Optional action.
3739
/// - position: Position. Defaults to `Drop.Position.top`.
@@ -75,13 +77,13 @@ public struct Drop: ExpressibleByStringLiteral {
7577

7678
/// Title.
7779
public var title: String
78-
80+
7981
/// Maximum number of lines that `title` can occupy. Defaults to `1`. A value of 0 means no limit.
8082
public var titleNumberOfLines: Int
8183

8284
/// Subtitle.
8385
public var subtitle: String?
84-
86+
8587
/// Maximum number of lines that `subtitle` can occupy. Defaults to `1`. A value of 0 means no limit.
8688
public var subtitleNumberOfLines: Int
8789

Sources/Drops.swift

+44-3
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@
2323

2424
import UIKit
2525

26-
typealias AnimationCompletion = (_ completed: Bool) -> Void
26+
internal typealias AnimationCompletion = (_ completed: Bool) -> Void
2727

28-
@available(iOSApplicationExtension, unavailable)
2928
/// A shared class used to show and hide drops.
29+
@available(iOSApplicationExtension, unavailable)
3030
public final class Drops {
31+
/// Handler.
32+
public typealias DropHandler = (Drop) -> Void
3133

3234
// MARK: - Static
3335

@@ -49,6 +51,30 @@ public final class Drops {
4951
shared.hideAll()
5052
}
5153

54+
/// A handler to be called before a drop is presented.
55+
public static var willShowDrop: DropHandler? {
56+
get { shared.willShowDrop }
57+
set { shared.willShowDrop = newValue }
58+
}
59+
60+
/// A handler to be called after a drop is presented.
61+
public static var didShowDrop: DropHandler? {
62+
get { shared.didShowDrop }
63+
set { shared.didShowDrop = newValue }
64+
}
65+
66+
/// A handler to be called before a drop is dismissed.
67+
public static var willDismissDrop: DropHandler? {
68+
get { shared.willDismissDrop }
69+
set { shared.willDismissDrop = newValue }
70+
}
71+
72+
/// A handler to be called after a drop is dismissed.
73+
public static var didDismissDrop: DropHandler? {
74+
get { shared.didDismissDrop }
75+
set { shared.didDismissDrop = newValue }
76+
}
77+
5278
// MARK: - Instance
5379

5480
/// Create a new instance with a custom delay between drops.
@@ -69,10 +95,12 @@ public final class Drops {
6995
/// Hide currently shown drop.
7096
public func hideCurrent() {
7197
guard let current = current, !current.isHiding else { return }
98+
willDismissDrop?(current.drop)
7299
DispatchQueue.main.async {
73100
current.hide(animated: true) { [weak self] completed in
74101
guard completed, let self = self else { return }
75102
self.dispatchQueue.sync {
103+
self.didDismissDrop?(current.drop)
76104
guard self.current === current else { return }
77105
self.current = nil
78106
}
@@ -88,6 +116,18 @@ public final class Drops {
88116
}
89117
}
90118

119+
/// A handler to be called before a drop is presented.
120+
public var willShowDrop: DropHandler?
121+
122+
/// A handler to be called after a drop is presented.
123+
public var didShowDrop: DropHandler?
124+
125+
/// A handler to be called before a drop is dismissed.
126+
public var willDismissDrop: DropHandler?
127+
128+
/// A handler to be called after a drop is dismissed.
129+
public var didDismissDrop: DropHandler?
130+
91131
// MARK: - Helpers
92132

93133
let delayBetweenDrops: TimeInterval
@@ -128,8 +168,9 @@ public final class Drops {
128168
DispatchQueue.main.async { [weak self] in
129169
guard let self = self else { return }
130170
guard let current = self.current else { return }
131-
171+
self.willShowDrop?(current.drop)
132172
current.show { completed in
173+
self.didShowDrop?(current.drop)
133174
guard completed else {
134175
self.dispatchQueue.sync {
135176
self.hide(presenter: current)

Tests/DropViewTests.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,13 @@ final class DropViewTests: XCTestCase {
161161

162162
waitForExpectations(timeout: 1)
163163
}
164-
164+
165165
func testLabelNumberOfLines() {
166166
let drop1 = Drop(title: "Title")
167167
let view1 = DropView(drop: drop1)
168168
XCTAssertEqual(view1.titleLabel.numberOfLines, 1)
169169
XCTAssertEqual(view1.subtitleLabel.numberOfLines, 1)
170-
170+
171171
let drop2 = Drop(
172172
title: "Title",
173173
titleNumberOfLines: 3,

Tests/DropsTests.swift

+109
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,113 @@ final class DropsTests: XCTestCase {
135135

136136
XCTAssert(Drops.shared.queue.isEmpty)
137137
}
138+
139+
func testHandlers() {
140+
let drops = Drops(delayBetweenDrops: 0)
141+
let expectedDrop = Drop(title: "Hello world!", duration: .seconds(0.1))
142+
143+
let willShowDropExp = expectation(description: "willShowDrop is called")
144+
let didShowDropExp = expectation(description: "didShowDrop is called")
145+
let willDismissDropExp = expectation(description: "willDismissDrop is called")
146+
let didDismissDropExp = expectation(description: "didDismissDrop is called")
147+
148+
drops.willShowDrop = { drop in
149+
XCTAssertEqual(drop, expectedDrop)
150+
willShowDropExp.fulfill()
151+
}
152+
153+
drops.didShowDrop = { drop in
154+
XCTAssertEqual(drop, expectedDrop)
155+
didShowDropExp.fulfill()
156+
}
157+
158+
drops.willDismissDrop = { drop in
159+
XCTAssertEqual(drop, expectedDrop)
160+
willDismissDropExp.fulfill()
161+
}
162+
163+
drops.didDismissDrop = { drop in
164+
XCTAssertEqual(drop, expectedDrop)
165+
didDismissDropExp.fulfill()
166+
}
167+
168+
drops.show(expectedDrop)
169+
170+
waitForExpectations(timeout: 1)
171+
}
172+
173+
func testStaticHandlers() {
174+
let expectedDrop = Drop(title: "Hello world!", duration: .seconds(0.1))
175+
176+
let willShowDropExp = expectation(description: "willShowDrop is called")
177+
let didShowDropExp = expectation(description: "didShowDrop is called")
178+
let willDismissDropExp = expectation(description: "willDismissDrop is called")
179+
let didDismissDropExp = expectation(description: "didDismissDrop is called")
180+
181+
Drops.willShowDrop = { drop in
182+
XCTAssertEqual(drop, expectedDrop)
183+
willShowDropExp.fulfill()
184+
}
185+
186+
Drops.didShowDrop = { drop in
187+
XCTAssertEqual(drop, expectedDrop)
188+
didShowDropExp.fulfill()
189+
}
190+
191+
Drops.willDismissDrop = { drop in
192+
XCTAssertEqual(drop, expectedDrop)
193+
willDismissDropExp.fulfill()
194+
}
195+
196+
Drops.didDismissDrop = { drop in
197+
XCTAssertEqual(drop, expectedDrop)
198+
didDismissDropExp.fulfill()
199+
}
200+
201+
Drops.show(expectedDrop)
202+
203+
waitForExpectations(timeout: 1)
204+
}
205+
206+
func testStaticHandlersSettersAndGetters() {
207+
Drops.willShowDrop = { _ in }
208+
XCTAssertNotNil(Drops.shared.willShowDrop)
209+
Drops.willShowDrop = nil
210+
XCTAssertNil(Drops.shared.willShowDrop)
211+
212+
Drops.didShowDrop = { _ in }
213+
XCTAssertNotNil(Drops.shared.didShowDrop)
214+
Drops.didShowDrop = nil
215+
XCTAssertNil(Drops.shared.didShowDrop)
216+
217+
Drops.willDismissDrop = { _ in }
218+
XCTAssertNotNil(Drops.shared.willDismissDrop)
219+
Drops.willDismissDrop = nil
220+
XCTAssertNil(Drops.shared.willDismissDrop)
221+
222+
Drops.didDismissDrop = { _ in }
223+
XCTAssertNotNil(Drops.shared.didDismissDrop)
224+
Drops.didDismissDrop = nil
225+
XCTAssertNil(Drops.shared.didDismissDrop)
226+
227+
Drops.shared.willShowDrop = { _ in }
228+
XCTAssertNotNil(Drops.willShowDrop)
229+
Drops.shared.willShowDrop = nil
230+
XCTAssertNil(Drops.willShowDrop)
231+
232+
Drops.shared.didShowDrop = { _ in }
233+
XCTAssertNotNil(Drops.didShowDrop)
234+
Drops.shared.didShowDrop = nil
235+
XCTAssertNil(Drops.didShowDrop)
236+
237+
Drops.shared.willDismissDrop = { _ in }
238+
XCTAssertNotNil(Drops.willDismissDrop)
239+
Drops.shared.willDismissDrop = nil
240+
XCTAssertNil(Drops.willDismissDrop)
241+
242+
Drops.shared.didDismissDrop = { _ in }
243+
XCTAssertNotNil(Drops.didDismissDrop)
244+
Drops.shared.didDismissDrop = nil
245+
XCTAssertNil(Drops.didDismissDrop)
246+
}
138247
}

0 commit comments

Comments
 (0)