Skip to content

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

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions