@@ -109,12 +109,40 @@ struct StrictFrameView<Child: View>: TypeSafeView {
109109 backend. setPosition ( ofChildAt: 0 , in: widget, to: childPosition)
110110 }
111111
112+ let idealWidth : Int
113+ let idealHeight : Int
114+ if let width, let height {
115+ idealWidth = width
116+ idealHeight = height
117+ } else if let width, height == nil {
118+ idealWidth = width
119+ idealHeight = childSize. idealHeightForProposedWidth
120+ } else if let height, width == nil {
121+ idealHeight = height
122+ idealWidth = childSize. idealWidthForProposedHeight
123+ } else {
124+ idealWidth = childSize. idealSize. x
125+ idealHeight = childSize. idealSize. y
126+ }
127+
128+ let idealWidthForProposedHeight : Int
129+ let idealHeightForProposedWidth : Int
130+ if width == nil && height == nil {
131+ idealWidthForProposedHeight = childSize. idealWidthForProposedHeight
132+ idealHeightForProposedWidth = childSize. idealHeightForProposedWidth
133+ } else {
134+ idealWidthForProposedHeight = idealWidth
135+ idealHeightForProposedWidth = idealHeight
136+ }
137+
112138 return ViewSize (
113139 size: frameSize,
114140 idealSize: SIMD2 (
115- width ?? childSize . idealSize . x ,
116- height ?? childSize . idealSize . y
141+ idealWidth ,
142+ idealHeight
117143 ) ,
144+ idealWidthForProposedHeight: idealWidthForProposedHeight,
145+ idealHeightForProposedWidth: idealHeightForProposedWidth,
118146 minimumWidth: width ?? childSize. minimumWidth,
119147 minimumHeight: height ?? childSize. minimumHeight,
120148 maximumWidth: width. map ( Double . init) ?? childSize. maximumWidth,
@@ -183,9 +211,6 @@ struct FlexibleFrameView<Child: View>: TypeSafeView {
183211 dryRun: Bool
184212 ) -> ViewSize {
185213 var proposedFrameSize = proposedSize
186- if let idealWidth {
187- proposedFrameSize. x = min ( proposedFrameSize. x, idealWidth)
188- }
189214 if let minWidth {
190215 proposedFrameSize. x = max ( proposedFrameSize. x, minWidth)
191216 }
@@ -198,9 +223,6 @@ struct FlexibleFrameView<Child: View>: TypeSafeView {
198223 if let maxHeight {
199224 proposedFrameSize. y = min ( proposedFrameSize. y, maxHeight)
200225 }
201- if let idealHeight {
202- proposedFrameSize. y = min ( proposedFrameSize. y, idealHeight)
203- }
204226
205227 let childSize = children. child0. update (
206228 with: body. view0,
@@ -209,27 +231,50 @@ struct FlexibleFrameView<Child: View>: TypeSafeView {
209231 dryRun: dryRun
210232 )
211233
234+ // TODO: Fix idealSize propagation. When idealSize isn't possible, we
235+ // have to use idealWidthForProposedHeight and
236+ // idealHeightForProposedWidth, and sometimes we may also have to
237+ // perform an additional dryRun update to probe the child view.
238+
212239 var frameSize = childSize
213240 if let minWidth {
214241 frameSize. size. x = max ( frameSize. size. x, minWidth)
215242 frameSize. minimumWidth = minWidth
216243 frameSize. idealSize. x = max ( frameSize. idealSize. x, minWidth)
244+ frameSize. idealWidthForProposedHeight = max (
245+ frameSize. idealWidthForProposedHeight,
246+ minWidth
247+ )
217248 }
218249 if let maxWidth {
219250 frameSize. size. x = min ( frameSize. size. x, maxWidth)
220251 frameSize. idealSize. x = min ( frameSize. idealSize. x, maxWidth)
221252 frameSize. maximumWidth = min ( childSize. maximumWidth, Double ( maxWidth) )
253+ frameSize. idealWidthForProposedHeight = min (
254+ frameSize. idealWidthForProposedHeight,
255+ maxWidth
256+ )
222257 }
258+
223259 if let minHeight {
224260 frameSize. size. y = max ( frameSize. size. y, minHeight)
225261 frameSize. minimumHeight = minHeight
226262 frameSize. idealSize. y = max ( frameSize. idealSize. y, minHeight)
263+ frameSize. idealHeightForProposedWidth = max (
264+ frameSize. idealHeightForProposedWidth,
265+ minHeight
266+ )
227267 }
228268 if let maxHeight {
229269 frameSize. size. y = min ( frameSize. size. y, maxHeight)
230270 frameSize. idealSize. y = min ( frameSize. idealSize. y, maxHeight)
231271 frameSize. maximumHeight = min ( childSize. maximumHeight, Double ( maxHeight) )
272+ frameSize. idealHeightForProposedWidth = min (
273+ frameSize. idealHeightForProposedWidth,
274+ maxHeight
275+ )
232276 }
277+
233278 if let idealWidth {
234279 frameSize. idealSize. x = idealWidth
235280 }
0 commit comments