UITextview 设置属性文本导致性能下降
UITextview set Attribute Text cause Performance slow
我是 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
}
尝试删除光标位置更改的最后一行,看看这是否是性能下降的原因。如果是这样,请稍等片刻后尝试执行此部分:
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .milliseconds(5)) {[weak self] in
self?.myTextView.selectedRange.location += 1
}
你所做的可以概括为-
- 添加段落样式和其他文本属性。
- 读取
attributedText
的旧值,使用所有这些数据重新创建 NSAttributedString
的新实例。
- 手动管理光标位置(向后删除 (-1) vs 添加字符 (+1))
- 手动更新
textView.textStorage
。
return false
- 不允许系统控制输入。
此处还有许多其他详细信息,UITextView
会自动为您涵盖 - 如果您允许系统控制输入。例如-
You are not accounting for what happens when user selects a range of characters and hits backward delete. (-1 won't cover for this case).
下面的代码与您当前的代码完全相同 -
// 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
}
我是 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
}
尝试删除光标位置更改的最后一行,看看这是否是性能下降的原因。如果是这样,请稍等片刻后尝试执行此部分:
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .milliseconds(5)) {[weak self] in
self?.myTextView.selectedRange.location += 1
}
你所做的可以概括为-
- 添加段落样式和其他文本属性。
- 读取
attributedText
的旧值,使用所有这些数据重新创建NSAttributedString
的新实例。 - 手动管理光标位置(向后删除 (-1) vs 添加字符 (+1))
- 手动更新
textView.textStorage
。 return false
- 不允许系统控制输入。
此处还有许多其他详细信息,UITextView
会自动为您涵盖 - 如果您允许系统控制输入。例如-
You are not accounting for what happens when user selects a range of characters and hits backward delete. (-1 won't cover for this case).
下面的代码与您当前的代码完全相同 -
// 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
}