NSViewRepresentables с автоматическим размером в ScrollView перекрывают друг друга (SwiftUI)
Я пытаюсь отобразить элементы в ScrollView, который содержит несколько NSViewRepresentables с автоматическим размером. Однако кажется, что элементы перекрывают друг друга после прокрутки или при изменении размера его родительского 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? Большое спасибо за любой совет.