iOS Development

ios – Multiline Textual content Situation with NSAttributedString containing NSTextAttachment

Spread the love


I am making an attempt so as to add a rounded background with padding to attributed textual content. Whereas I’ve efficiently applied the rounded background with padding, I am dealing with challenges in aligning the attachment exactly with the textual content.

closing class TextUViewController: UIViewController {
    non-public lazy var label: UILabel = {
        let label = UILabel()
        label.numberOfLines = 2
        label.backgroundColor = .pink.withAlphaComponent(0.3)
        return label
    }()

    override func viewDidLoad() {
        tremendous.viewDidLoad()
        view.backgroundColor = .black
        view.addSubview(label)
        label.translatesAutoresizingMaskIntoConstraints = false
        label.leadingAnchor.constraint(equalTo: view.leadingAnchor, fixed: 15).isActive = true
        label.trailingAnchor.constraint(equalTo: view.trailingAnchor, fixed: -15).isActive = true
        label.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        label.attributedText = createAttributedText()
    }

    func createAttributedText() -> NSAttributedString {
        let textual content = "It has roots in a chunk of classical Latin literature from 45 BC, making it over 2000 years outdated."
        let token = "2000"
        let attributedString = NSMutableAttributedString(string: textual content)
        let baseAttributes: [NSAttributedString.Key: Any] = [
            .foregroundColor: UIColor.green,
            .font: UIFont.systemFont(ofSize: 14, weight: .medium),
            .baselineOffset: 0,
        ]
        let baseRange = NSRange(location: 0, size: attributedString.size)
        attributedString.addAttributes(baseAttributes, vary: baseRange)

        if let vary = textual content.vary(of: token) {
            let nsRange = NSRange(vary, in: textual content)
            let attachment = createAttachment()
            let attachmentString = NSAttributedString(attachment: attachment)
            attributedString.replaceCharacters(in: nsRange, with: attachmentString)
        }

        return attributedString
    }

    func createAttachment() -> NSTextAttachment {
        let label = UILabel()
        label.textual content = "2000"
        label.textColor = .blue
        label.backgroundColor = .white
        label.font = UIFont.systemFont(ofSize: 14, weight: .daring)
        label.layer.cornerRadius = 2
        label.layer.masksToBounds = true
        label.textAlignment = .middle
        label.sizeToFit()

        let width = label.bounds.width + 12
        let peak = label.bounds.peak + 6
        label.bounds = .init(
            x: 0,
            y: 0,
            width: width,
            peak: peak
        )

        let renderer = UIGraphicsImageRenderer(dimension: label.bounds.dimension)
        let picture = renderer.picture { context in
            label.layer.render(in: context.cgContext)
        }

        let attachment = NSTextAttachment()
        attachment.picture = picture

        return attachment
    }
}

Do you will have any options to unravel this drawback, or do you will have another resolution for including a rounded background to attributed textual content?

I’ve tried utilizing baselineOffset to repair the alignment challenge, however then the textual content would not behave appropriately in multiline situations.

with baselineOffset: 0 multi line

with baselineOffset: 0 multi line

with baselineOffset: 6 multi line

with baselineOffset: 6 multi line

with baselineOffset: 6 single line (That is what I wish to obtain in each single and multiline texts.)

with baselineOffset: 6 single line

Leave a Reply

Your email address will not be published. Required fields are marked *