@@ -12,24 +12,38 @@ import Combine
12
12
/// Note that the `KeyboardAdaptive` modifier wraps your view in a `GeometryReader`,
13
13
/// which attempts to fill all the available space, potentially increasing content view size.
14
14
struct KeyboardAdaptive : ViewModifier {
15
+ private let rerender : AnyPublisher < Any , Never >
15
16
@State private var bottomPadding : CGFloat = 0
16
-
17
+
18
+ init ( rerender: AnyPublisher < Any , Never > ? = nil ) {
19
+ var publishers = [ Publishers . keyboardHeight. map { arg -> Any in arg } . eraseToAnyPublisher ( ) ]
20
+ if let rerender = rerender {
21
+ publishers. append ( rerender)
22
+ }
23
+ self . rerender = Publishers . MergeMany ( publishers) . eraseToAnyPublisher ( )
24
+ }
25
+
26
+ private func bottomPadding( forGeometry geometry: GeometryProxy ) -> CGFloat {
27
+ let keyboardTop = geometry. frame ( in: . global) . height - Publishers. keyboardHeight. value
28
+ var focusedTextInputBottom = UIResponder . currentFirstResponder? . globalFrame? . maxY ?? 0
29
+ focusedTextInputBottom += bottomPadding / 2
30
+ return 2 * max( 0 , focusedTextInputBottom - keyboardTop - geometry. safeAreaInsets. bottom)
31
+ }
32
+
17
33
func body( content: Content ) -> some View {
18
34
GeometryReader { geometry in
19
35
content
20
36
. padding ( . bottom, self . bottomPadding)
21
- . onReceive ( Publishers . keyboardHeight) { keyboardHeight in
22
- let keyboardTop = geometry. frame ( in: . global) . height - keyboardHeight
23
- let focusedTextInputBottom = UIResponder . currentFirstResponder? . globalFrame? . maxY ?? 0
24
- self . bottomPadding = max ( 0 , focusedTextInputBottom - keyboardTop - geometry. safeAreaInsets. bottom)
25
- }
26
- . animation ( . easeOut( duration: 0.16 ) )
37
+ . onReceive ( self . rerender, perform: { _ in
38
+ self . bottomPadding = self . bottomPadding ( forGeometry: geometry)
39
+ } )
40
+ . animation ( . easeOut( duration: 0.16 ) )
27
41
}
28
42
}
29
43
}
30
44
31
45
extension View {
32
- func keyboardAdaptive( ) -> some View {
33
- ModifiedContent ( content: self , modifier: KeyboardAdaptive ( ) )
46
+ func keyboardAdaptive( rerender : AnyPublisher < Any , Never > ? = nil ) -> some View {
47
+ ModifiedContent ( content: self , modifier: KeyboardAdaptive ( rerender : rerender ) )
34
48
}
35
49
}
0 commit comments