Как позволить NSTextField расти с текстом в автоматическом макете?

Автоматическое расположение в Lion должно позволить довольно просто позволить текстовому полю (и, следовательно, метке) расти вместе с текстом, который он содержит.

В Интерфейсном Разработчике текстовое поле установлено для переноса.

Какой простой и надежный способ сделать это?

Ответы на вопрос(3)

Свифт 4 Редактируемый авторазмер NSTextField

На основании поста Питера Лапису в Objective-C

SubclassNSTextField, добавьте код ниже.

override var intrinsicContentSize: NSSize {
    // Guard the cell exists and wraps
    guard let cell = self.cell, cell.wraps else {return super.intrinsicContentSize}

    // Use intrinsic width to jive with autolayout
    let width = super.intrinsicContentSize.width

    // Set the frame height to a reasonable number
    self.frame.size.height = 750.0

    // Calcuate height
    let height = cell.cellSize(forBounds: self.frame).height

    return NSMakeSize(width, height);
}

override func textDidChange(_ notification: Notification) {
    super.textDidChange(notification)
    super.invalidateIntrinsicContentSize()
}

Настройкаself.frame.size.height до «разумного числа» @ Избега некоторые ошибки при использованииFLT_MAX, CGFloat.greatestFiniteMagnitude или большие цифры. Ошибки возникают во время работы, когда пользователь выбирает выделение текста в поле, они могут перетаскивать прокрутку вверх и вниз в бесконечность. Кроме того, когда пользователь вводит текст,NSTextField отключается, пока пользователь не закончит редактирование. Наконец, если пользователь выбрал символNSTextField, а затем пытается изменить размер окна, если значениеself.frame.size.height слишком велик, окно будет висеть.

intrinsicContentSize но это может быть необходимо не во всех случаях. Autolayout будет расти и уменьшать высоту текстового поля, если (а) вы дадите текстовому полю символpreferredMaxLayoutWidth и (б) сделать поле неeditable. Эти шаги позволяют текстовому полю определять его собственную ширину и вычислять высоту, необходимую для автоматического размещения. Видеть этот ответ а также этот ответ Больше подробностей

Еще более странно, это следует из зависимости от @ текстового поeditable атрибут, что autolayout сломается, если вы используете привязки на поле и не можете очиститьConditionally Sets Editable вариант.

 Bryan17 мар. 2019 г., 03:20
Seconded. Это правильный ответ
 Oskar27 янв. 2019 г., 11:44
Это правильный ответ, нет необходимости в подклассе
Решение Вопроса

intrinsicContentSize вNSView возвращает то, что само представление считает своим внутренним размером контента.

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

Hence, пользовательский подклассNSTextField может переопределить этот метод, чтобы вернуть лучшее значение, такое как значение, предоставленное ячейкойcellSizeForBounds: метод:

-(NSSize)intrinsicContentSize
{
    if ( ![self.cell wraps] ) {
        return [super intrinsicContentSize];
    }

    NSRect frame = [self frame];

    CGFloat width = frame.size.width;

    // Make the frame very high, while keeping the width
    frame.size.height = CGFLOAT_MAX;

    // Calculate new height within the frame
    // with practically infinite height.
    CGFloat height = [self.cell cellSizeForBounds: frame].height;

    return NSMakeSize(width, height);
}

// you need to invalidate the layout on text change, else it wouldn't grow by changing the text
- (void)textDidChange:(NSNotification *)notification
{
    [super textDidChange:notification];
    [self invalidateIntrinsicContentSize];
}
 ideawu11 янв. 2014 г., 07:02
IntrinsicContentSize: метод не вызывается при изменении текста в нем с помощью setStringValue:.
 Scott Roth27 окт. 2012 г., 16:30
Это точно соответствует тому, что я вижу. Просто чтобы прояснить, это игнорирование свойства 'wraps' в ячейке кажется ошибкой в Lion, которая была исправлена в Mountain Lion. Так что, если вы нацелены на Lion и выше, вы увидите разные результаты в 2 ОС, пока не примените исправление, чтобы ускорить Lion.
 Arvin12 нояб. 2012 г., 15:52
Да, это ошибка в Lion. Мне бы очень хотелось, чтобы Apple исправила эти проблемы в OS X 10.7 и 10.8. В моей реализации я делаю еще несколько проверок для особых случаев (например, если это Lion ||, если язык не английский), и я устанавливаю свой рост немного по-другому. Тем не менее, то, что опубликовал Monolo, является хорошим началом.
 Peter Lapisu04 окт. 2014 г., 21:12
Вам нужно сделать недействительным макет - - (void) textDidChange: (NSNotification *) уведомление {[super textDidChange: уведомление]; [self invalidateIntrinsicContentSize]; }
 Clifton Labrum08 нояб. 2017 г., 23:07
Кто-нибудь сделал версию Swift за последнее время?

Ваш ответ на вопрос