2015-01-16 2 views
8

Добрый день, друзья!iOS: программно изменяющиеся ограничения, установленные от Interface Builder

Мне не удалось анимировать представления, которые были установлены в IB из кода. App падает с следующей причине:

Иерархия зрения не готова к ограничению ...

Я видел несколько подобных вопросов здесь, и причина всегда, что вид, который был создан программно, это было еще не добавлено в супервизор. Но я создал все взгляды в IB!

Консоль также говорит:

Просмотр не найден в контейнере иерархии: (здесь идет это SuperView)

Это не имеет никакого смысла для меня, потому что на самом деле это subview соответствующего надзора, и xcode знает это - он печатает иерархию представлений сразу и подходит.

В чем причина? Спасибо!

Edit: код я использую:

- (void)setEditingConstraintsForView:(UIView *)view 
{ 
    // Pin given view to top, fix it height 
    NSDictionary *givenView = @{@"view":view}; 
    view.translatesAutoresizingMaskIntoConstraints = NO; 

    NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|" options:0 metrics:nil views:givenView]; 
    NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view(height)]" options:0 metrics:@{@"height":@(viewHeight)} views:givenView]; 

    [self.animatedVIew addSubview:view]; 

    for (NSArray *constraints in @[horizontalConstraints, verticalConstraints]) { 
     [view addConstraints:constraints]; 
    } 
} 

Также я удалить все ограничения, которые я установил в IB перед установкой нового:

- (NSDictionary *)constraintsFromIB 
{ 
    if (!_constraintsFromIB) { 
     _constraintsFromIB = @{@"view1":self.view1.referencingConstraintsInSuperviews, 
           @"view2":self.view2.referencingConstraintsInSuperviews, 
           @"view3":self.view3.referencingConstraintsInSuperviews }; 
    } 

    return _constraintsFromIB; 
} 

И потом:

- (void)updateViewConstraints 
{ 
    [super updateViewConstraints]; 

    // clear all constraints 
    for (NSString *viewName in self.constraintsFromIB.allKeys) { 
     for (NSLayoutConstraint *constraint in self.constraintsFromIB[viewName]) { 
      [constraint remove]; 
      } 

} }

UPDATE 2: Метод я использую вызывать изменения: когда пользователь прикасается взгляд, это одна называется:

- (void)animateConstraintsForState:(LDYEditingLabel)state 
{ 
    self.editingLabel = state;   
    [UIView animateWithDuration:0.3 animations:^{ 
     [self updateViewConstraints]; 
     [self.view layoutIfNeeded]; 
    }]; 
} 

Позже в updateViewConstraints: есть код, который вызывает мой метод setEditingConstraintsForView:(UIView *)view

+0

Можете ли вы показать код? – Paulw11

+0

С каким методом вы вызываете этот код? 'ViewDidAppear'? 'ViewDidAppear'? или какой-либо другой метод? – Paulw11

+0

Просто добавлено другое редактирование. Он запускается из крана на экране с помощью блока анимации. –

ответ

22

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

Затем вы обновляете ограничение и вызываете [self updateViewConstraints]; в анимации блок

enter image description here

+0

Спасибо за ответ, что определенно сработает. Но что, если у меня было бы много ограничений, чтобы это можно было бы сделать? Мне нужны представления, чтобы они появлялись и исчезали, меняли места на экране и так далее. Я думаю, что если я создаю выход для каждого ограничения - реализация контроллера представления будет ужасным беспорядком –

+0

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

2

Если бы это было, я бы телеграфировать ограничения на IBOutlets и просто модифицировать существующие ограничения. Вероятно, это будет легче, чем добавлять и удалять их программно.

Вам также может потребоваться позвонить setNeedsLayout после того, как вы изменили ограничения.

+0

Спасибо за совет! Он отлично работает. Но причина, по которой я пытался сделать это программно, заключается в том, что у меня есть много разных взглядов на изменение ограничений. В какой-то момент мне нужно, чтобы все виды исчезали с экрана и отображали новые - datePicker, в частности, и несколько пользовательских элементов управления. И чем он должен вернуться в прежнее состояние. Что бы вы сделали в такой ситуации? Еще раз спасибо! –

+0

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

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