i have a uitextview with large texts and above i have a search field. Anything searched, i would love the uitextview to scroll to that specific text and hightlight. And i need to make sure that the uitextview scrolls in such a way that the searched text stays in the first line
I populated the textview with attributed text with some attributes. What i tried is get the text before the target text and tried to get the size of it adding the exact attributes i added on textview text at the beginning.
made a CGPoint using that height and set the contentOffset of the uitextview. But the textview scrolled no where near the target text. Maybe my approach is wrong as i dont have the width of the textview when setting attributes
My code is :
func goToBla() {
if let string = ayatTextView.text {
if let range = string.range(of: tazweedAyahas[8].text) {
let firstPart = string[string.startIndex..<range.lowerBound]
print("before \(tazweedAyahas[5].text) : ")
print(firstPart)
if let otherStr = firstPart as? NSString {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
let size = otherStr.size(withAttributes: [NSAttributedStringKey.paragraphStyle: paragraphStyle,
NSAttributedStringKey.font: UIFont(name: "me_quran", size: 30)
])
let point = CGPoint(x: 0, y: size.height)
ayatTextView.setContentOffset(point, animated: true)
}
}
}
}
Your approach is much more complicated than it needs to be. Use the scrollRangeToVisible
method of UITextView
.
func goToBla() {
if let string = ayatTextView.text, let range = string.localizedStandardRange(of: tazweedAyahas[8].text) {
let viewRange = NSRange(range, in: string)
ayatTextView.selectedRange = viewRange // optional
ayatTextView.scrollRangeToVisible(viewRange)
}
}
Note the following:
localizedStandardRange
when searching if you want to ignore diacritics and case, and you want other locale specific search features.selectedRange
if you want the matching text selected.If you want to get the selected range at the top, try something like this instead of calling scrollRangeToVisible
:
let rect = ayatTextView.layoutManager.boundingRect(forGlyphRange: viewRange, in: ayatTextView.textContainer)
ayatTextView.contentOffset = CGPoint(x: 0, y: rect.origin.y)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With