Автомакет в Lion должен сделать достаточно простым, чтобы текстовое поле (и, следовательно, ярлык) увеличивалось с сохраненным текстом.
Текстовое поле настроено на обертку в Interface Builder.
Что такое простой и надежный способ сделать это?
Автомакет в Lion должен сделать достаточно простым, чтобы текстовое поле (и, следовательно, ярлык) увеличивалось с сохраненным текстом.
Текстовое поле настроено на обертку в Interface Builder.
Что такое простой и надежный способ сделать это?
Метод intrinsicContentSize в NSView возвращает то, что сам взгляд рассматривает как его собственный размер содержимого.
NSTextField вычисляет это без учета свойства wraps своей ячейки, поэтому он будет сообщать размеры текста, если он выложен в одной строке.
Следовательно, пользовательский подкласс NSTextField может переопределить этот метод, чтобы вернуть лучшее значение, например, предоставленное методом cell 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];
}
Основано на посте Питера Лапису Objective-C
Подкласс NSTextField, добавьте код ниже.
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 будет увеличиваться и уменьшать высоту текстового поля, если (a) вы даете текстовое поле a preferredMaxLayoutWidth и (b) создаете поле не editable. Эти шаги позволяют текстовому полю определять его внутреннюю ширину и вычислять высоту, необходимую для автоматического отключения. Подробнее см. этот ответ и этот ответ.
Еще более неясно, из зависимости от атрибута текстового поля editable, что автоопределение будет нарушено, если вы используете привязки в поле и не можете очистить параметр Conditionally Sets Editable.