【问题标题】:UITextView set NSTextAttachment Images cause Performance lag, slow issueUITextView 设置 NSTextAttachment 图像导致性能滞后、缓慢问题
【发布时间】:2021-06-16 03:01:06
【问题描述】:

我想在用户输入时将图像附件添加到 UITextview,这很好,但问题是 CPU 增长与添加的图像附件数量一样多。 90%。并导致 UI 滞后等缓慢。我已将图像调整为小尺寸,但问题仍然存在。 here is image what I'm doing

    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
     
        
        for data in arrDataModel {
                  if data.textDefaul == text {
                      let attachment = NSTextAttachment()
                      if let image = data.imageData {

                          let imageNew = UIImage(data: image)!
                          attachment.image = imageNew
                         let attString = NSAttributedString(attachment: attachment)
                         txtViewShow.textStorage.replaceCharacters(in: range, with: attString)
                      
                      }

                   break

                  }
          }
        
         return true
         
                
      }

【问题讨论】:

  • 每当添加新附件时,它似乎 uitextview 都会重绘所有附件。但我不知道如何避免它

标签: ios swift performance text uitextview


【解决方案1】:

您的所有模型实例似乎都将imageData: Data 保存在内存中。你应该避免这样做。您可以随时从String (resourceName) 创建UIImage 实例。

例如,这是我的Assets.xcassets 中的内容。

注意:额外的空白将在实现中很有用。

那么你可以像下面那样做 -

class ViewController: UIViewController, UITextViewDelegate {

    let alphabets = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", 
                     "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]

    struct AlphabetInfo {
        let alphabet: String
        
        var image: UIImage? {
            UIImage(named: "alphabet_\(alphabet)")
        }
    }

    lazy var alphabetInfos: [AlphabetInfo] = {
        alphabets.map { AlphabetInfo(alphabet: $0) }
    }()

    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        for info in alphabetInfos {
            if info.alphabet == text.uppercased() {
                if let image = info.image {
                    let attachment = NSTextAttachment()
                    attachment.image = image
                    attachment.bounds = CGRect(origin: .zero, size: CGSize(width: 60, height: 60))
                    let attachmentString = NSAttributedString(attachment: attachment)
                    textView.textStorage.replaceCharacters(in: range, with: attachmentString)
                }
                break
            }
        }
        
        var cursorLocation = textView.selectedRange.location
        if text.isEmpty {
            textView.textStorage.replaceCharacters(in: range, with: text)
            cursorLocation -= range.length
        } else {
            cursorLocation += text.count
        }
        textView.selectedRange.location = cursorLocation

        return false
    }
}

输出

【讨论】:

  • 谢谢!但出于某种原因我不得不坚持,但内存并没有增长太多,这是正常的,如果我添加 200 多个附件图像,CPU 会增长到 90%。
  • 我用大约 200 张图像尝试了上面的示例,在 CPU 中没有看到任何类似的峰值。最多是30%左右。我使用了60x60 图像 - 也许您的图像仍然太大。我的资源大小在6KB and 8KB 之间。
  • 图像是 50*50,实际上是 200+,如果我继续输入,它会增长 10%-30%-..90%
  • 添加 570 多张图片后,它会增长到 ~90%
  • 我明白了。我尝试了 1500 多个附件,然后开始查看问题。请参阅imgur.com/lROzlbi 这显然是因为UITextView 有太多附件无法处理。您应该考虑改用UICollectionView 来解决这个问题。每个字符图像将在UICollectionViewCell 内。您的 UICollectionView 将有两个部分 - 第一个部分将使用 AlphabetInfoCollectionViewCell 显示字母信息/图像,第二部分将使用不同的单元格,例如 AlphabetTextInputCollectionViewCell,其中包含一个允许文本输入的 textField。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-03
  • 2011-06-14
  • 1970-01-01
  • 2017-06-23
  • 2016-07-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多