NSStackView и подпредставления с внутренним размером контента
У меня есть NSStackView, созданный программно, к которому я добавляю один NSButton.
NSStackView *stackView = [[NSStackView alloc] initWithFrame:rect];
stackView.autoresizingMask = NSViewWidthSizable|NSViewHeightSizable;
stackView.alignment = NSLayoutAttributeBaseline;
(...)
NSButton *button = [[NSButton alloc] initWithFrame:CGRectMake(0, 0, 40, 50)];
button.image = item.image;
button.title = item.name;
button.bordered = NO;
button.imagePosition = NSImageAbove;
button.translatesAutoresizingMaskIntoConstraints = NO;
(...)
[stackView addView:button inGravity:NSStackViewGravityLeading];
Я ожидал, что этого будет достаточно, так как кнопка имеет внутренний размер контента (я проверила, что она возвращает соответствующее значение).
Изучив иерархию представлений, я вижу, что кадр кнопок имеет origin=(x=0, y=0) size =(width=40, height=50), его суперпредставление (экземпляр NSStackViewContainer) имеет origin=(x=0, y=0) размер = (ширина = 0, высота = 0), а NSStackView имеет происхождение = (x = 0, y = 0) размер = (ширина =400, высота =50).
Как вы можете видеть, NSStackViewContainer имеет 0 ширину и высоту...
Если я добавлю ограничения ширины и высоты для кнопки, все будет работать нормально. Почему кнопки intrinsicContentSize недостаточно?
2 ответа
[stackView constraints]
вероятно возвращает пустой массив - что неверно и вызывает проблему. Если это так, то ничто не вызывает начальный проход обновления ограничений или макета, когда представление стека находится в окне.
Добавление ваших собственных ограничений в окне было бы достаточно для его запуска, но NSStackView должен иметь возможность запускать его сам, если это не было иначе (это, вероятно, заслуживает того, чтобы перехватить радар).
Один из способов обойти это, без добавления ненужных ограничений, это вызвать:
[window updateConstraintsIfNeeded];
или же
[window layoutIfNeeded];
после того, как StackView был добавлен в окно.
Обновление: это исправлено в NSStackView в Yosemite, 10.10.
Разве вы не должны использовать addArrangedSubview вместо addView?