如何使用nsattributedstring在Swift中将图像添加为文本附件

时间:2015-09-24 22:31:54

标签: ios iphone swift ios-app-extension custom-keyboard

我正在尝试使用我作为按钮添加的图像为iOS构建自定义键盘。当我按下按钮时,链接到该按钮的图像被放入一个属性字符串,该字符串被加载到自定义键盘视图内的UiTextView中。那很有效。

问题在于,当我将新图像附加到属性字符串时,字符串中的旧图像和新图像都将更改为我当前按下的图像。我无法理解为什么字符串中的旧图像会发生变化。

有什么建议吗?我尝试过使用replaceCharactersInRange和insertAttributedString,却无法使用它。这是代码(在viewDidLoad之后):

let textAttachment = NSTextAttachment()

let textView = UITextView(frame: CGRectMake(5, 5, 200, 40))
var attributedString = NSMutableAttributedString(string: "")

@IBAction func buttonPressed(button :UIButton) {

    let string = button.titleLabel?.text

    textAttachment.image = UIImage(named: "\(string!).png")!
    textAttachment.image = UIImage(CGImage: textAttachment.image!.CGImage!, scale: 6, orientation: .Up)
    let attrStringWithImage = NSAttributedString(attachment: textAttachment)
    attributedString.appendAttributedString(attrStringWithImage);


    textView.attributedText = attributedString;
  }

谢谢!

4 个答案:

答案 0 :(得分:3)

  

我们不能简单地附加NSTextAttachment图片。我们必须存储   所有附加的图像和连接到现有的归属   字符串。

func buttonPressed(_ sender: Any) {

    let  button = sender as! UIButton
    let tag =  button.tag
    let attributedString:NSAttributedString!

    switch tag {
    case 2:
        attributedString = addAttributedText(text: (button.titleLabel?.text)!)
    case 3:
        attributedString = addAttributedText(text: (button.titleLabel?.text)!)
    case 4:
        attributedString = addAttributedText(text: (button.titleLabel?.text)!)
    default:
       attributedString = addAttributedText(text: "launch")
      }
        textView.attributedText = attributedString
    }

    func addAttributedText(text:String) -> NSAttributedString {
        textViewDidChange(textView)
        let axtractedImageAttribute = NSMutableAttributedString()
        for image in imageArray {
            let attachment:NSTextAttachment = NSTextAttachment()
            attachment.image = image
            attachment.setImageHeight(height: 20)
            let attachmentString:NSAttributedString = NSAttributedString(attachment: attachment)
            axtractedImageAttribute.append(attachmentString)
        }

        let attachment:NSTextAttachment = NSTextAttachment()
        attachment.image = UIImage(named: "\(text).png")
        attachment.setImageHeight(height: 20)
        let attachmentString:NSAttributedString = NSAttributedString(attachment: attachment)
        let attributedString:NSMutableAttributedString = NSMutableAttributedString(string:textView.text!)
        attributedString.append(axtractedImageAttribute)
        attributedString.append(attachmentString)
        return attributedString
    }

    //MARKS:-  Extract attachedImage
    func textViewDidChange(_ textView: UITextView)  {
        imageArray = [UIImage]()
        let range = NSRange(location: 0, length: textView.attributedText.length)
        if (textView.textStorage.containsAttachments(in: range)) {
            let attrString = textView.attributedText
            var location = 0
            while location < range.length {
                var r = NSRange()
                let attrDictionary = attrString?.attributes(at: location, effectiveRange: &r)
                if attrDictionary != nil {
                    let attachment = attrDictionary![NSAttachmentAttributeName] as? NSTextAttachment
                    if attachment != nil {
                        if attachment!.image != nil {
                            imageArray.append( attachment!.image!)
                        }
                    }
                    location += r.length
                }
            }
        }
    }

}

enter image description here enter image description here

Demo Reference

答案 1 :(得分:0)

我发现了问题,我需要为NSTextAttachment设置不同的变量(即textAttachment1,textAttachment2等),否则它只使用第一个被寻址的图像。

答案 2 :(得分:0)

这对我有用:

let attributedStringTextAttachment = NSTextAttachment()
attributedStringTextAttachment.image = UIImage(named: "image")

答案 3 :(得分:0)

这是我的扩展名 Swift 4 ,用于将图片更改为具有大小和色调颜色变化的属性字符串

public extension UIImage {

    func tint(with color: UIColor) -> UIImage {
        var image = withRenderingMode(.alwaysTemplate)
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        color.set()

        image.draw(in: CGRect(origin: .zero, size: size))
        image = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }

    func toAttributedString(with heightRatio: CGFloat, tint color: UIColor? = nil) -> NSAttributedString {
        let attachment = NSTextAttachment()
        var image = self

        if let tintColor = color {
            image.withRenderingMode(.alwaysTemplate)
            image = image.tint(with: tintColor)
        }

        attachment.image = image

        let ratio: CGFloat = image.size.width / image.size.height
        let attachmentBounds = attachment.bounds

        attachment.bounds = CGRect(x: attachmentBounds.origin.x,
                                   y: attachmentBounds.origin.y,
                                   width: ratio * heightRatio,
                                   height: heightRatio)

        return NSAttributedString(attachment: attachment)
    }
}