Как скрыть UIView, который не помещается в доступном пространстве?

Существует представление стека с 4 элементами.

Каждый элемент имеет приоритет сопротивления горизонтальному сжатию содержимого 1000, кроме одного:

A(1000) - B(1000) - C(999) - D(1000)

С большим пространством проблем нет, каждый вид занимает то, что ему нужно. Но когда пространство ограничено, вид C первым сжимается по горизонтали, чтобы дать место другим.

Он может сжиматься до тех пор, пока не станет невидимым:

A(1000) - B(1000) - - D(1000)

Но, несмотря на невидимость, расстояние между B и D в два раза больше, чем расстояние между A и B. Потому что C не спрятался, а просто уменьшился.

Есть ли способ обнаружить, что вид был сжат?, чтобы его можно было действительно скрыть.

PD: это представление находится внутри UITableViewCell, а не внутри UIViewController. В ячейке нет метода didLayoutSubviews, я пытался сделать это в layoutSubviews:

- (void)layoutSubviews
{
    [super layoutSubviews];
    // Truly hide it if is not visible anymore because there is no space.
    self.view.hidden = self.view.frame.size.width == 0;
}

Но это не сработало, есть идеи?

Ваши 4 «элемента» имеют фиксированную ширину? Или их ширина динамическая? Ограничена ли ширина представления стека? Проблема в том, что... Если C сократится до нуля, и вы его скроете, а также уберете пробел - C теперь будет больше места и больше не будет нулем... так что вы покажете его, но это добавит дополнительное пространство, так что оно сократится до нуля... и вы в бесконечном цикле. Покажите, как вы устанавливаете ширину элементов. Я думаю, вам может понадобиться выполнить некоторые вычисления, а не использовать представление стека.

DonMag 18.12.2020 21:35
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
1
472
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Как насчет этого.

Код приведен ниже. Это всего лишь пример, и он требует правильной настройки раскадровки.

@interface ViewController ()

@property (weak, nonatomic) IBOutlet NSLayoutConstraint * trailingConstraint;
@property (weak, nonatomic) IBOutlet UIView             * blackView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * blackViewTrailingConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint * blackViewWidthConstraint;

@property (nonatomic) BOOL preventLoop;

@end

@implementation ViewController

- (void)viewDidLoad {

    super.viewDidLoad;

    [self.blackView addObserver:self
             forKeyPath:@"bounds"
                options:0
                context:nil];

}

- ( void ) observeValueForKeyPath: ( NSString     * ) keyPath
             ofObject: ( id             ) object
               change: ( NSDictionary * ) change
              context: ( void         * ) context
{
    if ( ! self.preventLoop ) {

        self.preventLoop = YES;

        if ( self.blackView.bounds.size.width < 10 ) {

            self.blackViewWidthConstraint.constant = 0;
            self.blackViewTrailingConstraint.constant = 0;

        } else {

            self.blackViewTrailingConstraint.constant = 40;

        }

        self.preventLoop = NO;

    }

}

- (IBAction)squashButtonAction:(id)sender {

    self.trailingConstraint.constant += 10;
    self.blackViewWidthConstraint.constant = MAX ( 0, self.blackViewWidthConstraint.constant - 10 );

}

- (IBAction)resetButtonAction:(id)sender {

    self.trailingConstraint.constant = 20;
    self.blackViewWidthConstraint.constant = 150;

}

@end

Идея состоит в том, чтобы использовать наблюдение за значением ключа, чтобы определить, когда размер границ становится ниже порогового значения; 10 в данном случае. Когда это произойдет, соответствующий вид (черный здесь) будет иметь как ширину, так и замыкающее ограничение, установленное на 0. Ширина здесь очевидна, а замыкающее ограничение — это пространство между черным представлением и последним желтым представлением. Это делается для того, чтобы вы не получили двойное пространство.

Поскольку вы изменяете значение внутри наблюдателя, вам нужна некоторая логика, чтобы предотвратить его зацикливание, как вы можете видеть в коде.

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

РЕДАКТИРОВАТЬ

Есть много способов содрать шкуру с кошки... вот еще одна, еще более простая идея. Это смешивает идеи как из вашей первоначальной попытки, так и из моего первоначального ответа. Вместо использования наблюдателя вы можете сделать то же самое в одном из сообщений макета, как показано ниже.

Я думаю, что большая разница между вашей попыткой и тем, что я предлагаю, заключается в том, чтобы просто добавить конечное ограничение (blackViewTrailingConstraint в моем коде), а затем использовать его, чтобы сжать конечный пробел до 0 в нужное время.

Во всяком случае, вот код для выполнения того же без наблюдателя

- ( void ) viewWillLayoutSubviews {

    // you could also use ...

    // if ( self.blackView.bounds.size.width < 5 ) {

    // ... here but it is more correct to use the width
    // constaint and not the actual width here as you
    // and set the constaint and the width only updates
    // once layout completes
    if ( self.blackViewWidthConstraint.constant < 5 ) {

        self.blackViewWidthConstraint.constant = 0;
        self.blackViewTrailingConstraint.constant = 0;
        
    } else {

        self.blackViewTrailingConstraint.constant = 40;

    }

}

Привет, скаак, я не могу сейчас попробовать твой код. Попробую на следующей неделе (у меня отпуск). Большое спасибо за ваш ответ :-)

Sergio 22.12.2020 20:12

@Серджио, с праздником! Это хорошо, я немного подумал и обновил свой ответ.

skaak 23.12.2020 12:02

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