Отображение частичных строк текста на намеренно усеченном UITextView - PullRequest
0 голосов
/ 15 января 2020

Есть много вопросов к inte rnet, жалующихся на то, как UITextView преждевременно обрезает текст, но я не могу найти ничего об обратной ситуации, когда вы на самом деле хотите обрезать текст текст до конца - но частично через строку.

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

т.е. он в настоящее время делает то, что здесь слева, тогда как я ищу способ сделать то, что справа :

Illustration of partial lines of text

My UITextView имеет фиксированную высоту и прокрутка отключена. Я назначаю attributedText, который может иметь жирный шрифт, курсив и т. Д. c, а не простую строку.

Ответы [ 2 ]

1 голос
/ 15 января 2020

Я не думаю, что вы можете сделать это sh со свойствами UITextView.

Один подход, хотя:

  • встроить текстовое представление в "контейнер" "UIView
  • ограничить высоту представления контейнера по желанию
  • установить Clips to Bounds представления контейнера в значение ИСТИНА

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

Фон представления контейнера - желтый, фон представления текста - голубой:

enter image description here

Использование иерархии представления отладки - Show Clipped Content:

enter image description here

и вот трехмерный вид:

enter image description here


РЕДАКТИРОВАТЬ

Вот другой подход - может или не может работать для ваших требований. ..

  • UITextView - установить ограничения для положения, ширины и высоты
  • НЕ редактируется
  • ДА выбирается
  • Прокрутка включена - будет отображаться частичная строка
  • Отключить индикаторы прокрутки шоу

Теперь добавьте UIPanGestureRecognizer в это текстовое представление. Он не должен ничего делать ... но он (по крайней мере, кажется) не позволяет текстовому представлению получать жест панорамирования и, таким образом, предотвращает прокрутку.

Хотя одна заметная проблема ... если у вас достаточно текста, чтобы вы получили несколько строк, когда вы начинаете выделять, вы можете перетащить ручку выделения вниз на следующую строку (и), и текст будет прокручиваться вверх ..., вероятно, может предотвратить это в коде, или, может быть, это было бы желательно, а затем сбросьте прокрутку после того, как пользователь скопировал выделенный текст.

0 голосов
/ 15 января 2020

ОК, так что все получилось довольно быстро, но мне удалось это сделать ...

Вместо того, чтобы использовать стандарт UITextView, созданный через Interface Builder, мне пришлось вручную создать его, используя пользовательский NSTextContainer:

let frame = containerView.frame

let textStorage = NSTextStorage(string: "")
let layoutManager = NSLayoutManager()

let textContainer = CardTextContainer(size: CGSize(width: frame.size.width, height: CGFloat.greatestFiniteMagnitude))
textContainer.widthTracksTextView = true

layoutManager.addTextContainer(textContainer)
textStorage.addLayoutManager(layoutManager)

let textView = UITextView(frame: frame, textContainer: textContainer)
textView.isScrollEnabled = false

containerView.addSubview(textView)

Затем я определил CardTextContainer как подкласс NSTextContainer, который делегирует свое поведение базовому классу, за исключением случая, когда отображаемая строка перекрывается с нижней частью NSTextView:

class CardTextContainer : NSTextContainer {

    override func lineFragmentRect(forProposedRect proposedRect: CGRect, at characterIndex: Int, writingDirection baseWritingDirection: NSWritingDirection, remaining remainingRect: UnsafeMutablePointer<CGRect>?) -> CGRect {

        let fragmentRect = super.lineFragmentRect(forProposedRect: proposedRect, at: characterIndex, writingDirection: baseWritingDirection, remaining: remainingRect)

        if ((fragmentRect.size.width > 0) || (fragmentRect.size.height > 0)) {
            // Just rely on the base implementation when it's working well
            return fragmentRect
        } else {
            // See if we could do slightly better than they did
            if (proposedRect.origin.y < self.size.height) {
                return CGRect(origin: proposedRect.origin, size: CGSize(width: self.size.width, height: proposedRect.size.height))
            } else {
                // Fall back to the 'I give up' solution
                return fragmentRect
            }
        }        
    }    
}
...