Пространство строк NSParagraphStyle игнорируется

Простой тест, который не удалось: создайте новый проект только с одним подвью (UITextView) и поместите следующее в:

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.lineHeightMultiple = 50.f;
    paragraphStyle.lineSpacing = 100.f;
    paragraphStyle.minimumLineHeight = 200.f;
    paragraphStyle.maximumLineHeight = 500.f;

    UIFont *font = [UIFont fontWithName:@"AmericanTypewriter" size:24.f];

    self.textView.attributedText = [[NSAttributedString alloc] initWithString:
    @"This is a test.\n Will I pass?" attributes:
    @{NSParagraphStyleAttributeName : paragraphStyle, NSFontAttributeName : font}];
}

Интервал между линиями такой же, как если бы атрибут отсутствовал. Имеет ли что-нибудь, чтобы это успешно работало? Я ввел смешные цифры, чтобы показать, что это не изменится...

Ответ 1

Это ошибка в NSHTMLWriter, которая является частным классом, который UITextView использует для преобразования атрибутаText в HTML. Внутри он отображает этот HTML через UIWebDocumentView. Подробнее о внутренней работе UITextView читайте здесь: http://www.cocoanetics.com/2012/12/uitextview-caught-with-trousers-down/

Проблема заключается в легкой пропуске специальности в сокращении шрифта CSS. Если вы укажете размер пикселя со стенографией шрифта, тогда он устанавливает BOTH размер шрифта, а также высоту строки. Поскольку NSHTMLWriter помещает шрифт AFTER в строку-height, это приводит к тому, что высота строки будет отменена размером шрифта.

Смотрите здесь для моего радара, который включает в себя полный анализ ошибки: http://www.cocoanetics.com/2012/12/radar-uitextview-ignores-minimummaximum-line-height-in-attributed-string/

Я предлагаю вам также отправить отчет об ошибке и упомянуть мой радар № 12863734.

Ответ 2

Я не знаю, достаточно ли этого для ваших целей, но я мог бы отрегулировать интервал между строками, установив минимальную и максимальную высоту линии. Кроме того, чтобы использовать шрифт, я помещал его в свойство font текстового представления, а не передавал его как значение NSFontAttributeName в словаре атрибутов. (Может быть, эта часть не подтверждена (хорошо)?)

О ваших атрибутах

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

Также, если вам нужно просто отрегулировать расстояние между линиями, вам, вероятно, не нужно использовать paragraphStyle.lineHeightMultiple:)

Код

Это сработало для меня:

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.minimumLineHeight = 35.f;
paragraphStyle.maximumLineHeight = 35.f;

UIFont *font = [UIFont fontWithName:@"AmericanTypewriter" size:18.f];
NSString *string = @"This is a test.\nWill I pass?\n日本語のもじもあるEnglish\nEnglish y Español";
NSDictionary *attributtes = @{
    NSParagraphStyleAttributeName : paragraphStyle,
};
self.textView.font = font;
self.textView.attributedText = [[NSAttributedString alloc] initWithString:string
                                 attributes:attributtes];

BNqME.png

Дополнительные примечания

Кажется, что есть ситуация с японцами /Chinesse и, возможно, с другими символами, смешанными с символами алфавита в одной строке. Это сделает эту линию более важной, чтобы решить, что вам нужно настроить минимальную и максимальную высоту линии, как и я. Вы можете увидеть проблему при рендеринге моего примера без атрибутов.

Ответ 3

Настройка maximumLineHeight, похоже, разрешает эту проблему для меня;

CGFloat fontSize = 22.f;
titleLabel.font = [UIFont boldSystemFontOfSize:fontSize];
NSMutableParagraphStyle *paragraphStyle = [[[NSMutableParagraphStyle  alloc] init] autorelease];
paragraphStyle.maximumLineHeight = fontSize/2;
titleLabel.attributedText = [[[NSAttributedString alloc]
                              initWithString:@"This is a test.\nWill I pass?"
                              attributes: @{ NSParagraphStyleAttributeName : paragraphStyle,
                                             NSFontAttributeName : titleLabel.font}]
                             autorelease];

overlapping lines

Ответ 4

Для этой конкретной строки вам нужно установить paragraphSpacing. Что насчет lineSpacing, я считаю, что он просто не поддерживается на iOS.

Ответ 5

Как ответил nacho4d, в iOS 6 вам нужно использовать minimumLineHeight и maximumLineHeight и установить шрифт непосредственно в UITextView. > , а не в NSAttributedString, поскольку высота строки в этом случае будет переопределена.

Обратите внимание, что когда вы устанавливаете шрифт в UITextView, "редактируемое свойство UITextView должно быть установлено на YES, в противном случае присваиваемый текст не будет затронут.

Эти проблемы присутствуют только в iOS 6. В iOS 7 и выше все в порядке;

Ответ 6

В моем случае ни один из стилей абзаца не работал. Исправлено, чтобы установить атрибутный текст на этикетке ПОСЛЕ выполнения любых корректировок кадра на этикетке.:)