@@ -65,7 +65,7 @@ public protocol NSViewRepresentable: View where Content == Never {
65
65
/// This method is called after all AppKit lifecycle methods, such as
66
66
/// `nsView.didMoveToSuperview()`. The default implementation does nothing.
67
67
/// - Parameters:
68
- /// - nsVIew : The view being dismantled.
68
+ /// - nsView : The view being dismantled.
69
69
/// - coordinator: The coordinator.
70
70
static func dismantleNSView( _ nsView: NSViewType , coordinator: Coordinator )
71
71
}
@@ -76,32 +76,43 @@ extension NSViewRepresentable {
76
76
}
77
77
78
78
public func determineViewSize(
79
- for proposal: SIMD2 < Int > , nsView: NSViewType ,
79
+ for proposal: SIMD2 < Int > ,
80
+ nsView: NSViewType ,
80
81
context _: NSViewRepresentableContext < Coordinator >
81
82
) -> ViewSize {
82
83
let intrinsicSize = nsView. intrinsicContentSize
83
84
let sizeThatFits = nsView. fittingSize
84
85
85
86
let roundedSizeThatFits = SIMD2 (
86
87
Int ( sizeThatFits. width. rounded ( . up) ) ,
87
- Int ( sizeThatFits. height. rounded ( . up) ) )
88
+ Int ( sizeThatFits. height. rounded ( . up) )
89
+ )
88
90
let roundedIntrinsicSize = SIMD2 (
89
91
Int ( intrinsicSize. width. rounded ( . awayFromZero) ) ,
90
- Int ( intrinsicSize. height. rounded ( . awayFromZero) ) )
92
+ Int ( intrinsicSize. height. rounded ( . awayFromZero) )
93
+ )
91
94
92
95
return ViewSize (
93
96
size: SIMD2 (
94
- intrinsicSize. width < 0.0 ? proposal. x : roundedSizeThatFits. x,
95
- intrinsicSize. height < 0.0 ? proposal. y : roundedSizeThatFits. y
97
+ intrinsicSize. width < 0.0
98
+ ? proposal. x
99
+ : max ( min ( proposal. x, roundedSizeThatFits. x) , roundedIntrinsicSize. x) ,
100
+ intrinsicSize. height < 0.0
101
+ ? proposal. y
102
+ : max ( min ( proposal. y, roundedSizeThatFits. y) , roundedIntrinsicSize. y)
96
103
) ,
97
104
// The 10 here is a somewhat arbitrary constant value so that it's always the same.
98
105
// See also `Color` and `Picker`, which use the same constant.
99
106
idealSize: SIMD2 (
100
107
intrinsicSize. width < 0.0 ? 10 : roundedIntrinsicSize. x,
101
108
intrinsicSize. height < 0.0 ? 10 : roundedIntrinsicSize. y
102
109
) ,
110
+ // We don't have a nice way of measuring these, so just set them to the
111
+ // view's minimum sizes along each dimension to at least be correct.
112
+ idealWidthForProposedHeight: max ( 0 , roundedSizeThatFits. x) ,
113
+ idealHeightForProposedWidth: max ( 0 , roundedSizeThatFits. y) ,
103
114
minimumWidth: max ( 0 , roundedIntrinsicSize. x) ,
104
- minimumHeight: max ( 0 , roundedIntrinsicSize. x ) ,
115
+ minimumHeight: max ( 0 , roundedIntrinsicSize. y ) ,
105
116
maximumWidth: nil ,
106
117
maximumHeight: nil
107
118
)
@@ -154,6 +165,9 @@ extension View where Self: NSViewRepresentable {
154
165
let representingWidget = widget as! RepresentingWidget < Self >
155
166
representingWidget. update ( with: environment)
156
167
168
+ // We need to do this for `fittingSize` to work correctly (it takes all
169
+ // constraints into account).
170
+ backend. setSize ( of: representingWidget, to: proposedSize)
157
171
let size = representingWidget. representable. determineViewSize (
158
172
for: proposedSize,
159
173
nsView: representingWidget. subview,
@@ -209,14 +223,17 @@ final class RepresentingWidget<Representable: NSViewRepresentable>: NSView {
209
223
} ( )
210
224
211
225
func update( with environment: EnvironmentValues ) {
212
- if context == nil {
213
- context = . init(
226
+ if var context {
227
+ context. environment = environment
228
+ representable. updateNSView ( subview, context: context)
229
+ self . context = context
230
+ } else {
231
+ let context = NSViewRepresentableContext (
214
232
coordinator: representable. makeCoordinator ( ) ,
215
233
environment: environment
216
234
)
217
- } else {
218
- context!. environment = environment
219
- representable. updateNSView ( subview, context: context!)
235
+ self . context = context
236
+ representable. updateNSView ( subview, context: context)
220
237
}
221
238
}
222
239
0 commit comments