Расположение нескольких представлений в NSScrollView с использованием Visual AutoLayout
Мне нужно показать несколько видов, выровненных по вертикали внутри NSScrollView
Я начал с добавления NSTableView
а также NSButton
, Я выровнял их по вертикали NSTableView
сверху и NSButton
внизу я добавил NSTableview
а также NSButton
для NSView
называется tempView. А затем установите вид документа NSScrollView
для tempView.
Но у меня проблема в том, что мое табличное представление не расширяется должным образом, я вижу кнопки в порядке, но tablview не раскрывается должным образом и просто показывает последние записи, которые помещаются в таблицу. Как вы можете видеть на следующем рисунке, он отображает последние 4 строки по 20 строк.] Мой код следующий
-(void)setupView {
_scrollView = [[NSScrollView alloc] init];
[_scrollView setHasVerticalScroller:YES];
[_scrollView setHasVerticalRuler:YES];
[_scrollView setBorderType:NSBezelBorder];
[_scrollView setBackgroundColor:[NSColor purpleColor]];
_scrollView.autoresizingMask = NSViewHeightSizable;
_tableView = [[NSTableView alloc] init];
[_tableView setDataSource:self];
[_tableView setHeaderView:nil];
[_tableView addTableColumn:[[NSTableColumn alloc] initWithIdentifier:@"firstColumn"]];
[_tableView setDelegate:self];
[_tableView setColumnAutoresizingStyle:NSTableViewUniformColumnAutoresizingStyle];
[_tableView setBackgroundColor:[NSColor greenColor]];
NSButton* _button = [[NSButton alloc] initWithFrame:NSZeroRect];
NSView* tempView = [[NSView alloc] initWithFrame:NSZeroRect];
[tempView setTranslatesAutoresizingMaskIntoConstraints:NO];
[_scrollView setTranslatesAutoresizingMaskIntoConstraints:NO];
[_button setTranslatesAutoresizingMaskIntoConstraints:NO];
[_tableView setTranslatesAutoresizingMaskIntoConstraints:NO];
[tempView addSubview:_button];
[tempView addSubview:_tableView];
[_scrollView setDocumentView:tempView];
[self addSubview:_scrollView];
NSString *const kViewContainerVertical = @"V:|[tempView]|";
NSString *const kViewContainerHorizontal = @"H:|[tempView]|";
NSDictionary *viewDictionary = NSDictionaryOfVariableBindings(tempView);
NSArray *contraintOneView = [NSLayoutConstraint constraintsWithVisualFormat:kViewContainerVertical
options:NSLayoutFormatAlignAllLeft
metrics:nil
views:viewDictionary];
NSArray *constraintTwoView = [NSLayoutConstraint constraintsWithVisualFormat:kViewContainerHorizontal
options:NSLayoutFormatAlignAllLeft
metrics:nil
views:viewDictionary];
NSString *const kViewVertical = @"V:|[_tableView]-2-[_button]|";
NSString *const kTextViewHorizontal = @"H:|[_tableView(_button)]-0-|";
NSString *const kButtonHorizontal = @"H:|-0-[_button]-0-|";
NSDictionary *dictionary = NSDictionaryOfVariableBindings(_tableView, _button);
NSArray *contraintOne = [NSLayoutConstraint constraintsWithVisualFormat:kViewVertical
options:NSLayoutFormatAlignAllLeft
metrics:nil
views:dictionary];
NSArray *constraintTwo = [NSLayoutConstraint constraintsWithVisualFormat:kTextViewHorizontal
options:NSLayoutFormatAlignAllLeft
metrics:nil
views:dictionary];
NSArray *constraintThree = [NSLayoutConstraint constraintsWithVisualFormat:kButtonHorizontal
options:NSLayoutFormatAlignAllLeft
metrics:nil
views:dictionary];
[tempView addConstraints:contraintOne];
[tempView addConstraints:constraintTwo];
[tempView addConstraints:constraintThree];
[_scrollView.contentView addConstraints:contraintOneView];
[_scrollView.contentView addConstraints:constraintTwoView];
NSString *const kScrollVertical = @"V:|-0-[_scrollView]-0-|";
NSString *const kScrollHorizontal = @"H:|-0-[_scrollView]-0-|";
NSDictionary *scrollDictionary = NSDictionaryOfVariableBindings(_scrollView);
NSArray *contraintOneScroll = [NSLayoutConstraint constraintsWithVisualFormat:kScrollVertical
options:NSLayoutFormatAlignAllLeft
metrics:nil
views:scrollDictionary];
NSArray *constraintTwoScroll = [NSLayoutConstraint constraintsWithVisualFormat:kScrollHorizontal
options:NSLayoutFormatAlignAllLeft
metrics:nil
views:scrollDictionary];
[self addConstraints:contraintOneScroll];
[self addConstraints:constraintTwoScroll];
}
Я не понимаю причину такого поведения.
[_tableView constraintsAffectingLayoutForOrientation:NSLayoutConstraintOrientationVertical]
Возвращает
<__NSArrayI 0x608000101050>(
<NSContentSizeLayoutConstraint:0x6080000a2520 V:[NSButton:0x608000140c60'Button'(21)] Hug:250 CompressionResistance:750>,
<NSLayoutConstraint:0x608000082620 V:[NSButton:0x608000140c60'Button']-(0)-| (Names: '|':NSView:0x608000121180 )>,
<NSLayoutConstraint:0x6080000825d0 V:[NSTableView:0x1004032f0]-(2)-[NSButton:0x608000140c60'Button']>,
<NSLayoutConstraint:0x608000082da0 V:|-(0)-[JSFlippedView:0x608000160cc0] (Names: '|':NSView:0x610000120140 )>,
<NSAutoresizingMaskLayoutConstraint:0x608000081770 h=-&- v=-&- V:|-(1)-[NSClipView:0x100408c20] (Names: '|':NSScrollView:0x6080001c0000 )>,
<NSLayoutConstraint:0x608000082490 V:[NSView:0x608000121180]-(0)-| (Names: '|':NSClipView:0x100408c20 )>,
<NSLayoutConstraint:0x6080000828a0 V:[NSScrollView:0x6080001c0000]-(0)-| (Names: '|':JSFlippedView:0x608000160cc0 )>,
<NSAutoresizingMaskLayoutConstraint:0x608000082fd0 h=-&- v=-&- V:[NSView:0x610000120140]-(0)-| (Names: '|':NSThemeFrame:0x100403e30'ScrollTest-expand' )>,
<NSLayoutConstraint:0x608000082df0 V:[JSFlippedView:0x608000160cc0]-(0)-| (Names: '|':NSView:0x610000120140 )>,
<NSLayoutConstraint:0x608000082440 V:|-(0)-[NSView:0x608000121180] (Names: '|':NSClipView:0x100408c20 )>,
<NSAutoresizingMaskLayoutConstraint:0x608000081540 h=-&- v=-&- V:[NSClipView:0x100408c20]-(1)-| (Names: '|':NSScrollView:0x6080001c0000 )>,
<NSLayoutConstraint:0x608000082850 V:|-(0)-[NSScrollView:0x6080001c0000] (Names: '|':JSFlippedView:0x608000160cc0 )>,
<NSAutoresizingMaskLayoutConstraint:0x608000083200 h=-&- v=-&- V:|-(22)-[NSView:0x610000120140] (Names: '|':NSThemeFrame:0x100403e30'ScrollTest-expand' )>,
<NSLayoutConstraint:0x608000082580 V:|-(0)-[NSTableView:0x1004032f0] (Names: '|':NSView:0x608000121180 )>,
<NSLayoutConstraint:0x6000000806e0 'NSWindow-current-height' V:[NSThemeFrame:0x100403e30'ScrollTest-expand'(727@500)] priority:500>
)
а также _tableView intrinsicContentSize
дает {-1, -1}
,
1 ответ
Кажется, проблема в том, что табличное представление не имеет внутренней высоты. Следовательно, это не "толкает" границы документа, чтобы увеличить его, поэтому он прокручивается.
Я замечаю, что если я добавлю табличное представление к окну в IB, а затем скажу IB сбросить все окно (или представление клипа или представление таблицы) в соответствии с предлагаемыми ограничениями, между представлением таблицы и представлением клипа не будет никаких ограничений. Кроме того, табличное представление все еще имеет translatesAutoresizingMaskIntoConstraints
включен. Это отличается от некоторых других типов представлений в представлениях прокрутки. Итак, я думаю, что IB знает, что табличные представления не являются автоматически разбирающимися в макете.
Я полагаю, что табличное представление непосредственно в виде клипа (так как IB устанавливает его) просто использует механизм старого стиля для позиционирования и определения размера. Когда табличное представление вычисляет его размер (например, добавляется строка), оно, вероятно, просто вызывает -setFrameSize:
на себя. Просмотр клипа контролирует его кадр, наблюдая NSViewFrameDidChangeNotification
уведомление. Это не работает в вашем случае, потому что автоматическое расположение в основном игнорирует / отменяет попытки установить фрейм.
Вы можете работать с этим, но это будет рискованно. Вы бы покинули вид таблицы translatesAutoresizingMaskIntoConstraints
на, но это накладывает ограничения на то, какие ограничения вы можете установить, не вызывая конфликтов. По сути, вы не можете установить ограничения, которые налагают позицию или размер на табличное представление, но вы можете "повесить" другие представления за пределы табличного представления, если они могут свободно перемещаться или изменять размеры, чтобы табличное представление могло свободно переместить и изменить размер.
Во-первых, ваш документ просмотра (tempView
) должно быть перевернутым представлением, потому что вы захотите расположить табличное представление на его вершине, установив его фрейм, а затем оно будет изменять свой размер, устанавливая размер фрейма, и вы хотите, чтобы оно уменьшалось.
Инициируйте представление документа с рамкой с ненулевым размером. Происхождение не имеет значения.
Инициируйте табличное представление с рамкой, источник которой равен (0, 0) и имеет тот же размер, что и представление документа. Не забудьте оставить свой translatesAutoresizingMaskIntoConstraints
на.
Не ограничивайте верхнюю, переднюю или заднюю кромки табличного представления его суперпредставлением. Не ограничивайте его ширину, чтобы соответствовать кнопке. Я думаю, что другие ограничения между табличным представлением и его суперпредставлением и кнопкой в порядке. Так, kViewVertical
должен бросить первый |
, Вы должны избавиться от kTextViewHorizontal
полностью. kButtonHorizontal
Это хорошо.
Установить вид таблицы autoresizingMask
в NSViewWidthSizable
, Так как табличное представление началось с фрейма, совпадающего с границами его суперпредставления, это сохранит левый и правый края табличного представления, совпадающие с суперпредставлением. Там нет вертикальной составляющей autoresizingMask
, По сути, вы не хотите, чтобы изменения высоты суперпредставления пытались изменить высоту табличного представления. В табличном представлении можно установить собственную высоту кадра. Это переместит кнопку, потому что она ограничена основанием табличного представления, и это изменит высоту представления документа, потому что ее основание ограничено основанием кнопки.
Не ограничивайте вид документа (tempView
) к виду клипа по его нижнему краю. Это просто пытается заставить вид документа быть размером contentSize
вида прокрутки. Это обязательно предотвратит прокрутку (сделав вид прокрутки и окно увеличенным, чтобы показать весь вид документа). Скорее, представление документа изменит размер, как обсуждалось в предыдущем абзаце, и представление клипа заметит это и обновит представление прокрутки соответствующим образом.
Я думаю, что на данный момент все будет в основном работать. Я подозреваю, что когда представление прокрутки достаточно велико, чтобы отображать как кнопку, так и представление всей таблицы, они будут прикреплены к нижней части представления прокрутки, а не к вершине, которая была бы более естественной. Чтобы исправить это, используйте подкласс NSClipView
это перевернуто.