@@ -32,10 +32,6 @@ public final class EdgeAligningView<CustomView: UIView>: UIView {
32
32
/// Bottom edge
33
33
case bottom
34
34
35
- var otherEdges : [ Edge ] {
36
- Edge . allCases. filter { $0 != self }
37
- }
38
-
39
35
}
40
36
41
37
/// Set of edge constraints to be set as loose.
@@ -44,23 +40,32 @@ public final class EdgeAligningView<CustomView: UIView>: UIView {
44
40
guard flexibleEdges != oldValue else {
45
41
return
46
42
}
47
- setupContainer ( )
43
+ lastConstraintsUpdateEdges = nil
44
+ setNeedsUpdateConstraints ( )
48
45
}
49
46
}
50
47
51
48
/// Contained view.
52
49
public var customView : CustomView {
53
50
didSet {
54
- guard customView != oldValue else {
51
+ guard customView !== oldValue else {
55
52
return
56
53
}
57
54
oldValue. removeFromSuperview ( )
58
55
setupContainer ( )
59
56
}
60
57
}
61
58
59
+ private var rigidConstraints : [ Edge : NSLayoutConstraint ] = [ : ]
60
+
61
+ private var flexibleConstraints : [ Edge : NSLayoutConstraint ] = [ : ]
62
+
63
+ private var centerConstraints : ( centerX: NSLayoutConstraint , centerY: NSLayoutConstraint ) ?
64
+
62
65
private var addedConstraints : [ NSLayoutConstraint ] = [ ]
63
66
67
+ private var lastConstraintsUpdateEdges : Set < Edge > ?
68
+
64
69
/// Initializes and returns a newly allocated `EdgeAligningView`
65
70
/// - Parameters:
66
71
/// - customView: An instance of `CustomView`
@@ -87,6 +92,28 @@ public final class EdgeAligningView<CustomView: UIView>: UIView {
87
92
fatalError ( " Use init(with:flexibleEdges:) instead. " )
88
93
}
89
94
95
+ public override func updateConstraints( ) {
96
+ guard lastConstraintsUpdateEdges != flexibleEdges else {
97
+ super. updateConstraints ( )
98
+ return
99
+ }
100
+
101
+ flexibleEdges. forEach { edge in
102
+ rigidConstraints [ edge] ? . isActive = false
103
+ flexibleConstraints [ edge] ? . isActive = true
104
+ }
105
+ Set ( Edge . allCases) . subtracting ( flexibleEdges) . forEach { edge in
106
+ flexibleConstraints [ edge] ? . isActive = false
107
+ rigidConstraints [ edge] ? . isActive = true
108
+ }
109
+ centerConstraints? . centerX. isActive = flexibleEdges. contains ( . leading) && flexibleEdges. contains ( . trailing)
110
+ centerConstraints? . centerY. isActive = flexibleEdges. contains ( . top) && flexibleEdges. contains ( . bottom)
111
+
112
+ lastConstraintsUpdateEdges = flexibleEdges
113
+
114
+ super. updateConstraints ( )
115
+ }
116
+
90
117
private func setupSubviews( ) {
91
118
translatesAutoresizingMaskIntoConstraints = false
92
119
insetsLayoutMarginsFromSafeArea = false
@@ -104,55 +131,40 @@ public final class EdgeAligningView<CustomView: UIView>: UIView {
104
131
removeConstraints ( addedConstraints)
105
132
addedConstraints. removeAll ( )
106
133
}
107
- Set ( Edge . allCases) . subtracting ( flexibleEdges) . forEach { setConstraint ( for: $0, on: customView, flexible: false ) }
108
- flexibleEdges. forEach { setConstraint ( for: $0, on: customView, flexible: true ) }
109
- setDistributionConstraint ( on: customView)
110
- setNeedsLayout ( )
134
+
135
+ lastConstraintsUpdateEdges = nil
136
+
137
+ let rigidConstraints = buildRigidConstraints ( customView)
138
+ let flexibleConstraints = buildFlexibleConstraints ( customView)
139
+ let centerConstraints = buildCenterConstraints ( customView)
140
+
141
+ addedConstraints. append ( contentsOf: rigidConstraints. values)
142
+ addedConstraints. append ( contentsOf: flexibleConstraints. values)
143
+ addedConstraints. append ( centerConstraints. centerX)
144
+ addedConstraints. append ( centerConstraints. centerY)
145
+
146
+ self . rigidConstraints = rigidConstraints
147
+ self . flexibleConstraints = flexibleConstraints
148
+ self . centerConstraints = centerConstraints
149
+ setNeedsUpdateConstraints ( )
111
150
}
112
151
113
- private func setConstraint( for edge: Edge , on view: UIView , flexible: Bool = false ) {
114
- var addedConstraints : [ NSLayoutConstraint ] = [ ]
115
- switch edge {
116
- case . top:
117
- if flexible {
118
- addedConstraints. append ( view. topAnchor. constraint ( greaterThanOrEqualTo: layoutMarginsGuide. topAnchor) )
119
- } else {
120
- addedConstraints. append ( view. topAnchor. constraint ( equalTo: layoutMarginsGuide. topAnchor) )
121
- }
122
- case . leading:
123
- if flexible {
124
- addedConstraints. append ( view. leadingAnchor. constraint ( greaterThanOrEqualTo: layoutMarginsGuide. leadingAnchor) )
125
- } else {
126
- addedConstraints. append ( view. leadingAnchor. constraint ( equalTo: layoutMarginsGuide. leadingAnchor) )
127
- }
128
- case . trailing:
129
- if flexible {
130
- addedConstraints. append ( view. trailingAnchor. constraint ( lessThanOrEqualTo: layoutMarginsGuide. trailingAnchor) )
131
- } else {
132
- addedConstraints. append ( view. trailingAnchor. constraint ( equalTo: layoutMarginsGuide. trailingAnchor) )
133
- }
134
- case . bottom:
135
- if flexible {
136
- addedConstraints. append ( view. bottomAnchor. constraint ( lessThanOrEqualTo: layoutMarginsGuide. bottomAnchor) )
137
- } else {
138
- addedConstraints. append ( view. bottomAnchor. constraint ( equalTo: layoutMarginsGuide. bottomAnchor) )
139
- }
140
- }
141
- NSLayoutConstraint . activate ( addedConstraints)
142
- self . addedConstraints. append ( contentsOf: addedConstraints)
152
+ private func buildCenterConstraints( _ view: UIView ) -> ( centerX: NSLayoutConstraint , centerY: NSLayoutConstraint ) {
153
+ ( centerX: view. centerXAnchor. constraint ( equalTo: layoutMarginsGuide. centerXAnchor) , centerY: view. centerYAnchor. constraint ( equalTo: layoutMarginsGuide. centerYAnchor) )
143
154
}
144
155
145
- private func setDistributionConstraint( on view: UIView ) {
146
- if flexibleEdges. contains ( . leading) , flexibleEdges. contains ( . trailing) {
147
- let layoutConstraint = view. centerXAnchor. constraint ( equalTo: layoutMarginsGuide. centerXAnchor)
148
- addedConstraints. append ( layoutConstraint)
149
- layoutConstraint. isActive = true
150
- }
151
- if flexibleEdges. contains ( . top) , flexibleEdges. contains ( . bottom) {
152
- let layoutConstraint = view. centerYAnchor. constraint ( equalTo: layoutMarginsGuide. centerYAnchor)
153
- addedConstraints. append ( layoutConstraint)
154
- layoutConstraint. isActive = true
155
- }
156
+ private func buildRigidConstraints( _ view: UIView ) -> [ Edge : NSLayoutConstraint ] {
157
+ [ . top: view. topAnchor. constraint ( equalTo: layoutMarginsGuide. topAnchor) ,
158
+ . bottom: view. bottomAnchor. constraint ( equalTo: layoutMarginsGuide. bottomAnchor) ,
159
+ . leading: view. leadingAnchor. constraint ( equalTo: layoutMarginsGuide. leadingAnchor) ,
160
+ . trailing: view. trailingAnchor. constraint ( equalTo: layoutMarginsGuide. trailingAnchor) ]
161
+ }
162
+
163
+ private func buildFlexibleConstraints( _ view: UIView ) -> [ Edge : NSLayoutConstraint ] {
164
+ [ . top: view. topAnchor. constraint ( greaterThanOrEqualTo: layoutMarginsGuide. topAnchor) ,
165
+ . bottom: view. bottomAnchor. constraint ( lessThanOrEqualTo: layoutMarginsGuide. bottomAnchor) ,
166
+ . leading: view. leadingAnchor. constraint ( greaterThanOrEqualTo: layoutMarginsGuide. leadingAnchor) ,
167
+ . trailing: view. trailingAnchor. constraint ( lessThanOrEqualTo: layoutMarginsGuide. trailingAnchor) ]
156
168
}
157
169
158
170
}
0 commit comments