Skip to content

Commit 98aa08b

Browse files
committed
Change the way height of custom scroll view is computed
1 parent 02cacbd commit 98aa08b

1 file changed

Lines changed: 28 additions & 37 deletions

File tree

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,46 @@
11
import AppKit
2-
import SwiftUI
32
import Combine
3+
import SwiftUI
4+
5+
struct CustomScrollViewHeightPreferenceKey: PreferenceKey {
6+
static var defaultValue: Double = 0
7+
static func reduce(value: inout Double, nextValue: () -> Double) {
8+
value = nextValue() + value
9+
}
10+
}
11+
12+
struct CustomScrollViewUpdateHeightModifier: ViewModifier {
13+
func body(content: Content) -> some View {
14+
content
15+
.background {
16+
GeometryReader { proxy in
17+
Color.clear
18+
.preference(
19+
key: CustomScrollViewHeightPreferenceKey.self,
20+
value: proxy.size.height
21+
)
22+
}
23+
}
24+
}
25+
}
426

527
/// Used to workaround a SwiftUI bug. https://github.com/intitni/CopilotForXcode/issues/122
628
struct CustomScrollView<Content: View>: View {
729
@ViewBuilder var content: () -> Content
8-
@State var height: Double = 100
30+
@State var height: Double = 10
931
@AppStorage(\.useCustomScrollViewWorkaround) var useNSScrollViewWrapper
1032

1133
var body: some View {
1234
if useNSScrollViewWrapper {
1335
List {
1436
content()
1537
.listRowInsets(EdgeInsets(top: 0, leading: -8, bottom: 0, trailing: -8))
38+
.modifier(CustomScrollViewUpdateHeightModifier())
1639
}
1740
.listStyle(.plain)
18-
.frame(idealHeight: height)
19-
.background {
20-
ComputeHeight(height: $height) {
21-
content()
22-
}
23-
.frame(maxWidth: .infinity)
24-
.opacity(0)
41+
.frame(idealHeight: max(10, height))
42+
.onPreferenceChange(CustomScrollViewHeightPreferenceKey.self) { newHeight in
43+
height = newHeight
2544
}
2645
} else {
2746
ScrollView {
@@ -30,31 +49,3 @@ struct CustomScrollView<Content: View>: View {
3049
}
3150
}
3251
}
33-
34-
private struct ComputeHeight<Content: View>: NSViewRepresentable {
35-
@Binding var height: Double
36-
@ViewBuilder var content: () -> Content
37-
38-
func makeNSView(context: Context) -> NSView {
39-
let view = NSView()
40-
return view
41-
}
42-
43-
func updateNSView(_ nsView: NSView, context: Context) {
44-
updateHeight(nsView)
45-
}
46-
47-
func updateHeight(_ nsView: NSView) {
48-
let contentView = content()
49-
let hostingView = NSHostingView(
50-
rootView: contentView.frame(width: nsView.frame.width == 0 ? 200 : nsView.frame.width)
51-
)
52-
let size = hostingView.fittingSize
53-
54-
if height != size.height {
55-
Task { @MainActor in
56-
height = size.height
57-
}
58-
}
59-
}
60-
}

0 commit comments

Comments
 (0)