ScrollRectToVisible для представления совпадающей строки поиска для прокрутки до среднего представления UITextView

У меня есть UiTextView, который я использую для отображения подробного текста. Иногда текст может быть достаточно длинным, чтобы его прокрутить. Иногда текст может быть достаточно коротким, чтобы поместиться во фрейме UITextView.

Я также реализую функцию поиска, которую можно использовать для поиска более длинных текстовых строк. Функция добавляет атрибут цвета шрифта к тексту, соответствующему строке ввода поиска. Функция собирает массив значений NSRange для каждого совпадающего ввода строки поиска. Я использую регулярное выражение для сопоставления строки поиска и возвращаю массив значений NSRange для каждого совпадения.

В настоящее время я разрабатываю функцию, которая анимирует пользователя в позицию UITextView совпадающей строки поиска.

Позже я предоставлю кнопку, которую пользователь может щелкнуть, чтобы просмотреть совпадения.

Пока все работает очень хорошо. См. код ниже. detailText — это UITextView:

    // rangeOfSearchText uses a regex to return the range of the match. For text purposes, the function returns the first index only. 

   let rangeOfMatch = rangeOfSearchText(searchString: self.searchText!, UIText: self.detailText.text)

   let glyRange =  self.detailText.layoutManager.glyphRange(forCharacterRange: rangeOfMatch, actualCharacterRange:nil)

   let rect =  self.detailText.layoutManager.lineFragmentRect(forGlyphAt: NSMaxRange(glyRange), effectiveRange: nil)
   self.detailText.scrollRectToVisible(rect, animated: true)

Хотя код работает хорошо, совпадающий текст отображается внизу результирующего фрейма UITextView. Я хочу, чтобы совпадающий текст отображался в середине представления. Я попробовал следующий фрагмент кода, который вроде как работает:

self.detailText.contentOffset.y = 200      

contentOffset работает должным образом только в том случае, если совпадающий текстовый диапазон находится в середине более крупной многострочной строки. Если совпадающий текстовый диапазон находится в начале строки, реализация contentOffset прокручивает пользователя за совпадающий текст на 200. По сути, совпавший текст прокручивается вне поля зрения. Это нехорошо. Если совпадающий текст находится в конце многострочного текста, contentOffset добавляет больше пробелов, чтобы совпадающий текст располагался в середине представления. Ни один из результатов не является желаемым. Я могу жить с последним, но первый не годится, потому что он прокручивает первый совпадающий текст из поля зрения.

Я искал аналогичную проблему с переполнением стека, но не нашел. Если он существует, пожалуйста, укажите на него. Если нет, любое предложение приветствуется.


person KDiaz    schedule 25.03.2019    source источник


Ответы (1)


Похоже, это работает:

if rect.minY >= detailText.frame.height/2 {

self.detailText.scrollRectToVisible(rect.offsetBy(dx: 0.0, dy: detailText.frame.height/2), animated: true)

}

person KDiaz    schedule 25.03.2019