Atributika
Atributika copied to clipboard
[Img] When I add an image, the onClick doesn't work
Hello all!
First at all, I think that library is amazing, but I have an issue with the library, this issue is produced when:
I add an image with <img scr="http://www.example.com/image.jpg" />
all the links with 'a' tags don't work because onClick doesn't call.
Is there any issue or I do something wrong?
My code:
private var bodyTextView = AttributedLabel()
bodyTextView.numberOfLines = 0
bodyTextView.onClick = { label, detection in
switch detection.type {
case .link(let url):
UIApplication.shared.open(url)
break
case .tag(let tag):
if let urlStr = tag.attributes["href"],
let url = URL(string: urlStr) {
UIApplication.shared.open(url)
}
break
default:
break
}
}
let string = "Example text <a href='http://www.example.com/examplelink'>Example link</a><br /><br /><img src='http://www.example.com/image.jpg' />"
let bodyHTML = string.toHtml([
StyleParams.paragraphFont: UIFont.systemFont(ofSize: 15, weight: .regular),
StyleParams.paragraphColor: UIColor.black,
StyleParams.linkFont: UIFont.systemFont(ofSize: 15, weight: .regular),
StyleParams.linkFontColor: UIColor.red,
StyleParams.linkFontHightlightColor: UIColor.red
])
bodyTextView.attributeText = bodyHTML
public enum StyleParams {
//Headers (<h1>..<h5>)
case titleH1Font // h1
case titleH1Color
case titleH1BackgroundColor
case titleH2Font // h2
case titleH2Color
case titleH2BackgroundColor
case titleH3Font // h3
case titleH3Color
case titleH3BackgroundColor
case titleH4Font // h4
case titleH4Color
case titleH4BackgroundColor
case titleH5Font // h5
case titleH5Color
case titleH5BackgroundColor
//Links (<a>)
case linkFont
case linkFontColor
case linkFontHightlightColor
case linkBackgroundColor
//Paragraph (<p>)
case paragraphFont
case paragraphColor
case paragraphBackgroundColor
//Img
case imgPlaceholder
}
extension String {
public func toHTML(params: [StyleParams:Any] = [:]) -> AttributedText {
let listHeaders = ["h1", "h2", "h3", "h4", "h5"]
let style = self.style(tags: [
headerStyle(headers: listHeaders, params: params),
paragraphStyle(params: params),
linkStyle(params: params)
])
return imageStyle(
style: style,
params: params
).styleHashtags(
linkHashtag(params: params)
).styleMentions(
linkStyle(params: params)
).styleLinks(
linkStyle(params: params)
)
//OnClick works well without parse to NSAttributeString/NSMutableAttributedString
/* return style
.styleHashtags(
linkHashtag(params: params)
).styleMentions(
linkStyle(params: params)
).styleLinks(
linkStyle(params: params)
)*/
}
private func imageStyle() -> Style {
return Style("img")
}
private func imageStyle(style: AttributedText, params: [StyleParams: Any] = [:]) -> NSMutableAttributedString {
let mutableAttrStr = NSMutableAttributedString(attributedString: style.attributedString)
var placeHodler = UIImage(named: "forum_empty_avatar")
if let imageNamed = params[.imgPlaceholder] as? String {
placeHodler = UIImage(named: imageNamed)
}
var locationShift = 0
for detection in style.detections {
switch detection.type {
case .tag(let tag):
if let imgSrc = tag.attributes["scr"] {
let imageView = UIImageView()
if let url = URL(string: imgSrc) {
imageView.af.setImage(withURL: url, placeholderImage: placeHodler)
} else {
imageView.image = placeHodler
}
let textAttachment = NSTextAttachment()
textAttachment.image = imageView.image
let imageAttrStr = NSAttributedString(attachment: textAttachment)
let nsrange = NSRange(detection.range, in: mutableAttrStr.string)
mutableAttrStr.insert(imageAttrStr, at: nsrange.location + locationShift)
locationShift += 1
}
break
default:
break
}
}
return mutableAttrStr
}
private func linkHashtag(params: [StyleParams:Any] = [:]) -> Style {
var styleHashtag = Style.font(UIFont.systemFont(ofSize: 15))
if let font = params[.linkFont] as? UIFont {
styleHashtag = styleHashtag.font(font)
}
return styleHashtag
}
private func linkStyle(params: [StyleParams:Any] = [:]) -> Style {
var styleLink = Style("a")
if let font = params[.linkFont] as? UIFont {
styleLink = styleLink.font(font)
}
if let color = params[.linkFontColor] as? UIColor {
styleLink = styleLink.foregroundColor(color, .normal)
} else {
fatalError("You need add font color to <a> tag.")
}
if let color = params[.linkFontHightlightColor] as? UIColor {
styleLink = styleLink.foregroundColor(color, .highlighted)
} else {
fatalError("You need add font hightlight color to <a> tag.")
}
if let backgroundColor = params[.linkBackgroundColor] as? UIColor {
styleLink = styleLink.backgroundColor(backgroundColor)
}
return styleLink
}
private func paragraphStyle(params: [StyleParams:Any]) -> Style {
var styleLink = Style("p")
if let font = params[.paragraphFont] as? UIFont {
styleLink = styleLink.font(font)
}
if let color = params[.paragraphColor] as? UIColor {
styleLink = styleLink.foregroundColor(color)
}
if let backgroundColor = params[.paragraphBackgroundColor] as? UIColor {
styleLink = styleLink.backgroundColor(backgroundColor)
}
return styleLink
}
private func headerStyle(headers: [String], params: [StyleParams:Any]) -> Style {
var styleLink = Style("h1")
for header in headers {
styleLink = Style(header)
switch header {
case "h1": styleLink = headerH1Style(style: styleLink, params: params)
break
case "h2": styleLink = headerH2Style(style: styleLink, params: params)
break
case "h3": styleLink = headerH3Style(style: styleLink, params: params)
break
case "h4": styleLink = headerH4Style(style: styleLink, params: params)
break
case "h5": styleLink = headerH5Style(style: styleLink, params: params)
break
default: styleLink = headerH5Style(style: styleLink, params: params)
break
}
}
return styleLink
}
private func headerH1Style(style: Style, params: [StyleParams:Any]) -> Style {
var style = style
if let font = params[.titleH1Font] as? UIFont {
style = style.font(font)
}
if let color = params[.titleH1Color] as? UIColor {
style = style.foregroundColor(color)
}
if let color = params[.titleH1BackgroundColor] as? UIColor {
style = style.backgroundColor(color)
}
return style
}
}
Looks like connected with this one https://github.com/psharanda/Atributika/issues/130
Check kvlb
@jordizspmobile I just need to show the image and do not need the tap. In that case, your code should download the image and show it but I was wondering does it ever show the image.
Because when the attributed string is built the image is not present, it is being downloaded, and after that textAttachment's image is set. By this time the attributed string is already shown. Setting the image on textAttachment
after that has no effect in my case.
How do we update the textAttachment
after the image is downloaded?