У меня есть вертикальный NSStackView с таким поведением. Он имеет два подпредставления, одно из которых находится в верхней части представления стека, которое будет иметь фиксированную высоту. Затем есть еще одно представление, которое будет охватывать оставшееся пространство в представлении. Подобно изображению ниже. Мой текущий код уже отображает представление, как показано ниже:
Я хочу иметь поведение, при котором, когда я скрываю вид сверху или ViewA, ViewB принимает высоту всего представления стека. Как это изображение:
Я делаю это программно, но когда я устанавливаю ViewA как скрытый, ViewB не занимает все доступное пространство. Оставив пространство ViewA там.
Мой текущий код уже показывает пользовательский интерфейс, как на первом изображении, и это:
@interface CutsomStackView : NSSTackView
@property (nonatomic) NSView *viewA;
@property (nonatomic) NSView *viewB;
- (id)initWithFrame:(NSRect)frame views:(NSArray<NSView *> *)views;
@end
@implementation CutsomStackView
- (id)initWithFrame:(NSRect)frame views:(NSArray<NSView *> *)views
{
if (!(self = [super initWithFrame:frame]))
return nil;
_viewA = views[0];
_viewB = views[1];
self.detachesHiddenViews = YES;
self.orientation = NSUserInterfaceLayoutOrientationVertical;
self.spacing = 0;
self.distribution = NSStackViewDistributionFill;
CGFloat viewAHeight = NSHeight(_viewA.frame);
[self addSubview:_viewA];
[self addSubview:_viewB];
_viewA.translatesAutoresizingMaskIntoConstraints = NO;
_viewB.translatesAutoresizingMaskIntoConstraints = NO;
NSDictionary *views = @{
_viewA,
_viewB
};
NSDictionary *metrics = @{
@"viewAHeight": @(viewAHeight)
};
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:UNLOCALIZED_STRING("V:|[_viewA(viewAHeight)][_viewB]|") options:NSLayoutFormatAlignAllLeading | NSLayoutFormatAlignAllTrailing metrics:metrics views:views]];
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:UNLOCALIZED_STRING("H:|[_viewA]|") options:0 metrics:nil views:views]];
return self;
}
@end
Я не уверен, что мне нужно добавить, чтобы ViewB увеличивался в размерах, когда ViewA скрыт.
Кроме того, после того, как я скрою viewB, я вызову метод layoutSubtreeIfNeeded
.
Нужно ли добавлять нижнее и верхнее ограничения в topView
?
Извините, вы имеете в виду, что мне нужно добавить ограничения верхней и нижней привязки представления B относительно его суперпредставления?
ViewA нуждается в верхнем ограничении с фиксированным значением. ViewB нуждается в нижнем ограничении с фиксированным значением.
Как насчет моих текущих ограничений макета, следует ли их удалить? Я не понимаю, почему viewB нужно только нижнее ограничение и никакое другое сверху.
viewA нуждается в нижнем ограничении viewB с фиксированным значением. viewB нуждается в верхнем ограничении viewA с фиксированным значением.
Ваш подход даже не работает. Это фактически сломало пользовательский интерфейс. Я снял свои ограничения и просто ушел [_viewB constraintEqualToAnchor:_viewA.bottomAnchor constant:0].active = YES; [_viewA.bottomAnchor constraintEqualToAnchor:_viewB.topAnchor constant:0].active = YES;
В итоге проблема заключалась в трех разных вещах:
-[NSStackView addSubView:]
вместо -[NSStackView addArrangedSubview:]
Фиксированный код:
@interface CutsomStackView : NSSTackView
@property (nonatomic) NSView *viewA;
@property (nonatomic) NSView *viewB;
- (id)initWithFrame:(NSRect)frame views:(NSArray<NSView *> *)views;
@end
@implementation CutsomStackView
- (id)initWithFrame:(NSRect)frame views:(NSArray<NSView *> *)views
{
if (!(self = [super initWithFrame:frame]))
return nil;
_viewA = views[0];
_viewB = views[1];
self.detachesHiddenViews = YES;
self.orientation = NSUserInterfaceLayoutOrientationVertical;
self.spacing = 0;
self.distribution = NSStackViewDistributionFill;
CGFloat viewAHeight = NSHeight(_viewA.frame);
[self addArrangedSubview:_viewA];
[self addArrangedSubview:_viewB];
_viewA.translatesAutoresizingMaskIntoConstraints = NO;
[_viewA setContentHuggingPriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationVertical];
[_viewA.heightAnchor constraintEqualToConstant:topBarViewHeight].active = YES;
_viewB.translatesAutoresizingMaskIntoConstraints = NO;
[_viewB setContentHuggingPriority:NSLayoutPriorityDefaultLow forOrientation:NSLayoutConstraintOrientationVertical];
return self;
}
@end
Вам просто нужно установить верхнее и нижнее ограничения.