我想找到用户正在输入的当前段落(插入符号所在的位置)。示例:在第二段中。
我知道我可以使用:let components = textView.text.components(separatedBy: "\n")
分隔段落,但是我不确定如何对当前的编辑段落进行检查。有任何想法吗?
最佳答案
这是一种方法...
获取插入符号的Y位置(插入点)。然后,遍历textView中的段落枚举,将其边界矩形与插入符号位置进行比较:
extension UITextView {
func boundingFrame(ofTextRange range: Range<String.Index>?) -> CGRect? {
guard let range = range else { return nil }
let length = range.upperBound.encodedOffset-range.lowerBound.encodedOffset
guard
let start = position(from: beginningOfDocument, offset: range.lowerBound.encodedOffset),
let end = position(from: start, offset: length),
let txtRange = textRange(from: start, to: end)
else { return nil }
return selectionRects(for: txtRange).reduce(CGRect.null) { $0.union($1.rect) }
}
}
// return value will be Zero-based index of the paragraphs
// if the textView has no text, return -1
@objc func getParagraphIndex(in textView: UITextView) -> Int {
// this will make sure the the text container has updated
theTextView.layoutManager.ensureLayout(for: theTextView.textContainer)
// make sure we have some text
guard let str = theTextView.text else { return -1 }
// get the full range
let textRange = str.startIndex..<str.endIndex
// we want to enumerate by paragraphs
let opts:NSString.EnumerationOptions = .byParagraphs
var caretYPos = CGFloat(0)
if let selectedTextRange = theTextView.selectedTextRange {
caretYPos = theTextView.caretRect(for: selectedTextRange.start).origin.y + 4
}
var pIndex = -1
var i = 0
// loop through the paragraphs, comparing the caret Y position to the paragraph bounding rects
str.enumerateSubstrings(in: textRange, options: opts) {
(substring, substringRange, enclosingRange, b) in
// get the bounding rect for the sub-rects in each paragraph
if let boundRect = self.theTextView.boundingFrame(ofTextRange: substringRange) {
if caretYPos > boundRect.origin.y && caretYPos < boundRect.origin.y + boundRect.size.height {
pIndex = i
b = true
}
i += 1
}
}
return pIndex
}
用法:
let paraIndex = getParagraphIndex(in myTextView)
关于ios - 获取当前段落索引,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56772930/