diff --git a/MVMCoreUI/Atoms/Views/Label.swift b/MVMCoreUI/Atoms/Views/Label.swift index 10b9220e..b1e8c4ed 100644 --- a/MVMCoreUI/Atoms/Views/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label.swift @@ -26,6 +26,8 @@ public typealias ActionBlock = () -> Void public var sizeObject: MFSizeObject? public var scaleSize: NSNumber? + fileprivate var hasAttachmentImage = false + // Used for scaling the font in updateView. private var originalAttributedString: NSAttributedString? @@ -223,6 +225,21 @@ public typealias ActionBlock = () -> Void attributedString.removeAttribute(.foregroundColor, range: range) attributedString.addAttribute(.foregroundColor, value: UIColor.mfGet(forHex: colorHex), range: range) } + case "externalLink": + let fontSize = (attribute["size"] as? CGFloat ?? label.font.pointSize) * 0.8 + + let imageAttachment = NSTextAttachment() + imageAttachment.image = MVMCoreUIUtility.imageNamed("externalLink") + imageAttachment.bounds = CGRect(x: 0, y: 0, width: fontSize, height: fontSize) + + let mutableAttributedString = NSMutableAttributedString() + mutableAttributedString.append(NSAttributedString(string: " ")) + mutableAttributedString.append(NSAttributedString(attachment: imageAttachment)) + + attributedString.insert(mutableAttributedString, at: location) + + (label as? Label)?.hasAttachmentImage = true + case "font": if let fontStyle = attribute.optionalStringForKey("style") { let styles = MFStyler.styleGetAttributedString("0", withStyle: fontStyle) @@ -342,13 +359,12 @@ public typealias ActionBlock = () -> Void } } - ///Appends an external link image to the end of the attributed string. public func addExternalLinkIcon() { let size = round(font.pointSize * 0.8) - guard let attributedText = self.attributedText else { return } + guard let attributedText = attributedText else { return } let fullString = NSMutableAttributedString(attributedString: attributedText) @@ -359,6 +375,8 @@ public typealias ActionBlock = () -> Void fullString.append(NSAttributedString(string: " ")) fullString.append(NSAttributedString(attachment: imageAttachment)) self.attributedText = fullString + + hasAttachmentImage = true } } @@ -369,6 +387,7 @@ extension Label { text = nil attributedText = nil originalAttributedString = nil + hasAttachmentImage = false styleB2(true) } @@ -489,11 +508,25 @@ extension UITapGestureRecognizer { return true } - guard let attributedText = label.attributedText else { return false } + guard let attributedText = label.attributedText, let font = label.font else { return false } + + var fontToAnalyze: UIFont? = font + + // Necessary where label text is not consistent in font. + for attr in attributedText.attributes(at: targetRange.location, effectiveRange: nil) { + if attr.key == NSAttributedString.Key.font { + fontToAnalyze = attr.value as? UIFont + } + } + + let range = label.hasAttachmentImage ? NSRange(location: 0, length: attributedText.length) : targetRange + + let mutableAttribString = NSMutableAttributedString(attributedString: attributedText) + mutableAttribString.addAttributes([NSAttributedString.Key.font: fontToAnalyze as Any], range: range) let layoutManager = NSLayoutManager() let textContainer = NSTextContainer(size: .zero) - let textStorage = NSTextStorage(attributedString: attributedText) + let textStorage = NSTextStorage(attributedString: mutableAttribString) layoutManager.addTextContainer(textContainer) textStorage.addLayoutManager(layoutManager) @@ -503,8 +536,8 @@ extension UITapGestureRecognizer { textContainer.maximumNumberOfLines = label.numberOfLines textContainer.size = label.bounds.size - let indexOfCharacter = layoutManager.characterIndex(for: location(in: label), in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil) - - return NSLocationInRange(indexOfCharacter, targetRange) + let indexOfGlyph = layoutManager.glyphIndex(for: location(in: label), in: textContainer) + + return NSLocationInRange(indexOfGlyph, targetRange) } }