@@ -25,6 +25,7 @@ public func UIStackViewSpace(_ value: CGFloat, withSummation: Bool = false) -> U
2525 stackView. setCustomSpacing ( finalSpace, after: view)
2626 }
2727}
28+
2829public func UIStackViewSpace( _ value: CGFloat , bindVisibilityTo view: UIView ) -> UIStackViewConfiguration {
2930 AnyUIStackViewConfiguration { [ weak view] ( stackView: UIStackView ) in
3031 guard let view = view else { return }
@@ -47,18 +48,65 @@ public func UIStackViewSpace(_ value: CGFloat, bindVisibilityTo view: UIView) ->
4748 }
4849}
4950
50- public typealias UIStackViewSpaceObserver = ( CGFloat ) -> Void
51- public typealias UIStackViewSpaceProvider = ( UIStackViewSpaceObserver ) -> Void
51+ public final class UIStackViewDynamicSpaceProvider {
52+ public init ( _ initialValue: CGFloat = UIStackView . spacingUseDefault) {
53+ self . currentValue = initialValue
54+ }
55+
56+ private( set) public var currentValue : CGFloat
57+
58+ private var observers : [ ( CGFloat ) -> ( ) ] = [ ]
59+
60+ fileprivate func addObserver( _ observer: @escaping ( CGFloat ) -> Void ) {
61+ observers. append ( observer)
62+ observer ( currentValue)
63+ }
64+
65+ public func update( with newValue: CGFloat ) {
66+ currentValue = newValue
67+ for observer in observers { observer ( currentValue) }
68+ }
69+ }
70+
71+ public extension UIStackViewDynamicSpaceProvider {
72+ static func binding( space: CGFloat , toVisibility view: UIView ) -> UIStackViewDynamicSpaceProvider {
73+ func getSpace( isHidden: Bool ) -> CGFloat {
74+ if isHidden { return UIStackView . spacingUseDefault }
75+ else { return space }
76+ }
77+
78+ let provider = UIStackViewDynamicSpaceProvider ( getSpace ( isHidden: view. isHidden) )
79+
80+ let subscription = view. observe (
81+ \. isHidden,
82+ options: [ . new] ,
83+ changeHandler: { [ weak provider] _, update in
84+ guard let newSpace = update. newValue. map ( getSpace ( isHidden: ) )
85+ else { return }
86+
87+ provider? . update ( with: newSpace)
88+ } )
89+
90+ whenDeallocated ( view, { [ weak provider] in
91+ provider? . update ( with: getSpace ( isHidden: true ) )
92+ subscription. invalidate ( )
93+ } )
94+
95+ return provider
96+ }
97+ }
5298
53- public func UIStackViewSpace( dynamic provider: @escaping UIStackViewSpaceProvider ) -> UIStackViewConfiguration {
99+ public func UIStackViewSpace( _ provider: UIStackViewDynamicSpaceProvider ) -> UIStackViewConfiguration {
54100 AnyUIStackViewConfiguration { ( stackView: UIStackView ) in
55101 let view = stackView. lastArrangedView
56102
57- provider ( { [ weak stackView, weak view] ( newSpace: CGFloat ) in
103+ provider. addObserver ( onMainThread { [ weak stackView, weak view] ( newSpace: CGFloat ) in
58104 guard let view = view else { return }
59105
60106 stackView? . setCustomSpacing ( newSpace, after: view)
61107 } )
108+
109+ whenDeallocated ( stackView, { _ = provider } )
62110 }
63111}
64112
@@ -72,18 +120,4 @@ private extension UIStackView {
72120 }
73121
74122 static let systemSpaces = [ UIStackView . spacingUseDefault, UIStackView . spacingUseSystem]
75-
76- func observeArrangedSubviews( _ observer: @escaping ( [ UIView ] ) -> Void ) {
77- let subscription = layer. observe (
78- \. sublayers,
79-
80- options: [ . initial, . new] ,
81-
82- changeHandler: { [ unowned self] _, _ in
83- observer ( arrangedSubviews)
84- }
85- )
86-
87- whenDeallocated ( self , subscription. invalidate)
88- }
89123}
0 commit comments