11import AppKit
2- import SwiftUI
32import 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
628struct 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