Reputation:
I'm using SwiftUI, with a custom view for displaying HTML text in a Text :
struct HTMLText: UIViewRepresentable {
private let html: String
private let label = UILabel()
init(html: String, font: String? = nil, size: CGFloat? = nil) {
self.html = html
}
func makeUIView(context: UIViewRepresentableContext<Self>) -> UILabel {
DispatchQueue.main.async {
let data = Data(html.utf8)
if let attributedString = try? NSAttributedString(
data: data,
options: [.documentType: NSAttributedString.DocumentType.html],
documentAttributes:nil) {
label.attributedText = attributedString
}
}
return label
}
func updateUIView(_ uiView: UILabel, context: Context) {}
}
In my main view, I'm using it that way :
struct ConsonantListItem: View {
let consonant: Consonant
var color : String = "#\(UIColor(named: "DefaultText")?.getHexString() ?? "")"
var body: some View {
VStack {
HTMLText(html: "<div style=\"text-align:center\"><span style=\"font-size:20px;font-family:'Helvetica Neue';color:\(self.color)\">\(consonant.consonantRtgs)</span></div>")
.frame(height: 20)
// ...
}
}
}
If I'm running my application, this is working pretty well, and the color is the right one, wether I'm in light or dark mode (DefaultText is a color from assets which is black in light mode, and white in dark mode). But when I'm switching mode in the settings, then the color of this component is not updated. I tried to put the color with @State before, but nothing changed.
All the other colors are updated, but the only solution for this component is to kill and restart the app to make it the right color.
Am I missing something?
Upvotes: 2
Views: 961
Reputation: 2818
Consider managing the color not inside html but by means of Swift. Also you might have to add the same code in updateUIView to trigger the changes. See the modified code:
struct HTMLText: UIViewRepresentable {
private let html: String
init(html: String, font: String? = nil, size: CGFloat? = nil) {
self.html = html
}
func makeUIView(context: UIViewRepresentableContext<Self>) -> UILabel {
let label = UILabel()
setLabelText(label: label)
return label
}
func updateUIView(_ uiView: UILabel, context: Context) {
setLabelText(label: uiView)
}
private func setLabelText(label: UILabel) {
DispatchQueue.main.async {
let data = Data(html.utf8)
if let attributedString = try? NSAttributedString(
data: data,
options: [.documentType: NSAttributedString.DocumentType.html],
documentAttributes:nil) {
label.attributedText = attributedString
label.backgroundColor = UIColor.systemBackground
label.textColor = UIColor.label
}
}
}
}
Instead of UIColor.systemBackground
and UIColor.label
you can use custom colors for light/dark modes like this - colorScheme == .dark ? Color.black : Color.white
. For that you will also need to declare colorScheme
in your struct this way - @Environment(\.colorScheme) var colorScheme
Upvotes: 0