|
3 | 3 | // OpenSwiftUI |
4 | 4 | // |
5 | 5 | // Audited for 6.5.4 |
6 | | -// Status: WIP |
| 6 | +// Status: Complete |
7 | 7 | // ID: 220887A402CE7023D01D5BCC1E080716 (SwiftUI) |
8 | 8 |
|
| 9 | +import OpenAttributeGraphShims |
9 | 10 | @_spi(ForOpenSwiftUIOnly) |
10 | 11 | import OpenSwiftUICore |
11 | 12 |
|
12 | | -// MARK: - FocusEventProxyResponder [TBA] |
| 13 | +// MARK: - FocusEventProxyResponder |
13 | 14 |
|
14 | | -class FocusEventProxyResponder: DefaultLayoutViewResponder {} |
| 15 | +private class FocusEventProxyResponder: DefaultLayoutViewResponder {} |
| 16 | + |
| 17 | +@inline(__always) |
| 18 | +func asFocusEventProxyResponder(_ responder: ResponderNode) -> ViewResponder? { |
| 19 | + responder as? FocusEventProxyResponder |
| 20 | +} |
| 21 | + |
| 22 | +#if os(iOS) || os(visionOS) |
| 23 | +// MARK: - FocusEventProxyModifier |
| 24 | + |
| 25 | +struct FocusEventProxyModifier: MultiViewModifier, PrimitiveViewModifier { |
| 26 | + static func _makeView( |
| 27 | + modifier: _GraphValue<Self>, |
| 28 | + inputs: _ViewInputs, |
| 29 | + body: @escaping (_Graph, _ViewInputs) -> _ViewOutputs |
| 30 | + ) -> _ViewOutputs { |
| 31 | + var outputs = body(_Graph(), inputs) |
| 32 | + guard IOSFocusEnabledFlag.evaluate(inputs: inputs.base), |
| 33 | + inputs.preferences.requiresViewResponders else { |
| 34 | + return outputs |
| 35 | + } |
| 36 | + outputs.preferences.viewResponders = Attribute(FocusEventProxyResponderFilter( |
| 37 | + children: outputs.viewResponders(), |
| 38 | + responder: FocusEventProxyResponder(inputs: inputs) |
| 39 | + )) |
| 40 | + return outputs |
| 41 | + } |
| 42 | +} |
| 43 | + |
| 44 | +// MARK: - FocusEventProxyResponderFilter |
| 45 | + |
| 46 | +private struct FocusEventProxyResponderFilter: StatefulRule { |
| 47 | + @Attribute var children: [ViewResponder] |
| 48 | + |
| 49 | + let responder: FocusEventProxyResponder |
| 50 | + |
| 51 | + typealias Value = [ViewResponder] |
| 52 | + |
| 53 | + mutating func updateValue() { |
| 54 | + responder.updateChildren($children.changedValue()) |
| 55 | + if !hasValue { |
| 56 | + value = [responder] |
| 57 | + } |
| 58 | + } |
| 59 | +} |
| 60 | +#endif |
0 commit comments