Как определить, когда UILabel будет усечен, или позиция его разрыва строки изменится

У меня есть многострочный UILabel ( numberOfLines = 0). Его ширина может меняться во время выполнения, а иногда это приводит к усечению и / или повторной упаковке. Некоторые примеры иллюстрируют это лучше всего:

Пример 1: уменьшение ширины приводит к другой точке разрыва линии

введите описание изображения здесьвведите описание изображения здесь

Пример 2: уменьшение ширины приводит к усечению

введите описание изображения здесьвведите описание изображения здесь

Пример 3: уменьшение ширины приводит как к усечению, так и к другой позиции разрыва линии

введите описание изображения здесьвведите описание изображения здесь

Пример 4: уменьшение ширины не оказывает никакого влияния на усечение или положение разрыва линии

введите описание изображения здесьвведите описание изображения здесь

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

Как я могу проверить это? Тест должен вернуть YES, например, 1, 2 и 3, но NO, например, 4.

Примечание. Изменение размера никогда не изменит количество строк в моем примере.

Примечание 2: если у кого-то есть лучшие теги, связанные с форматированием текста, я бы хотел их узнать – не стесняйтесь редактировать.

Примечание 3: если вы заинтересованы в том, чтобы это поведение было выполнено, попробуйте Apple mail.app на iPhone. При просмотре папки «Входящие» проведите по электронной почте и просмотрите итоговую строку fade-in / out, поскольку она повторно обертывает и / или усекает (но не тогда, когда это не нужно).

5 Solutions collect form web for “Как определить, когда UILabel будет усечен, или позиция его разрыва строки изменится”

Вы можете узнать размер метки, необходимый для отображения конкретного экземпляра NSString . Например, вы можете использовать это:

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode

Возвращает размер строки, если она была визуализирована с указанными ограничениями.

Итак, вы хотите получить CGSize для конкретной строки и проверить, не больше ли она размера UILabel :

  UILabel *label; CGSize sizeNeeded = [label.text sizeWithFont:label.font constrainedToSize:CGSizeMake(label.bounds.size.width, MAXFLOAT)]; if (sizeNeeded.height > label.bounds.size.height) { NSLog(@"String is truncated"); } 

Более полезные методы NSString вы можете найти здесь: NSString UIKit Дополнительные ссылки

Хорошо, еще один способ сделать то, что вы хотите:

1) Создайте 2 UILabel с теми же свойствами, но второй ( label2 ) будет с другой width .

2) Установите alpha свойство label2 на 0.0 в режиме без редактирования.

3) Когда режим редактирования начинает делать такую ​​анимацию:

 // label1.alpha == 1.0, label2.alpha == 0.0 {[UIView animateWithDuration:0.5 animations:^{ label1.alpha = 0.0; label2.alpha = 1.0; }]; 

4) Когда режим редактирования заканчивается:

 {[UIView animateWithDuration:0.5 animations:^{ label1.alpha = 1.0; label2.alpha = 0.0; }]; 

Это даст вам тот же результат, что и в Mail.app

Решение Swift 3

Вы можете подсчитать количество строк после назначения строки и сравнить с максимальным количеством строк метки.

 import Foundation import UIKit extension UILabel { func countLabelLines() -> Int { // Call self.layoutIfNeeded() if your view is uses auto layout let myText = self.text! as NSString let attributes = [NSFontAttributeName : self.font] let labelSize = myText.boundingRect(with: CGSize(width: self.bounds.width, height: CGFloat.greatestFiniteMagnitude), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: attributes, context: nil) return Int(ceil(CGFloat(labelSize.height) / self.font.lineHeight)) } func isTruncated() -> Bool { if (self.countLabelLines() > self.numberOfLines) { return true } return false } } 

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

 - (BOOL)isLabelTruncated:(UILabel *)label { BOOL isTruncated = NO; CGRect labelSize = [label.text boundingRectWithSize:CGSizeFromString(label.text) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : label.font} context:nil]; if (labelSize.size.width / labelSize.size.height > label.numberOfLines) { isTruncated = YES; } return isTruncated; } 

Используйте этот метод, чтобы найти lable, усеченный в iOS 7.

 - (BOOL)isTruncated:(UILabel *)label{ CGSize sizeOfText = [label.text boundingRectWithSize: CGSizeMake(label.bounds.size.width, CGFLOAT_MAX) options: (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes: [NSDictionary dictionaryWithObject:label.font forKey:NSFontAttributeName] context: nil].size; if (self.frame.size.height < ceilf(sizeOfText.height)) { return YES; } return NO; } 

Для версий выше iOS 7 вы можете проверить следующие решения:

  1. https://stackoverflow.com/a/30813691/2123122
  2. https://stackoverflow.com/a/32094824/2123122
  • Прокрутка ручек с UIView поверх UIScrollView, ScrollView wont Scroll
  • Создайте вырез UIImage
  • Добавьте одно и то же представление в несколько раз для просмотра
  • Мигающий эффект на UILabel
  • Определяется класс без указания базового класса?
  • также рекурсивно удаляет рекурсивные представления своих детей?
  • Как представить UIViewController из SKScene?
  • Выполнение многих операций UIKit, блокирующих основной поток
  • UIView внутри UIScrollView не обновлялся, несмотря на вызов метода «setNeedDisplay»
  • используйте UIVisualEffectView, чтобы создать размытие, исправить на симуляторе, но не на iphone & ipad
  • На iOS setNeedsDisplay действительно не вызывает вызов drawRect ... если показ CALayer или drawInContext наконец не вызовет drawRect?
  • Interesting Posts

    Неверное значение backgroundTimeRemaining в методе applicationDidEnterBackground

    Сохранение данных изображения в базу данных sqlite в iphone

    Скриншот SDK для iOS

    iOS: уведомлять другие контроллеры представлений с вкладками об изменении своего набора данных

    Разностное поведение didReceiveRemoteNotification между производством и развитием APNS

    Может ли CoreBluetooth установить пару и поговорить с ведомым модулем bluetooth 2.0?

    Просмотр над строкой состояния

    Невозможно увидеть UIView после добавления в UIViewController в раскадровке отдельно в последнем xcode 5

    Присвойте значение в Swift заменяет запятую точкой с запятой

    Передача целого числа между сценами, iphone game sprite-kit

    Преобразование MIDI-файла в аудиофайл с использованием библиотеки звуковых фонограмм SF2 с аудиокитом

    Как указать startTime для анимации с помощью CFTimeInterval?

    Внутренняя консистентность UIScrollView

    Как загрузить URL-адрес HTTPS в iOS 9?

    iOS 10 UNUserNotificationCenterDelegate не вызывается. push notifications не работает

    PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.