NSStackView, заполнение представления, когда одно из подпредставлений скрыто

У меня есть вертикальный 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.

Вам просто нужно установить верхнее и нижнее ограничения.

El Tomato 20.12.2020 06:33

Нужно ли добавлять нижнее и верхнее ограничения в topView?

Jacobo 20.12.2020 06:34

Извините, вы имеете в виду, что мне нужно добавить ограничения верхней и нижней привязки представления B относительно его суперпредставления?

Jacobo 20.12.2020 06:40

ViewA нуждается в верхнем ограничении с фиксированным значением. ViewB нуждается в нижнем ограничении с фиксированным значением.

El Tomato 20.12.2020 06:50

Как насчет моих текущих ограничений макета, следует ли их удалить? Я не понимаю, почему viewB нужно только нижнее ограничение и никакое другое сверху.

Jacobo 20.12.2020 06:52

viewA нуждается в нижнем ограничении viewB с фиксированным значением. viewB нуждается в верхнем ограничении viewA с фиксированным значением.

El Tomato 20.12.2020 06:54

Ваш подход даже не работает. Это фактически сломало пользовательский интерфейс. Я снял свои ограничения и просто ушел [_viewB constraintEqualToAnchor:_viewA.bottomAnchor constant:0].active = YES; [_viewA.bottomAnchor constraintEqualToAnchor:_viewB.topAnchor constant:0].active = YES;

Jacobo 20.12.2020 07:07
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
302
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В итоге проблема заключалась в трех разных вещах:

  1. Использование -[NSStackView addSubView:] вместо -[NSStackView addArrangedSubview:]
  2. Использование ограничения для правильной организации представлений.
  3. Огромный приоритет просмотров.

Фиксированный код:

@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

Другие вопросы по теме