Представления не отображаются правильно после добавления их в NSStackView программным путем

Я пытаюсь добавить некоторые представления (NSTextField в этом примере) в NSStackView:

Я добавил экземпляр NSStackView в файл XIB, связал его с выходом как виджеты в Документ. В ...didLoadNib я делаю следующее:

NSTextField *tf = [[NSTextField alloc] init];
tf.stringValue = @"124";
[tf setFrameSize:NSMakeSize(100, 20)];
[widgets addView:tf inGravity:NSStackViewGravityLeading];
NSLog(@"%f - %d", NSHeight(tf.frame), [tf hasAmbiguousLayout]);

NSTextField *tf2 = [[NSTextField alloc] init];
tf2.stringValue = @"123";
[tf2 setFrameSize:NSMakeSize(100, 20)];
[widgets addView:tf2 inGravity:NSStackViewGravityLeading];
NSLog(@"%f - %d", NSHeight(tf2.frame), [tf2 hasAmbiguousLayout]);

TextField помещаются в StackView, но они размещаются в одном и том же месте, т.е. второе полностью перекрывает первое. Я по-прежнему могу выбрать первый с помощью [пробел+таб].

Вот вывод консоли:

2015-06-13 17:11:00.736 celty-test[62306:9217679] 20.000000 - 1
2015-06-13 17:11:00.739 celty-test[62306:9217679] Unable to simultaneously satisfy constraints:
(
    "<NSLayoutConstraint:0x608000084bf0 V:[NSStackViewSpacer:0x6080001834d0(>=8)]>",
    "<NSLayoutConstraint:0x608000084f10 V:[NSTextField:0x608000183330]-(0)-[NSStackViewSpacer:0x6080001834d0]>",
    "<NSLayoutConstraint:0x608000085460 V:[NSStackViewSpacer:0x6080001834d0]-(0)-[NSTextField:0x608000183400]>",
    "<NSAutoresizingMaskLayoutConstraint:0x608000084970 h=--& v=--& V:[NSTextField:0x608000183330]-(0)-|   (Names: '|':NSStackViewContainer:0x6000001a0700 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x608000084d30 h=--& v=--& V:[NSTextField:0x608000183400]-(0)-|   (Names: '|':NSStackViewContainer:0x6000001a0700 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x608000084d80 h=--& v=--& V:[NSTextField:0x608000183400(20)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x608000084bf0 V:[NSStackViewSpacer:0x6080001834d0(>=8)]>

Set the NSUserDefault NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints to YES to have -[NSWindow visualizeConstraints:] automatically called when this happens.  And/or, break on objc_exception_throw to catch this in the debugger.
2015-06-13 17:11:00.802 celty-test[62306:9217679] Unable to simultaneously satisfy constraints:
(
    "<NSLayoutConstraint:0x608000084f10 V:[NSTextField:0x608000183330]-(0)-[NSStackViewSpacer:0x6080001834d0]>",
    "<NSLayoutConstraint:0x608000085460 V:[NSStackViewSpacer:0x6080001834d0]-(0)-[NSTextField:0x608000183400]>",
    "<NSAutoresizingMaskLayoutConstraint:0x608000084970 h=--& v=--& V:[NSTextField:0x608000183330]-(0)-|   (Names: '|':NSStackViewContainer:0x6000001a0700 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x608000084d30 h=--& v=--& V:[NSTextField:0x608000183400]-(0)-|   (Names: '|':NSStackViewContainer:0x6000001a0700 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x608000084d80 h=--& v=--& V:[NSTextField:0x608000183400(20)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x608000085460 V:[NSStackViewSpacer:0x6080001834d0]-(0)-[NSTextField:0x608000183400]>

Set the NSUserDefault NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints to YES to have -[NSWindow visualizeConstraints:] automatically called when this happens.  And/or, break on objc_exception_throw to catch this in the debugger.
2015-06-13 17:11:00.814 celty-test[62306:9217679] 20.000000 - 0

Скриншоты XIB и результатов: XIB

результат

В StackView не добавляются ограничения. StackView должен быть вертикальным. В stackview будет добавлено динамическое количество текстовых полей.


person ShadowPrince    schedule 13.06.2015    source источник
comment
Есть ли ограничения на виджеты? У вас есть гравитация, устанавливающая оба текстовых поля в нижней части виджета, и ваш отладчик выглядит так, как будто вы добавили интервал между текстовыми полями, но они должны быть закреплены сверху-внизу виджета, если вы хотите виджет изменяемого размера. Нравится "V:|[tf]-8-[tf2]|"   -  person Tim    schedule 13.06.2015
comment
Я не добавлял никаких ограничений ни в ScrollView, ни в текстовые поля.   -  person ShadowPrince    schedule 13.06.2015


Ответы (1)


Вам необходимо установить для свойства translatesAutoresizingMaskIntoConstraints текстовых полей значение false.

Обычно вы не должны этого делать, если представление размещается каким-то другим кодом. То есть вы ожидаете, что представление стека решит, должно ли это свойство быть включено или выключено, потому что оно контролирует размещение его в иерархии представлений. Однако в NSStackView есть ошибка, связанная с этим вплоть до 10.10, поэтому вам нужно отключить ее самостоятельно.

Подсказка заключается в том, что множество невыполнимых ограничений включает ограничения типа NSAutoresizingMaskLayoutConstraint.

person Ken Thomases    schedule 13.06.2015
comment
Спасибо любезно. Только второй день в Cocoa, а уже обнаружена ошибка. - person ShadowPrince; 13.06.2015
comment
Похоже, это исправлено в версии 10.11, где NSStackView для добавленных представлений установлено значение false. - person Taylor; 15.06.2015
comment
Большое спасибо! Я только что потратил часы, пытаясь заставить это работать, и это исправило это. Как ни странно, у меня есть другое представление стека с той же настройкой, и оно отлично работает без этого... - person DanielGibbs; 25.06.2015
comment
Представления не верхнего уровня в NIB/раскадровке, использующие автоматическое расположение, translatesAutoresizingMaskIntoConstraints отключены IB. В основном проблемы возникают с представлениями, созданными программно, хотя это также могут быть представления верхнего уровня из NIB/раскадровки или представления из NIB/раскадровки, которые не настроены на использование автоматического макета. - person Ken Thomases; 25.06.2015