【问题标题】:UITextview set Attribute Text cause Performance slowUITextview 设置属性文本导致性能变慢
【发布时间】:2021-06-15 09:48:28
【问题描述】:

我是 iOS 的初学者。我想在用户输入时设置 UITextview 属性文本,没关系,但问题是性能滞后,而且太慢。我不知道发生了什么。我将不胜感激您的任何帮助!谢谢

  
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
       
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineBreakMode = .byWordWrapping
        paragraphStyle.alignment = .left

        let alignTextAttributes = [
            NSAttributedString.Key.kern : 30,
            NSAttributedString.Key.paragraphStyle : paragraphStyle,
            NSAttributedString.Key.foregroundColor : UIColor.black,
         
            ]
        as [NSAttributedString.Key : Any]
       
        let atribute = NSAttributedString(string: text, attributes: alignTextAttributes)
        
        

       
        var cursorLocation = textView.selectedRange.location
        if text == ""{
            textView.textStorage.replaceCharacters(in: range, with: atribute)
           cursorLocation -= 1
          
           
        }else{

            textView.textStorage.replaceCharacters(in: range, with: atribute)
            cursorLocation += 1
        }
     
       textView.selectedRange.location = cursorLocation

       //add attachment image to another uitextview
        let attachment = NSTextAttachment()
        let imageNew = UIImage(named: "icon")
        attachment.image = imageNew

       let attString = NSAttributedString(attachment: attachment)
       txtViewAnother.textStorage.replaceCharacters(in: range, with: attString)
 
        return false
                
      }

【问题讨论】:

  • 很伤心没有人帮助我
  • 首先,看起来没有使用 var 属性字符串。
  • 更进一步,考虑将 alignTextAttributes 存储为类级别属性,而不是在每次用户键入时重新创建它
  • 最后,尝试删除光标位置改变的最后一行,看看这是否是导致性能下降的原因。如果是这样,LMK 和我们将是一个解决方案
  • 非常感谢@ArikSegal,设置光标位置是问题所在。那么如何在输入普通文本时设置光标位置?

标签: ios swift text attributes uitextview


【解决方案1】:

你所做的可以概括为-

  1. 添加段落样式和其他文本属性。
  2. 读取attributedText 的旧值,使用所有这些数据重新创建NSAttributedString 的新实例。
  3. 手动管理光标位置(向后删除 (-1) 与添加字符 (+1))
  4. 手动更新textView.textStorage
  5. return false - 不允许系统控制打字。

这里还有很多其他细节UITextView 会自动为您介绍 - 如果您允许系统控制打字。比如——

当用户选择一系列字符并点击向后删除时,您没有考虑到会发生什么。 (-1 不会涵盖这种情况)。

以下代码与您当前的代码完全相同 -

// Initialize once and reuse every time
lazy var paragraphStyle: NSMutableParagraphStyle = {
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.lineBreakMode = .byWordWrapping
    paragraphStyle.alignment = .left
    return paragraphStyle
}()

// Initialize once and reuse every time    
lazy var alignTextAttributes: [NSAttributedString.Key: Any] = {
    return [
        .kern : 30,
        .paragraphStyle : paragraphStyle,
        .foregroundColor : UIColor.black,
    ]
}()
    
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    // If I want to set each characters with different kern values, how can I do that?
    alignTextAttributes[.kern] = textView.text.count.isMultiple(of: 2) ? 30 : 10

    // This is the key part
    textView.typingAttributes = alignTextAttributes

    // Allow system to control typing
    return true
}

【讨论】:

  • 非常感谢@Tarun。如果我想为每个字符设置不同的 kern 值,我该怎么做?
  • 您可以在分配typingAttributes 之前将.kern 值更改为您的选择。请参阅更新。
  • 谢谢你,还有一件事,当我用这种方法添加附件图像时,CPU 的增长与添加的附件数量一样多,它滞后。我调整图像大小但仍然发生。我通过添加更多代码来编辑我的问题。请帮帮我
  • 为此,您可以提出一个关注附件部分的新问题。
  • 我担心管理员会将其设为垃圾邮件。如果您现在可以帮助我解决附件问题,将很高兴。但不要介意我会检查你的代码并很快接受它。非常感谢你
【解决方案2】:

尝试删除更改光标位置的最后一行,看看这是否是导致性能下降的原因。如果是这样,请稍等片刻后尝试执行此部分:

    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .milliseconds(5)) {[weak self] in
        self?.myTextView.selectedRange.location += 1
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多