1

我正在尝试在包含几个自动调整大小的 NSViewRepresentables 的 ScrollView 中显示项目。但是,似乎项目在滚动后或当其父 ScrollView 的大小发生更改时相互重叠:

在此处输入图像描述

如果我从这里的其他重要回复中正确理解(例如@Asperi 的答案在这里),则 ScrollView 需要知道其项目的高度才能正确呈现它。因此,我尝试将每个项目的总高度传递给其父 ScrollView,但是,这些项目仍然重叠。

我做了一个简单的例子:

struct dataItem: Identifiable {
    let id = UUID()
    let question: String
    let answer: String
}

let exampleData: [dataItem] = [dataItem(question: "Lorem Ipsum is simply....", answer: "Lorem Ips ange...ker including versions of Lorem Ipsum.") ,
                        dataItem(question:"The standard ..ranslation by H. Rackham.", answer:"The standard c.... Rackham."),
                        dataItem(question:"The standard ch...Rackham.", answer:"The stand...kham."),
                        dataItem(question:"The stand..Rackham.", answer:"The standa...kham."),
                        dataItem(question:"The stand...ackham.", answer:"The standard ...ham."),
                        dataItem(question:"The standa..H. Rackham.", answer:"The standard c...ackham."),
                        dataItem(question:"The st... H. Rackham.", answer:"The standard ch...m.")
]

struct ContentView: View {
    @State var totalHeight: CGFloat = 80
    
    var body: some View {
        ScrollView{
            ScrollViewReader{ scrollView in
                LazyVStack {
                    ForEach(exampleData, id: \.id) { item  in
                        RowView(item: item, totalHeight: $totalHeight)
// The following line makes the ScrollView jitter
//                            .frame(height: totalHeight)
                    }
                }
            }
        }
        .id(UUID().uuidString)
    }
}

struct RowView: View {
    let item: dataItem
    @Binding var totalHeight: CGFloat
    @State var optimalHeightQuestionValue: CGFloat = .zero
    @State var optimalHeightAnswerValue: CGFloat = .zero
    
    var body: some View{
        
        let optimalHeightQuestion = Binding<CGFloat>(
            get: {self.optimalHeightQuestionValue}, set: {
                self.optimalHeightQuestionValue = $0
                totalHeight = optimalHeightQuestionValue + optimalHeightAnswerValue
            })
        let optimalHeightAnswer = Binding<CGFloat>(
            get: {self.optimalHeightAnswerValue}, set: {
                self.optimalHeightAnswerValue = $0
                totalHeight = optimalHeightQuestionValue + optimalHeightAnswerValue
            })
        
        VStack{
            TextViewExt(attributedText: NSAttributedString(string: item.question), optimalHeight: optimalHeightQuestion)
                .frame(height: optimalHeightQuestionValue)
            TextViewExt(attributedText: NSAttributedString(string: item.answer), optimalHeight: optimalHeightAnswer)
                .frame(height: optimalHeightAnswerValue)
        }
    }
}


struct TextViewExt: NSViewRepresentable {
    typealias NSViewType = NSTextView
    
    var attributedText: NSAttributedString
    @Binding var optimalHeight: CGFloat
    
    func makeNSView(context: Context) -> NSTextView {
        let textView = NSTextView()
        textView.backgroundColor = .clear
        return textView
    }
    
    func updateNSView(_ nsView: NSTextView, context: Context) {
        DispatchQueue.main.async {
            nsView.textStorage?.setAttributedString(attributedText)
            nsView.translatesAutoresizingMaskIntoConstraints = true
            nsView.sizeToFit()
            self.optimalHeight = nsView.frame.height
        }
    }
    
}

有人知道为什么会这样吗?或者 NSTextView 的自动调整大小有什么问题?非常感谢您的任何建议。

4

0 回答 0