2013-05-21 1 views
5

Так я пытаюсь оживить некоторые ограничения макета, и я с жалким везением, я просто не вижу ничего, и тогда я получаю сообщение об ошибке, говорящее, как он не может одновременно удовлетворить все Сдерживает и т.д.Programatic NSLayoutConstraint вопросы анимации

Я использую класс под названием PullableView, чья анимация использует старый стиль [UIView commitAnimation], поэтому я подклассифицировал его и добавил в свой код для того, что, по моему мнению, будет для анимации ограничений ... Нет такой удачи и попытки оживить его или даже заставить его делать многое что-то сложно, я просто получаю «Невозможно одновременно удовлетворить ограничения». Проблема в том, что я довольно новичок в этом бизнесе с ограничениями, поэтому я не знаю, с чего начать.

вот ошибка, другая - почти такая же, но для centerY.

"<NSLayoutConstraint:0x7c8a3a0 StyledPullableView:0x905a9b0.centerX == UIView:0x9054680.centerX>", "<NSLayoutConstraint:0x7c6b480 StyledPullableView:0x905a9b0.centerX == UIView:0x9054680.centerX + 128>"

Я, конечно, сделать [pullRightView setTranslatesAutoresizingMaskIntoConstraints:NO]; перед вызовом этого

помощь оценили.

- (void)setOpenedForConstraints:(BOOL)op animated:(BOOL)anim 
{ 
    opened = op; 

    if (anim) 
    {   
     NSLayoutConstraint *constraintX = [NSLayoutConstraint constraintWithItem:self 
                       attribute:NSLayoutAttributeCenterX 
                       relatedBy:NSLayoutRelationEqual 
                        toItem:_parentView 
                       attribute:NSLayoutAttributeCenterX 
                       multiplier:1 
                       constant:0]; 

     NSLayoutConstraint *constraintY = [NSLayoutConstraint constraintWithItem:self 
                       attribute:NSLayoutAttributeCenterY 
                       relatedBy:NSLayoutRelationEqual 
                        toItem:_parentView 
                       attribute:NSLayoutAttributeCenterY 
                       multiplier:1 
                       constant:0]; 

     [_parentView addConstraint:constraintX]; 
     [_parentView addConstraint:constraintY]; 

     constraintX.constant = opened ? self.openedCenter.x : self.closedCenter.x; 
     constraintY.constant = opened ? self.openedCenter.y : self.closedCenter.y; 
    } 

    if (anim) 
    { 

     // For the duration of the animation, no further interaction with the view is permitted 
     dragRecognizer.enabled = NO; 
     tapRecognizer.enabled = NO; 

     //[UIView commitAnimations]; 

     [UIView animateWithDuration:animationDuration 
         animations:^ 
     { 
      [self layoutIfNeeded]; 
     }]; 

    } 
    else 
    { 

     if ([delegate respondsToSelector:@selector(pullableView:didChangeState:)]) 
     { 
      [delegate pullableView:self didChangeState:opened]; 
     } 
    } 
} 

ответ

11

Пара мыслей:

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

  2. При изменении существующего ограничения существуют два подхода. Один из них состоит в том, чтобы перебирать ограничения вида, находить тот, о котором идет речь, и затем корректировать для этого constant. Другой подход (и гораздо проще, когда представление является тем, которое вы добавили в Interface Builder), заключается в создании IBOutlet для ограничения в интерфейсе Builder. Тогда вы можете оживить это.

    • This answer, делая акцент на другой проблеме, иллюстрирует процесс создания IBOutlet для ограничения, а затем анимировать изменение его стоимости.

    • Если у вас есть перебирать ограничения в поисках ограничений (например, выбирая одно ограничение из целой коллекции, которые вы, возможно, созданная с визуальным языком формата, например), то replaceLeadingAndTopWithCenterConstraints показано на this answer может быть полезный пример того, как вы находите ограничение на существующее представление. В этом конкретном примере удаление ограничения и добавление нового, но вы могли бы так же легко, как только вы найдете существующее ограничение, отрегулируйте его константу.


Я не совсем уверен, что УБ вы собираетесь для, но, скажем, у вас есть панель, которую Вы хотите, чтобы соскользнуть в левой части экрана:

  1. Первый вопрос: какие ограничения вы определили: в этом примере у меня было бы четыре ограничения, три - для супервизора (а именно верхний, нижний и левый, но не справа) и ограничение ширины , И если вы делаете это в IB, это может быть очень сложно (например, вы не можете удалить правильное ограничение до тех пор, пока не добавите ограничение ширины).Просто убедитесь, что ограничения полностью определены, но минимально.

  2. Тогда я могу анимировать скольжение панели выключения экрана, просто изменив constant левого ограничения:

    - (IBAction)touchUpInsideButton:(id)sender 
    { 
        self.offscreen = !self.offscreen; 
    
        [UIView animateWithDuration:0.5 
            animations:^{ 
             self.panelLeftConstraint.constant = ([self isOffscreen] ? -kHowMuchToSlideOffToLeft : 0.0); 
             [self.view layoutIfNeeded]; 
            }]; 
    } 
    
  3. Вы можете видеть теперь, почему это важно, чтобы убедиться, что не было никакого права ограничение определено. Потому что, если бы я скорректировал левое ограничение, в то время как у меня было ограничение ширины и определенное ограничение ограничения, тогда это станет неудовлетворительным. Убедившись, что ограничения были минимально определены (хотя однозначно определены) в начале, я могу изменить левое ограничение, и представление теперь оживляет, как я этого хотел.

+0

Спасибо за ответ, я буду копаться через них ... Я также удалить все ограничения, прежде чем добавлять новые ... Хотя я это сделать в функции инициализации ... – Genhain

+1

@Genhain Я думаю, что это гораздо легче изменить ограничения, чем добавлять и удалять. И будьте очень осторожны, какие ограничения вы определили для представления в первую очередь. Например, если бы я собирался сдвинуть его влево, я бы определил его сверху, снизу, слева и ширине (но не правильно!), А затем я смогу анимировать, изменив константу левого ограничения , См. Пересмотренный ответ. Должен признаться, что я не смог расшифровать то, что ваш желаемый UX был из вашего образца кода, поэтому, если вы уточните, что вы пытаетесь выполнить, я мог бы быть более полезным. – Rob

+0

Отличный ответ, но точка 2 в вашем первом списке неверна. В блоке анимации должен находиться только layoutIfNeeded. – jrturton

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