Подсчет количества строк в UITextView, строк, обернутых по размеру кадра

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

Другое предложение для защиты вашего программного обеспечения: создать бизнес-модель, в которой код является неполной частью стоимости вашего предложения. Например, продавайте лицензии на продукт вместе с доступом к некоторым данным, которые вы управляете на своем сайте, или лицензируете продукт на модели подписки или при поддержке клиента.

Разработка EULA является юридическим вопросом, а не вопросом кодирования , Вы можете начать с чтения некоторого текста EULA для продуктов и веб-сайтов, которые вы используете. Вы можете найти интересные подробности!

Создание проприетарной лицензии является очень гибким и, вероятно, предметом, выходящим за рамки предполагаемого объема StackOverflow, поскольку это не совсем о кодировании.

Некоторые части EULA, которые приходят на ум:

  • Ограничение вашей ответственности, если у продукта есть ошибки или причинения ущерба.
  • Выяснение того, как клиент может использовать свое лицензионное программное обеспечение, для чего
  • Предоставление вам прав на аудит своего сайта, чтобы вы могли обеспечить соблюдение лицензий.
  • Что произойдет, если они нарушают правила, EULA, например они теряют свою привилегию использовать ваше программное обеспечение.

Вы должны обратиться к юристу для подготовки коммерческого лицензионного соглашения.

edit: Если этот проект не может оправдать расходы из них:

23
задан Shivaay 21 November 2018 в 10:22
поделиться

10 ответов

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

UIFont *font = [UIFont boldSystemFontOfSize:11.0];
CGSize size = [string sizeWithFont:font 
                      constrainedToSize:myUITextView.frame.size 
                      lineBreakMode:UILineBreakModeWordWrap]; // default mode
float numberOfLines = size.height / font.lineHeight;
27
ответ дан luvieere 21 November 2018 в 10:22
поделиться

Вам необходимо использовать свойство lineHeight и шрифт lineHeight:

Objective-C

int numLines = txtview.contentSize.height / txtview.font.lineHeight;

Swift

let numLines = (txtview.contentSize.height / txtview.font.lineHeight) as? Int

Я получаю правильное количество строк, надеюсь, это поможет и вам.

21
ответ дан Himanshu padia 21 November 2018 в 10:22
поделиться

Swift 3:

let layoutManager:NSLayoutManager = textView.layoutManager
let numberOfGlyphs = layoutManager.numberOfGlyphs
var numberOfLines = 0
var index = 0
var lineRange:NSRange = NSRange()

while (index < numberOfGlyphs) {
    layoutManager.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange)
    index = NSMaxRange(lineRange);
    numberOfLines = numberOfLines + 1
}

print(numberOfLines)
15
ответ дан castillejoale 21 November 2018 в 10:22
поделиться

Я нашел идеальное решение этой проблемы в Apple Text Layout Guide по программированию . Вот решение, которое предлагает Apple:

NSLayoutManager *layoutManager = [textView layoutManager];
unsigned numberOfLines, index;
unsigned numberOfGlyphs = [layoutManager numberOfGlyphs];
NSRange lineRange;

for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){
    (void) [layoutManager lineFragmentRectForGlyphAtIndex:index effectiveRange:&lineRange];
    index = NSMaxRange(lineRange);
}

Это можно легко записать в расширение для UITextView или в качестве автономного метода, принимающего объект UITextView в качестве параметра

9
ответ дан Luke Chase 21 November 2018 в 10:22
поделиться

Необходимо учитывать textView.textContainerInset, также необходимо округлить вычисленное значение, поскольку номер строки определенно является целым числом

float rawLineNumber = (textView.contentSize.height - textView.textContainerInset.top - textView.textContainerInset.bottom) / textView.font.lineHeight;
int finalLineNumber = round(rawLineNumber)

В реальном случае вы можете увидеть следующий результат rawLineNumber = 3.008099 finalLineNumber = 3 ( 3 строки)

7
ответ дан Jacky 21 November 2018 в 10:22
поделиться
   func numberOfLines(textView: UITextView) -> Int {
    let layoutManager = textView.layoutManager
    let numberOfGlyphs = layoutManager.numberOfGlyphs
    var lineRange: NSRange = NSMakeRange(0, 1)
    var index = 0
    var numberOfLines = 0

    while index < numberOfGlyphs {
        layoutManager.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange)
        index = NSMaxRange(lineRange)
        numberOfLines += 1
    }
    return numberOfLines
}

отлично работает для меня

4
ответ дан Softlabsindia 21 November 2018 в 10:22
поделиться

Swift 4 версия ответа Люка Чейза

let numberOfGlyphs = textView.layoutManager.numberOfGlyphs
var index = 0, numberOfLines = 0
var lineRange = NSRange(location: NSNotFound, length: 0)

while index < numberOfGlyphs {
  textView.layoutManager.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange)
  index = NSMaxRange(lineRange)
  numberOfLines += 1
}
4
ответ дан Yeesha 21 November 2018 в 10:22
поделиться

Я потратил много времени, пытаясь вычислить в реальном времени количество строк для входного TextView (скажем, в окне ввода текста чата), и единственное решение, которое работает в таком случае, это Люк Чейз (по какой-то причине кадр) Подход .height, по-видимому, обновляет только 3-ю или 4-ю букву, введенную в textView, и поэтому не является точной).

Однако, как упомянул комментатор, существует небольшая ошибка, из-за которой сгенерированные пользователем разрывы строк ("\ n" или нажатие клавиши на клавиатуре) не учитываются должным образом. Даже более странно, он только «пропускает» первый такой разрыв строки, все последующие правильно перехвачены (скажем, если вы перейдете на строку 4 раза, она вернет только 3 строки, явно пропустившие первый разрыв строки).

Итак, чтобы обойти эту ошибку, я просто смотрю запись первого такого переноса строки (символ «\ n») и вручную добавляю строку к числу строк, которое возвращает метод gliph.

В коде, который дает:

    func offSetTableViewIfNeeded() {
    let numberOfGlyphs = textView.layoutManager.numberOfGlyphs
    var index : Int = 0
    var lineRange = NSRange(location: NSNotFound, length: 0)
    var currentNumOfLines : Int = 0
    var numberOfParagraphJump : Int = 0

    while index < numberOfGlyphs {
        textView.layoutManager.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange)
        index = NSMaxRange(lineRange)
        currentNumOfLines += 1

        // Observing whether user went to line and if it's the first such line break, accounting for it.
        if textView.text.last == "\n", numberOfParagraphJump == 0 {
            numberOfParagraphJump = 1
        }
    }

    currentNumOfLines += numberOfParagraphJump

    print("Number of lines is:", currentNumOfLines)

Надеюсь, что это поможет другим, кто боролся со сверхъестественным поведением ввода textView (не может понять, почему Apple не предоставляет метод # line out из коробки!).

1
ответ дан Franc 21 November 2018 в 10:22
поделиться

Быстрое расширение:

Использование ответа @himanshu padia

//MARK: - UITextView
extension UITextView{

    func numberOfLines() -> Int{
        if let fontUnwrapped = self.font{
            return Int(self.contentSize.height / fontUnwrapped.lineHeight)
        }
        return 0
    }

}

Использование: yourTextView.numberOfLines()

знать, что если по какой-то причине шрифт текстового представления - ноль, возвращение будет ноль.

8
ответ дан Juan Boero 21 November 2018 в 10:22
поделиться

Используйте это (где _text_v - ваш текстовый просмотр):

-(NSInteger) linesCount {
    return _text_v.contentSize.height/_text_v.font.lineHeight;
}
4
ответ дан Max 21 November 2018 в 10:22
поделиться