String in Swift
在使用 Swift 操作字符串时,尤其是在处理 text filed/text view 时,需要做输入限制的时候,难免会遇到一些坑,甚至 crash。原因就是不同用户有着不一样的输入习惯,有些用户喜欢用纯文字,有些喜欢使用表情(emoj) 等,如果处理不当,就很容易出现问题。下面就是我遇到的一个 emoj 问题,因为刚开始我没有使用 utf16 来处理 index, 导致 index 越界发生 crash。以下为正确的用法:
NSRange Range 互转
extension String { func range(from nsRange: NSRange) -> Range<String.Index>? { let view = utf16 guard let start = view.index(view.startIndex, offsetBy: nsRange.location, limitedBy: view.endIndex), let end = view.index(start, offsetBy: nsRange.length, limitedBy: view.endIndex), let startIndex = String.Index(start, within: self), let endIndex = String.Index(end, within: self) else { return nil } return startIndex..<endIndex } func nsRange(from range: Range<String.Index>) -> NSRange? { let view = utf16 guard let start = range.lowerBound.samePosition(in: view), let end = range.upperBound.samePosition(in: view) else { return nil } return NSRange( location: view.distance(from: view.startIndex, to: start), length: view.distance(from: start, to: end) ) } }
|
在处理文字输入时使用 Range
class ViewController: NSViewController, NSTextViewDelegate { @IBOutlet var textView: NSTextView! override func viewDidLoad() { super.viewDidLoad() textView.delegate = self }
func textView(_ textView: NSTextView, shouldChangeTextIn affectedCharRange: NSRange, replacementString: String?) -> Bool { let string = textView.string guard let range = string.range(from: affectedCharRange) else { return true } let newString = string.replacingCharacters(in: range, with: replacementString ?? "") print(finalString) return true } }
|
如果您喜欢这篇文章,或觉得对您有用的话,欢迎发表评论,您也可以随意的分享或转载这篇文章。如果文章中的图片有侵犯您的版本,请联系作者将期删除。谢谢您的支持!