Skip to content

[Img] When I add an image, the onClick doesn't work #121

@jordizspmobile

Description

@jordizspmobile

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
    }
}

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions