2013-11-01 2 views
3

Я занимаюсь автоматической компоновкой и узнаю о анимационных ограничениях.iOS - ограничения неожиданно отображаются в viewdidload?

Мой первый вопрос. Если я динамически добавляю представления, кажется громоздким динамически добавлять свои ограничения к родительскому представлению. Есть ли какой-либо чистый способ выполнить гибкую компоновку, где виды могут быть добавлены и удалены программно? Или это означает, что я, вероятно, должен подумать о более простом решении для того, что я пытаюсь выполнить?

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

здесь некоторый код:

first = [[UIView alloc]initWithFrame:CGRectZero]; 

[first setBackgroundColor:[UIColor blueColor]]; 

[first setTranslatesAutoresizingMaskIntoConstraints:NO]; 

[self.view addSubview:first]; 



UIView *second = [[UIView alloc]initWithFrame:CGRectZero]; 

[second setBackgroundColor:[UIColor redColor]]; 

[second setTranslatesAutoresizingMaskIntoConstraints:NO]; 

[self.view addSubview:second]; 



NSLayoutConstraint *leading = [NSLayoutConstraint constraintWithItem:first attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1 constant:20]; 

NSLayoutConstraint *trailing = [NSLayoutConstraint constraintWithItem:first attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1 constant:-20]; 


top = [NSLayoutConstraint constraintWithItem:first attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:40]; 

height = [NSLayoutConstraint constraintWithItem:first attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:80]; 

[self.view addConstraints:@[leading,trailing,top,height]]; 

[height setConstant:10]; 

[UIView animateWithDuration:0.5 animations:^{ 

    [self.view layoutIfNeeded]; 

}]; 

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

Может ли кто-нибудь объяснить это поведение. Я заметил, что если я назначу ограничения и сделаю их анимацией на IBAction (нажатие кнопки), то он будет оживлять, как ожидалось.

ответ

3

Второй вопрос первым. Почему вы оживляете изменение в viewDidLoad? На этом этапе мы знаем, что представление загружено, но оно, вероятно, не выложено и определенно не будет видимым для пользователя; рассмотрите изменения компоновки ограничений в методе viewDidLayoutSubviews.

Что касается первого вопроса. Ответ Дэвида Х является одним из способов ... и совершенно прекрасным способом. Чтобы дать другой вариант, я использую constraintsWithVisualFormat:options:metrics:views:, который позволяет мне определять представления, а затем создает все необходимые ограничения во всех представлениях. Это может быть гораздо более простой способ создания ограничений по нескольким представлениям. В зависимости от того, что вы делаете, один способ может лучше соответствовать вашим потребностям.

Редактировать на основе комментариев ...

С чем-то, где вы должны разорвать ограничения, вы все равно должны найти и разорвать ограничения, прежде чем создавать новые. Об этом нет. У вас будет либо ссылка на ограничение, которое вы хотите сломать, либо выполнить итерацию по всем ограничениям на объект, чтобы найти его. A B C переходит в A B и C, где ограничение между B и C отсутствует.Использование визуального формата для размещения в X может быть чем-то вроде @ "[B] -20- [X] -20- [C]", которое создаст ограничение для 20-точечного интервала между B и X и второе ограничение, которое будет быть 20-точечным интервалом между X и C. В качестве примечания, визуальный формат выше определяет только горизонтальное позиционирование/расстояние. Для указания вертикальных ограничений вам понадобится вторая строка.

+0

спасибо я думаю, что мне нужно играть с ним немного больше – hamobi

+0

я думаю, мой вопрос .. если им добавление мнений между другими видами .. как если у меня есть вид B C , а затем я хочу добавить случайный вид X между ними таким образом B X C тогда я должен обновить ограничение просмотра B и C, наряду с созданием препятствий для X. это кажется очень громоздким – hamobi

+0

спасибо за обновленная информация. ценить это – hamobi

2

Я делаю что-то похожее на это, и технику можно расширить. Для каждого представления (действительно, любого объекта) создайте изменяемый словарь с атрибутом «вид» и «ограничения». представление - это просто представление, ограничения - это массив словарей, содержащих два объекта, свойство «view» и свойство «ограничение».

Когда вы решите добавить или вытащить представление, найдите словарь с соответствующим свойством вида, затем перейдите по массиву ограничений и добавьте/удалите ограничение (типа NSLayerConstraint) в свойство «view» сестры в словарь.

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

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

Смежные вопросы