Open halilyuce opened 4 years ago
Does it crash with every string you pass to setString? If you have a sample string I can try to see if it crashes for me as well
I solved it with dispatchqueue main async but now it is not calculating true label height size sometimes, I think it is about intrinsicContentSize override is not working at the same time because of dispatch.
Full code, any suggestions ? @gualtierofrigerio
class ViewWithLabel : UIView {
private var label = UILabel()
override init(frame: CGRect) {
super.init(frame:frame)
self.addSubview(label)
label.numberOfLines = 0
label.autoresizingMask = [.flexibleWidth, .flexibleHeight]
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var intrinsicContentSize: CGSize{
self.label.sizeThatFits(CGSize(width: UIScreen.main.bounds.width - 32, height: 9999))
}
func setString(_ html:String) {
DispatchQueue.main.async {
self.label.attributedText = html.convertHtml()
self.label.textColor = UIColor(named: "DarkColor")!
}
}
}
struct TextWithAttributedString: UIViewRepresentable {
var html: String
func makeUIView(context: Context) -> ViewWithLabel {
let view = ViewWithLabel(frame: .zero)
return view
}
func updateUIView(_ uiView: ViewWithLabel, context: Context) {
uiView.setString(html)
}
}
Extension :
extension String {
func convertHtml() -> NSAttributedString {
guard let data = data(using: .unicode, allowLossyConversion: true) else { return NSAttributedString() }
if let attributedString = try? NSMutableAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil) {
return attributedString
} else {
return NSAttributedString()
}
}
}
NewsDetail.swift
import Foundation
import SwiftUI
import SDWebImageSwiftUI
struct NewsDetail: View {
var title:String = ""
var content:String = ""
var image:String = ""
var video:String = ""
var imageShare = UIImageView()
@State private var showShareSheet = false
let screenWidth = UIScreen.main.bounds.width
let formatString = "<span style=\"font-family: '-apple-system', 'HelveticaNeue'; font-size:17\">%@</span>"
init(title:String,content:String,image:String,video:String){
self.content = content
self.title = title
self.image = image
self.video = video
self.imageShare.downloaded(from: image)
}
var body: some View {
ScrollView(.vertical, showsIndicators: true) {
VStack(alignment: .leading, spacing: 20){
Group{
if self.video != ""{
YoutubePlayer(videoID: video).frame(height:210)
}else {
WebImage(url: URL(string:image))
.resizable()
.indicator(.activity)
.animation(.easeInOut(duration: 0.5))
.transition(.fade)
.aspectRatio(contentMode: .fill)
.frame(width:screenWidth, height: 250)
.clipped()
}
}
Text(title).fontWeight(.bold).lineLimit(.none).padding(.horizontal).font(.title)
}
TextWithAttributedString(html: String(format:formatString, content)).padding(.horizontal).frame(width: screenWidth)
Divider()
}
.sheet(isPresented: $showShareSheet) {
ShareSheet(activityItems: [self.imageShare.image!, self.title])
}
.navigationBarTitle(Text(title), displayMode: .inline)
.navigationBarItems(trailing:
Button(action: {
}, label: {
Button(action: {
self.showShareSheet = true
}) {
Image(systemName: "square.and.arrow.up")
}
})
)
}
}
Hey, thanks for this repo. I am using it for render html as NSAttributedString thanks to this but when I open page app is crashing. I researched and they said you must add DispatchQueue.main.async to your code for solve it. Do you have any idea about it ? I added but it is still same.