在 NSTextView 中查找子字符串,然后滚动到子字符串的位置



我正在构建一个简单的Mac应用程序,该应用程序具有很长的字符串(15mb文本(的NSTextView。我想找到一个特定的子字符串(时间戳(,然后向下滚动到 NSTextView 中子字符串的位置。

现在我能够找到子字符串所在位置的索引,但它的格式很奇怪。我在这里使用了最高答案:使用 Swift 索引字符串中的子字符串

@IBOutlet weak var logTextView: NSScrollView!
@IBOutlet var logTextBox: NSTextView!
let searchString = "2018-03-29 19:10:17"
let baseString = logTextBox.string
let findIndex = baseString.endIndex(of: searchString)!
print(findIndex)

// Function I got from the stack overflow link
extension StringProtocol where Index == String.Index {
func index<T: StringProtocol>(of string: T, options: String.CompareOptions = []) -> Index? {
    return range(of: string, options: options)?.lowerBound
}
func endIndex<T: StringProtocol>(of string: T, options: String.CompareOptions = []) -> Index? {
    return range(of: string, options: options)?.upperBound
}
func indexes<T: StringProtocol>(of string: T, options: String.CompareOptions = []) -> [Index] {
    var result: [Index] = []
    var start = startIndex
    while start < endIndex, let range = range(of: string, options: options, range: start..<endIndex) {
        result.append(range.lowerBound)
        start = range.lowerBound < range.upperBound ? range.upperBound : index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex
    }
    return result
}
func ranges<T: StringProtocol>(of string: T, options: String.CompareOptions = []) -> [Range<Index>] {
    var result: [Range<Index>] = []
    var start = startIndex
    while start < endIndex, let range = range(of: string, options: options, range: start..<endIndex) {
        result.append(range)
        start = range.lowerBound < range.upperBound  ? range.upperBound : index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex
    }
    return result
}
}

NSTextViewNSText的子类,NSText定义了一个scrollRangeToVisible(NSRange)方法。因此,您可以将其用于滚动部分,但它需要 NSRange .

有一个记录不佳的NSRange初始值设定项可以将Range转换为NSRange。所以:

let haystack = logTextBox.string
let needle = "2018-03-29 19:10:17"
if let needleRange = haystack.range(of: needle) {
    logTextBox.scrollRangeToVisible(NSRange(needleRange, in: haystack))
}

最新更新