Skip to content

Commit 8714a9f

Browse files
committed
wip
1 parent b84c0ab commit 8714a9f

File tree

6 files changed

+344
-6
lines changed

6 files changed

+344
-6
lines changed

Sources/AtomicTransition/Asymmetric.swift

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import class UIKit.UIView
2+
13
extension AtomicTransition {
24
/// Provides a composite transition that uses a different transition for insertion versus removal.
35
public static func asymmetric(insertion: Self, removal: Self) -> Self {
@@ -11,3 +13,56 @@ extension AtomicTransition {
1113
}
1214
}
1315
}
16+
17+
public struct Asymmetric<InsertionTransition: AtomicTransitionProtocol, RemovalTransition: AtomicTransitionProtocol>: AtomicTransitionProtocol {
18+
private let insertion: InsertionTransition
19+
private let removal: RemovalTransition
20+
21+
init(insertion: InsertionTransition, removal: RemovalTransition) {
22+
self.insertion = insertion
23+
self.removal = removal
24+
}
25+
26+
public func transition(_ view: TransientView, for operation: TransitionOperation, in container: Container) {
27+
switch operation {
28+
case .insertion:
29+
insertion.transition(view, for: operation, in: container)
30+
case .removal:
31+
removal.transition(view, for: operation, in: container)
32+
}
33+
}
34+
}
35+
36+
public struct OnInsertion<Transition: AtomicTransitionProtocol>: AtomicTransitionProtocol {
37+
private let transition: Transition
38+
39+
init(@AtomicTransitionBuilder transition: () -> Transition) {
40+
self.transition = transition()
41+
}
42+
43+
public func transition(_ view: TransientView, for operation: TransitionOperation, in container: Container) {
44+
switch operation {
45+
case .insertion:
46+
transition.transition(view, for: operation, in: container)
47+
case .removal:
48+
return
49+
}
50+
}
51+
}
52+
53+
public struct OnRemoval<Transition: AtomicTransitionProtocol>: AtomicTransitionProtocol {
54+
private let transition: Transition
55+
56+
init(@AtomicTransitionBuilder transition: () -> Transition) {
57+
self.transition = transition()
58+
}
59+
60+
public func transition(_ view: TransientView, for operation: TransitionOperation, in container: Container) {
61+
switch operation {
62+
case .insertion:
63+
return
64+
case .removal:
65+
transition.transition(view, for: operation, in: container)
66+
}
67+
}
68+
}

Sources/AtomicTransition/AtomicTransition.swift

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import Animator
2-
import UIKit
3-
4-
public typealias _Animator = Animator
1+
import class Animator.AnimatorTransientView
2+
import class UIKit.UIView
3+
import protocol UIKit.UIViewControllerContextTransitioning
54

65
/// Represents an atomic transition which applies to a single view. It is the building block of `NavigationTransition`.
76
///
@@ -10,8 +9,6 @@ public typealias _Animator = Animator
109
/// the overarching operation (push vs pop) is. This design allows great flexibility when defining fully-fledged
1110
/// navigation transitions. In other words, a `NavigationTransition` is the aggregate of two or more `AtomicTransition`s.
1211
public struct AtomicTransition {
13-
public typealias Animator = _Animator
14-
1512
public enum Operation {
1613
case insertion
1714
case removal
@@ -34,3 +31,16 @@ public struct AtomicTransition {
3431
self.handler(view, operation, context)
3532
}
3633
}
34+
35+
public enum AtomicTransitionOperation {
36+
case insertion
37+
case removal
38+
}
39+
40+
public protocol AtomicTransitionProtocol {
41+
typealias TransitionOperation = AtomicTransitionOperation
42+
typealias TransientView = AnimatorTransientView
43+
typealias Container = UIView
44+
45+
func transition(_ view: TransientView, for operation: TransitionOperation, in container: Container)
46+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
@resultBuilder
2+
public struct AtomicTransitionBuilder {
3+
public static func buildBlock() -> Identity {
4+
Identity()
5+
}
6+
7+
public static func buildBlock<
8+
T1: AtomicTransitionProtocol
9+
>(
10+
_ t1: T1
11+
) -> Tuple<(T1)> {
12+
Tuple((t1))
13+
}
14+
15+
public static func buildBlock<
16+
T1: AtomicTransitionProtocol,
17+
T2: AtomicTransitionProtocol
18+
>(
19+
_ t1: T1,
20+
_ t2: T2
21+
) -> Tuple<(T1, T2)> {
22+
Tuple((t1, t2))
23+
}
24+
25+
public static func buildBlock<
26+
T1: AtomicTransitionProtocol,
27+
T2: AtomicTransitionProtocol,
28+
T3: AtomicTransitionProtocol
29+
>(
30+
_ t1: T1,
31+
_ t2: T2,
32+
_ t3: T3
33+
) -> Tuple<(T1, T2, T3)> {
34+
Tuple((t1, t2, t3))
35+
}
36+
37+
public static func buildBlock<
38+
T1: AtomicTransitionProtocol,
39+
T2: AtomicTransitionProtocol,
40+
T3: AtomicTransitionProtocol,
41+
T4: AtomicTransitionProtocol
42+
>(
43+
_ t1: T1,
44+
_ t2: T2,
45+
_ t3: T3,
46+
_ t4: T4
47+
) -> Tuple<(T1, T2, T3, T4)> {
48+
Tuple((t1, t2, t3, t4))
49+
}
50+
51+
public static func buildBlock<
52+
T1: AtomicTransitionProtocol,
53+
T2: AtomicTransitionProtocol,
54+
T3: AtomicTransitionProtocol,
55+
T4: AtomicTransitionProtocol,
56+
T5: AtomicTransitionProtocol
57+
>(
58+
_ t1: T1,
59+
_ t2: T2,
60+
_ t3: T3,
61+
_ t4: T4,
62+
_ t5: T5
63+
) -> Tuple<(T1, T2, T3, T4, T5)> {
64+
Tuple((t1, t2, t3, t4, t5))
65+
}
66+
67+
public static func buildBlock<
68+
T1: AtomicTransitionProtocol,
69+
T2: AtomicTransitionProtocol,
70+
T3: AtomicTransitionProtocol,
71+
T4: AtomicTransitionProtocol,
72+
T5: AtomicTransitionProtocol,
73+
T6: AtomicTransitionProtocol
74+
>(
75+
_ t1: T1,
76+
_ t2: T2,
77+
_ t3: T3,
78+
_ t4: T4,
79+
_ t5: T5,
80+
_ t6: T6
81+
) -> Tuple<(T1, T2, T3, T4, T5, T6)> {
82+
Tuple((t1, t2, t3, t4, t5, t6))
83+
}
84+
85+
public static func buildBlock<
86+
T1: AtomicTransitionProtocol,
87+
T2: AtomicTransitionProtocol,
88+
T3: AtomicTransitionProtocol,
89+
T4: AtomicTransitionProtocol,
90+
T5: AtomicTransitionProtocol,
91+
T6: AtomicTransitionProtocol,
92+
T7: AtomicTransitionProtocol
93+
>(
94+
_ t1: T1,
95+
_ t2: T2,
96+
_ t3: T3,
97+
_ t4: T4,
98+
_ t5: T5,
99+
_ t6: T6,
100+
_ t7: T7
101+
) -> Tuple<(T1, T2, T3, T4, T5, T6, T7)> {
102+
Tuple((t1, t2, t3, t4, t5, t6, t7))
103+
}
104+
}

Sources/AtomicTransition/Combined.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import class UIKit.UIView
2+
13
extension AtomicTransition {
24
/// Combines this transition with another, returning a new transition that is the result of both transitions
35
/// being applied.
@@ -16,3 +18,22 @@ extension Collection where Element == AtomicTransition {
1618
reduce(.identity) { $0.combined(with: $1) }
1719
}
1820
}
21+
22+
public struct Combined<TransitionA: AtomicTransitionProtocol, TransitionB: AtomicTransitionProtocol>: AtomicTransitionProtocol {
23+
private let transitionA: TransitionA
24+
private let transitionB: TransitionB
25+
26+
init(transitionA: TransitionA, transitionB: TransitionB) {
27+
self.transitionA = transitionA
28+
self.transitionB = transitionB
29+
}
30+
31+
public init(@AtomicTransitionBuilder _ builder: () -> TransitionA) where TransitionB == Identity {
32+
self.init(transitionA: builder(), transitionB: Identity())
33+
}
34+
35+
public func transition(_ view: TransientView, for operation: TransitionOperation, in container: Container) {
36+
transitionA.transition(view, for: operation, in: container)
37+
transitionB.transition(view, for: operation, in: container)
38+
}
39+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
1+
import class UIKit.UIView
2+
13
extension AtomicTransition {
24
/// A transition that returns the input view, unmodified, as the output view.
35
public static var identity: Self {
46
.init { _, _, _ in }
57
}
68
}
9+
10+
public struct Identity: AtomicTransitionProtocol {
11+
public init() {}
12+
13+
public func transition(_ view: TransientView, for operation: TransitionOperation, in container: Container) {
14+
// NO-OP
15+
}
16+
}

Sources/AtomicTransition/Tuple.swift

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import class Animator.AnimatorTransientView
2+
import class UIKit.UIView
3+
4+
/// Inspired by `TupleView` in SwiftUI.
5+
///
6+
/// This type helps collect all transitions in `AtomicTransitionBuilder` and forward over their implementation
7+
/// without losing type information.
8+
public struct Tuple<T>: AtomicTransitionProtocol {
9+
var value: T
10+
11+
init(_ value: T) {
12+
self.value = value
13+
}
14+
15+
public func transition(_ view: TransientView, for operation: TransitionOperation, in container: Container) {
16+
fatalError("Invalid AtomicTransition Tuple type \(type(of: self))")
17+
}
18+
}
19+
20+
extension Tuple {
21+
public func transition(
22+
_ view: TransientView,
23+
for operation: TransitionOperation,
24+
in container: Container
25+
) where T == () {
26+
// NO-OP
27+
}
28+
29+
public func transition(
30+
_ view: TransientView,
31+
for operation: TransitionOperation,
32+
in container: Container
33+
) where T: AtomicTransitionProtocol {
34+
value.transition(view, for: operation, in: container)
35+
}
36+
37+
public func transition<
38+
T1: AtomicTransitionProtocol,
39+
T2: AtomicTransitionProtocol
40+
>(
41+
_ view: TransientView,
42+
for operation: TransitionOperation,
43+
in container: Container
44+
) where T == (T1, T2) {
45+
value.0.transition(view, for: operation, in: container)
46+
value.1.transition(view, for: operation, in: container)
47+
}
48+
49+
public func transition<
50+
T1: AtomicTransitionProtocol,
51+
T2: AtomicTransitionProtocol,
52+
T3: AtomicTransitionProtocol
53+
>(
54+
_ view: TransientView,
55+
for operation: TransitionOperation,
56+
in container: Container
57+
) where T == (T1, T2, T3) {
58+
value.0.transition(view, for: operation, in: container)
59+
value.1.transition(view, for: operation, in: container)
60+
value.2.transition(view, for: operation, in: container)
61+
}
62+
63+
public func transition<
64+
T1: AtomicTransitionProtocol,
65+
T2: AtomicTransitionProtocol,
66+
T3: AtomicTransitionProtocol,
67+
T4: AtomicTransitionProtocol
68+
>(
69+
_ view: TransientView,
70+
for operation: TransitionOperation,
71+
in container: Container
72+
) where T == (T1, T2, T3, T4) {
73+
value.0.transition(view, for: operation, in: container)
74+
value.1.transition(view, for: operation, in: container)
75+
value.2.transition(view, for: operation, in: container)
76+
value.3.transition(view, for: operation, in: container)
77+
}
78+
79+
public func transition<
80+
T1: AtomicTransitionProtocol,
81+
T2: AtomicTransitionProtocol,
82+
T3: AtomicTransitionProtocol,
83+
T4: AtomicTransitionProtocol,
84+
T5: AtomicTransitionProtocol
85+
>(
86+
_ view: TransientView,
87+
for operation: TransitionOperation,
88+
in container: Container
89+
) where T == (T1, T2, T3, T4, T5) {
90+
value.0.transition(view, for: operation, in: container)
91+
value.1.transition(view, for: operation, in: container)
92+
value.2.transition(view, for: operation, in: container)
93+
value.3.transition(view, for: operation, in: container)
94+
value.4.transition(view, for: operation, in: container)
95+
}
96+
97+
public func transition<
98+
T1: AtomicTransitionProtocol,
99+
T2: AtomicTransitionProtocol,
100+
T3: AtomicTransitionProtocol,
101+
T4: AtomicTransitionProtocol,
102+
T5: AtomicTransitionProtocol,
103+
T6: AtomicTransitionProtocol
104+
>(
105+
_ view: TransientView,
106+
for operation: TransitionOperation,
107+
in container: Container
108+
) where T == (T1, T2, T3, T4, T5, T6) {
109+
value.0.transition(view, for: operation, in: container)
110+
value.1.transition(view, for: operation, in: container)
111+
value.2.transition(view, for: operation, in: container)
112+
value.3.transition(view, for: operation, in: container)
113+
value.4.transition(view, for: operation, in: container)
114+
value.5.transition(view, for: operation, in: container)
115+
}
116+
117+
public func transition<
118+
T1: AtomicTransitionProtocol,
119+
T2: AtomicTransitionProtocol,
120+
T3: AtomicTransitionProtocol,
121+
T4: AtomicTransitionProtocol,
122+
T5: AtomicTransitionProtocol,
123+
T6: AtomicTransitionProtocol,
124+
T7: AtomicTransitionProtocol
125+
>(
126+
_ view: TransientView,
127+
for operation: TransitionOperation,
128+
in container: Container
129+
) where T == (T1, T2, T3, T4, T5, T6, T7) {
130+
value.0.transition(view, for: operation, in: container)
131+
value.1.transition(view, for: operation, in: container)
132+
value.2.transition(view, for: operation, in: container)
133+
value.3.transition(view, for: operation, in: container)
134+
value.4.transition(view, for: operation, in: container)
135+
value.5.transition(view, for: operation, in: container)
136+
value.6.transition(view, for: operation, in: container)
137+
}
138+
}

0 commit comments

Comments
 (0)