UITextView添加图片后滚动卡顿

3

我有一个UITextView,我使用ImagePickerController向其中添加图片。

如果只有文本,它会很流畅,但是在添加3或4张图片后,在其内容中滚动时会变得卡顿。

我在添加图像时对其进行了压缩,压缩到最低质量,但是仍然存在卡顿问题。

以下是代码:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

    guard let _image = info[UIImagePickerControllerOriginalImage] as? UIImage else { return }

    self.dismiss(animated: true, completion: nil)

    // Compress the retrieved image
    let compressedImage = UIImage(data: _image.lowestQualityJPEGNSData!)

    //create and NSTextAttachment and add your image to it.
    let attachment = NSTextAttachment()
    let oldWidth = compressedImage?.size.width // scales it within the UITextView
    let scaleFactor = oldWidth! / (bodyEditText.frame.size.width - 10); // adjusts the desired padding
    attachment.image = UIImage(cgImage: (compressedImage?.cgImage!)!, scale: scaleFactor, orientation: .up)

    //put your NSTextAttachment into and attributedString
    let attString = NSAttributedString(attachment: attachment)

    //add this attributed string to the current position.
    bodyEditText.textStorage.insert(attString, at: bodyEditText.selectedRange.location)
}

extension UIImage {
    var uncompressedPNGData: Data?      { return UIImagePNGRepresentation(self)        }
    var highestQualityJPEGNSData: Data? { return UIImageJPEGRepresentation(self, 1.0)  }
    var highQualityJPEGNSData: Data?    { return UIImageJPEGRepresentation(self, 0.75) }
    var mediumQualityJPEGNSData: Data?  { return UIImageJPEGRepresentation(self, 0.5)  }
    var lowQualityJPEGNSData: Data?     { return UIImageJPEGRepresentation(self, 0.25) }
    var lowestQualityJPEGNSData:Data?   { return UIImageJPEGRepresentation(self, 0.0)  }
}

这个问题的原因是什么?你有什么技巧可以解决这个问题吗?
谢谢帮忙。
编辑:
感谢 Duncan C,我成功地消除了整个延迟,并大大提高了渲染图像的性能。
通过替换我的 imagePickerController 为以下内容来实现:
    let size = __CGSizeApplyAffineTransform(_image.size, CGAffineTransform.init(scaleX: 0.3, y: 0.3))
    let hasAlpha = false
    let scale: CGFloat = 0.0 // Automatically use scale factor of main screen

    UIGraphicsBeginImageContextWithOptions(size, !hasAlpha, scale)
    _image.draw(in: CGRect(origin: CGPoint.zero, size: size))

    let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    let att = NSTextAttachment()
    att.image = scaledImage

    //put your NSTextAttachment into and attributedString
    let attString = NSAttributedString(attachment: att)

    //add this attributed string to the current position.
    bodyEditText.textStorage.insert(attString, at: bodyEditText.selectedRange.location)
2个回答

2
您误用了比例因子。它是用于处理普通,视网膜和@3x视网膜图像的1x、2x和3x缩放的。

您这样做的方式,系统每次想要绘制其中一个图像时都必须将全尺寸图像渲染到您的边界矩形中。如果图像比您显示它们的大小大得多,您会浪费大量内存和处理时间。

首先尝试简单地设置您的图像视图的contentMode.scaleAspectFit,并在不搞乱比例因子的情况下安装原始图像到图像视图中。看看性能如何。

如果这不能给出可接受的性能,您应该将起始图像呈现到目标大小的离屏图形上下文中,并将重新呈现的图像安装到您的图像视图中。您可以使用UIGraphicsBeginImageContextWithOptions()或其他各种技术来调整大小以供显示。

请参阅此链接以获取有关图像缩放和调整大小的信息:

http://nshipster.com/image-resizing/


有一件事,我没有将检索到的图像设置为imageView,而是将其作为附件添加到NSAttributedString中;我该如何使其aspectFit? - Ivan Cantarino
谢谢你的回答,我相信通过你的解释我会解决我的问题。 - Ivan Cantarino
哦,我没有看到那部分。你有代码 attachment.image = ... 在缩放图像后将其分配给 attachment.image。 - Duncan C

1

这样做并不是最佳实践。UITextView 仅适用于文本,而非所有视图。

你需要创建一个自定义 UIView,其中包含 1 个 UITextView 和 2 个 UICollectionView,以容纳多张图片。

这样,你就可以在项目中多个位置重复使用此自定义视图。


如果您将此答案标记为有用,我将不胜感激 :) - Chetan A

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接