'How to use an NSAttributedString with a ScrollView in SwiftUI?
I've been able to render NSAttributedStrings via UIViewRepresentable which works great until I wrap the view in a ScrollView.
When placed inside the ScrollView, the NSAttributedString view stops rendering.
I've tried some other methods that replace an NSAttributedString with adding multiple Text() views together to get formatting which works inside the ScrollView and supports italics and monospace font. Unfortunately this doesn't work for links inside text blocks, which means I still need an NSAttributedString.
import SwiftUI
struct TextWithAttributedString: UIViewRepresentable {
var attributedString: NSAttributedString
init(_ attributedString: NSAttributedString) {
self.attributedString = attributedString
}
func makeUIView(context: Context) -> UITextView {
let textView = UITextView(frame: .zero)
textView.attributedText = self.attributedString
textView.isEditable = false
return textView
}
func updateUIView(_ textView: UITextView, context: Context) {
textView.attributedText = self.attributedString
}
}
let exampleText = """
Fugiat id blanditiis et est culpa voluptas. Vivamus aliquet enim eu blandit blandit. Sit eget praesentium maxime sit molestiae et alias aut.
"""
struct NSAttributedStringView: View {
var body: some View {
// Note: when uncommented, the view breaks
// ScrollView {
TextWithAttributedString(NSAttributedString(string: exampleText))
// }
}
}
struct NSAttributedStringView_Previews: PreviewProvider {
static var previews: some View {
NSAttributedStringView()
.previewLayout(.sizeThatFits)
}
}
Edit: I tried using the wrapped UITextView with the text property set instead of the attributeText property, but this also fails to render in the ScrollView, so the issue seems to be the UITextView, not the NSAttributedString.
So the question is, how do we get the UITextView to work in a ScrollView?
Solution 1:[1]
If you want to use Asperi's TextWithAttributedString as a child view, replace
height = textView.sizeThatFits(UIScreen.main.bounds.size).height
by
DispatchQueue.main.async {
height = textView.sizeThatFits(textView.visibleSize).height
}
Solution 2:[2]
Network problems like this have two common causes:
- A network problem(!)
- A long JVM pause
You don't show in your logs what happened before the errors, but there's a good chance you'll see warnings about a "Long JVM pause," which means that no Ignite code was being executed for a period of time. In this case, it means that messages from other nodes were not being handled. There are a number of causes for long pauses, but the most common is incorrectly configured garbage collectors. See the documentation for some hints.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | VictorN |
| Solution 2 | Stephen Darlington |
