Skip to content

Commit 60cdbed

Browse files
committed
wip
1 parent 8714a9f commit 60cdbed

File tree

9 files changed

+171
-1
lines changed

9 files changed

+171
-1
lines changed

Sources/AtomicTransition/AtomicTransitionBuilder.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
@resultBuilder
22
public struct AtomicTransitionBuilder {
3+
#if compiler(>=5.7)
4+
public static func buildPartialBlock(first: some AtomicTransitionProtocol) -> some AtomicTransitionProtocol {
5+
first
6+
}
7+
8+
public static func buildPartialBlock(accumulated: some AtomicTransitionProtocol, next: some AtomicTransitionProtocol) -> some AtomicTransitionProtocol {
9+
Combined(accumulated, next)
10+
}
11+
#else
312
public static func buildBlock() -> Identity {
413
Identity()
514
}
@@ -101,4 +110,5 @@ public struct AtomicTransitionBuilder {
101110
) -> Tuple<(T1, T2, T3, T4, T5, T6, T7)> {
102111
Tuple((t1, t2, t3, t4, t5, t6, t7))
103112
}
113+
#endif
104114
}

Sources/AtomicTransition/Combined.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,26 @@ public struct Combined<TransitionA: AtomicTransitionProtocol, TransitionB: Atomi
2323
private let transitionA: TransitionA
2424
private let transitionB: TransitionB
2525

26-
init(transitionA: TransitionA, transitionB: TransitionB) {
26+
init(_ transitionA: TransitionA, _ transitionB: TransitionB) {
2727
self.transitionA = transitionA
2828
self.transitionB = transitionB
2929
}
3030

31+
#if compiler(>=5.7)
32+
public init(@AtomicTransitionBuilder _ builder: () -> Self) {
33+
self = builder()
34+
}
35+
#else
3136
public init(@AtomicTransitionBuilder _ builder: () -> TransitionA) where TransitionB == Identity {
3237
self.init(transitionA: builder(), transitionB: Identity())
3338
}
39+
#endif
3440

3541
public func transition(_ view: TransientView, for operation: TransitionOperation, in container: Container) {
3642
transitionA.transition(view, for: operation, in: container)
3743
transitionB.transition(view, for: operation, in: container)
3844
}
3945
}
46+
47+
extension Combined: Equatable where TransitionA: Equatable, TransitionB: Equatable {}
48+
extension Combined: Hashable where TransitionA: Hashable, TransitionB: Hashable {}

Sources/AtomicTransition/Identity.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,5 @@ public struct Identity: AtomicTransitionProtocol {
1414
// NO-OP
1515
}
1616
}
17+
18+
extension Identity: Hashable {}

Sources/AtomicTransition/Move.swift

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,49 @@ extension AtomicTransition {
4040
}
4141
}
4242
}
43+
44+
public struct Move: AtomicTransitionProtocol {
45+
private let edge: Edge
46+
47+
public init(edge: Edge) {
48+
self.edge = edge
49+
}
50+
51+
public func transition(_ view: TransientView, for operation: TransitionOperation, in container: Container) {
52+
switch (edge, operation) {
53+
case (.top, .insertion):
54+
view.initial.translation.dy = -container.frame.height
55+
view.animation.translation.dy = 0
56+
57+
case (.leading, .insertion):
58+
view.initial.translation.dx = -container.frame.width
59+
view.animation.translation.dx = 0
60+
61+
case (.trailing, .insertion):
62+
view.initial.translation.dx = container.frame.width
63+
view.animation.translation.dx = 0
64+
65+
case (.bottom, .insertion):
66+
view.initial.translation.dy = container.frame.height
67+
view.animation.translation.dy = 0
68+
69+
case (.top, .removal):
70+
view.animation.translation.dy = -container.frame.height
71+
view.completion.translation.dy = 0
72+
73+
case (.leading, .removal):
74+
view.animation.translation.dx = -container.frame.width
75+
view.completion.translation.dx = 0
76+
77+
case (.trailing, .removal):
78+
view.animation.translation.dx = container.frame.width
79+
view.completion.translation.dx = 0
80+
81+
case (.bottom, .removal):
82+
view.animation.translation.dy = container.frame.height
83+
view.completion.translation.dy = 0
84+
}
85+
}
86+
}
87+
88+
extension Move: Hashable {}

Sources/AtomicTransition/Offset.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,28 @@ extension AtomicTransition {
3535
.offset(x: offset.width, y: offset.height)
3636
}
3737
}
38+
39+
public struct Offset: AtomicTransitionProtocol {
40+
private let x: CGFloat
41+
private let y: CGFloat
42+
43+
public init(x: CGFloat, y: CGFloat) {
44+
self.x = x
45+
self.y = y
46+
}
47+
48+
public func transition(_ view: TransientView, for operation: TransitionOperation, in container: Container) {
49+
switch operation {
50+
case .insertion:
51+
view.initial.translation.dx += x
52+
view.initial.translation.dy += y
53+
view.animation.transform = .identity
54+
case .removal:
55+
view.animation.translation.dx += x
56+
view.animation.translation.dy += y
57+
view.completion.transform = .identity
58+
}
59+
}
60+
}
61+
62+
extension Offset: Hashable {}

Sources/AtomicTransition/Opacity.swift

Lines changed: 19 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
/// A transition from transparent to opaque on insertion, and from opaque to transparent on removal.
35
public static var opacity: Self {
@@ -13,3 +15,20 @@ extension AtomicTransition {
1315
}
1416
}
1517
}
18+
19+
public struct Opacity: AtomicTransitionProtocol {
20+
public init() {}
21+
22+
public func transition(_ view: TransientView, for operation: TransitionOperation, in container: Container) {
23+
switch operation {
24+
case .insertion:
25+
view.initial.alpha = 0
26+
view.animation.alpha = 1
27+
case .removal:
28+
view.animation.alpha = 0
29+
view.completion.alpha = 1
30+
}
31+
}
32+
}
33+
34+
extension Opacity: Hashable {}

Sources/AtomicTransition/Rotate.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,24 @@ extension AtomicTransition {
1515
}
1616
}
1717
}
18+
19+
public struct Rotate: AtomicTransitionProtocol {
20+
private let angle: Angle
21+
22+
public init(_ angle: Angle) {
23+
self.angle = angle
24+
}
25+
26+
public func transition(_ view: TransientView, for operation: TransitionOperation, in container: Container) {
27+
switch operation {
28+
case .insertion:
29+
view.initial.rotation += angle.radians
30+
view.animation.transform = .identity
31+
case .removal:
32+
view.animation.rotation += angle.radians
33+
view.completion.transform = .identity
34+
}
35+
}
36+
}
37+
38+
extension Rotate: Hashable {}

Sources/AtomicTransition/Scale.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,24 @@ extension AtomicTransition {
2323
.scale(.leastNonzeroMagnitude)
2424
}
2525
}
26+
27+
public struct Scale: AtomicTransitionProtocol {
28+
private let scale: CGFloat
29+
30+
public init(_ scale: CGFloat) {
31+
self.scale = scale
32+
}
33+
34+
public func transition(_ view: TransientView, for operation: TransitionOperation, in container: Container) {
35+
switch operation {
36+
case .insertion:
37+
view.initial.scale = .init(width: scale, height: scale)
38+
view.animation.transform = .identity
39+
case .removal:
40+
view.animation.scale = .init(width: scale, height: scale)
41+
view.completion.transform = .identity
42+
}
43+
}
44+
}
45+
46+
extension Scale: Hashable {}

Sources/AtomicTransition/ZPosition.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
@_spi(package) import Animator
2+
import class UIKit.UIView
23

34
extension AtomicTransition {
45
public enum ZPosition {
@@ -30,3 +31,19 @@ extension AtomicTransition {
3031
.zPosition(.back)
3132
}
3233
}
34+
35+
public struct BringToFront: AtomicTransitionProtocol {
36+
public func transition(_ view: TransientView, for operation: TransitionOperation, in container: Container) {
37+
container.bringSubviewToFront(view.uiView)
38+
}
39+
}
40+
41+
extension BringToFront: Hashable {}
42+
43+
public struct SendToBack: AtomicTransitionProtocol {
44+
public func transition(_ view: TransientView, for operation: TransitionOperation, in container: Container) {
45+
container.sendSubviewToBack(view.uiView)
46+
}
47+
}
48+
49+
extension SendToBack: Hashable {}

0 commit comments

Comments
 (0)