识别标签中显示的属性字符串中的图像点击

问题描述 投票:0回答:2

我有一个属性字符串,如下所示,要显示在标签中。

let someText = NSMutableAttributedString(string: "This is a sample text with")
let imageAttachment = NSTextAttachment()
imageAttachment.image = UIImage(named: "icon") 

let imageString = NSAttributedString(attachment: imageAttachment)
someText.append(imageString)
someText.append(NSAttributedString(string: "attached")
somelabel.attributedText = someText

标签显示

This is a sample text with 'image' attached

如何识别点击图像(而不是文本)来执行操作?

ios swift xcode uilabel nsmutableattributedstring
2个回答
4
投票
  • 创建一个新的 NSAttributedStringKey,用于识别图像附件。
  • 然后使用图像创建一个 NSTextAttachment,将其包装在 NSMutableAttributedString 中并向其添加自定义属性。
  • 最后将包装器添加到完整的 NSAttributedString 并附加 UITapGestureRecognizer。

  • 然后在 UITapGestureRecognizer 上的选择器中只需查找该自定义标签即可。

大多数位的代码:

extension NSAttributedStringKey {
static let imagePath = NSAttributedStringKey(rawValue: "imagePath")
}

何时设置文本显示

let fullString = NSMutableAttributedString()    
let imageAttachment = NSTextAttachment()
imageAttachment.image = image

let imageAttributedString: NSMutableAttributedString = NSAttributedString(attachment: imageAttachment).mutableCopy() as! NSMutableAttributedString

let customAttribute = [ NSAttributedStringKey.imagePath: imagePath ]
imageAttributedString.addAttributes(customAttribute, range: NSRange(location: 0, length: imageAttributedString.length))

fullString.append(imageAttributedString)

然后在点击动作调用的函数中:

    @objc func onImageTap(_ sender: UITapGestureRecognizer) {
      let textView = sender.view as! UITextView
      let layoutManager = textView.layoutManager

      // location of tap in textView coordinates
      var location = sender.location(in: textView)
      location.x -= textView.textContainerInset.left;
      location.y -= textView.textContainerInset.top;

      // character index at tap location
      let characterIndex = layoutManager.characterIndex(for: location, in: textView.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)

      // if index is valid 
      if characterIndex < textView.textStorage.length {

        // check if the tap location has the custom attribute
        let attributeValue = textView.attributedText.attribute(NSAttributedStringKey.imagePath, at: characterIndex, effectiveRange: nil) as? String
        if let value = attributeValue {
            print("You tapped on \(NSAttributedStringKey.imagePath) and the value is: \(value)")
        }

    }

}

从那里您知道点击是在图像中,并且您有图像框架内的坐标,因此您可以使用该组合来确定点击了图像中的位置。


0
投票

您可以使用以下代码在 UILabel 内的属性字符串中实现图像点击功能。

第1步: 以下函数用于将字符串转换为属性字符串,应用各种属性,例如颜色更改、字体调整和添加图像。它返回结果属性字符串。

func createAttributedStringWithImage(message: String, subText1: String) -> NSAttributedString {

    let mainAttributes: [NSAttributedString.Key: Any] = [
        .foregroundColor: Constants.primaryTextColor ?? UIColor.black,   // Change color as needed
        .font: UIFont(name: "Poppins-Regular", size: 14.0) ?? UIFont.boldSystemFont(ofSize: 14)  // Change font as needed
    ]

    let subTextAttributes: [NSAttributedString.Key: Any] = [
        .foregroundColor: Constants.primaryTextColor ?? UIColor.black,    // Change color as needed
        .font: UIFont(name: "Poppins-Bold", size: 14.0) ?? UIFont.boldSystemFont(ofSize: 14)  // Change font as needed
    ]

    let attributedString = NSMutableAttributedString(string: message, attributes: mainAttributes)
    let spaceString = NSMutableAttributedString(string: " ", attributes: mainAttributes)
    
    attributedString.append(NSAttributedString(string: subText1))

    var combinedText = message + subText1 + " "
    
    if let range = combinedText.range(of: subText1) {
        let nsRange = NSRange(range, in: combinedText)
        attributedString.addAttributes(subTextAttributes, range: nsRange)
    }
    
    // Add an image attachment after subText1
    let imageAttachment = NSTextAttachment()
    imageAttachment.image = UIImage(named: "ic_edit") // Replace with the name of your image
    
    let imageAttributedString = NSAttributedString(attachment: imageAttachment)
    // Line to add space before image
    attributedString.append(spaceString)
    
    attributedString.append(imageAttributedString)
    
    return attributedString
}

第2步: 现在,我们需要将属性字符串分配给 UILabel 并向 UILabel 添加点击手势识别器。使用以下代码来实现此目的:

 let message = "We have sent the code verification to your email "
 let resultAttributedString = createAttributedStringWithImage(message: message, subText1: email)
 self.messageLabel?.attributedText = resultAttributedString
 self.messageLabel?.isUserInteractionEnabled = true
        
 let tapGesture = UITapGestureRecognizer.init(target: self, action: #selector(imageTapped(gesture:)))
 self.messageLabel?.addGestureRecognizer(tapGesture)

第3步: 当用户在添加点击手势后点击 UILabel 时,将调用以下函数。下面是 imageTapped 函数的实现,我们在其中编写代码来确定用户是否点击了图像或文本。

 @objc private func imageTapped(gesture: UITapGestureRecognizer) {
    guard let label = gesture.view as? UILabel else {
        return
    }
    
    guard let attributedText = label.attributedText else {
        return // nothing to do
    }
    
    let location = gesture.location(in: label)
    let textStorage = NSTextStorage(attributedString: attributedText)
    let textContainer = NSTextContainer(size: label.bounds.size)
    let layoutManager = NSLayoutManager()
    layoutManager.addTextContainer(textContainer)
    textStorage.addLayoutManager(layoutManager)
    
    textContainer.lineFragmentPadding = 0.0
    textContainer.lineBreakMode = label.lineBreakMode
    textContainer.maximumNumberOfLines = label.numberOfLines
    
    let characterIndex = layoutManager.characterIndex(for: location,in:textContainer,fractionOfDistanceBetweenInsertionPoints: nil)
    
    if characterIndex < textStorage.length {
       
        guard NSTextAttachment.character == (textStorage.string as NSString).character(at: characterIndex) else {
            return
        }
        guard let attachment = textStorage.attribute(.attachment, at: characterIndex, effectiveRange: nil) as? NSTextAttachment else {
            return
        }
        
        if (attachment.image != nil){
            // You have clicked on image and write your code here you want to achieve on image tapped.
        }
        
    }
    
}

最终输出:以下是上述步骤的输出,您的标签将如下所示。

© www.soinside.com 2019 - 2024. All rights reserved.