2014-09-02 2 views
29

только начал изучать строитель IOS AutoLayout, интерфейс очень прямо вперед, но когда я пытаюсь архивировать то же самое по кодуAutoLayout, Невозможно одновременно удовлетворяют ограничениям

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(==2)-[_nextKeyboardButton]-(==2)-[_numPadButton]-(==2)-[_spaceButton]-(==2)-[_returnButton]-(==2)-|" options:0 metrics:0 views:NSDictionaryOfVariableBindings(_nextKeyboardButton,_numPadButton,_spaceButton,_returnButton)]]; 

это вызывает исключение,

Невозможно одновременно удовлетворить ограничения.

Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
"<NSLayoutConstraint:0x6000000966c0 H:|-(2)-[UIButton:0x7fe4f1d1c760'Next'] (Names: '|':UIInputView:0x7fe4f1f04d00)>", 
"<NSLayoutConstraint:0x600000096710 H:[UIButton:0x7fe4f1d1c760'Next']-(2)-[UIButton:0x7fe4f1d1d1d0'123']>", 
"<NSLayoutConstraint:0x600000096760 H:[UIButton:0x7fe4f1d1d1d0'123']-(2)-[UIButton:0x7fe4f1d1d6f0'Space']>", 
"<NSLayoutConstraint:0x6000000967b0 H:[UIButton:0x7fe4f1d1d6f0'Space']-(2)-[UIButton:0x7fe4f1d1d8d0'Return']>", 
"<NSLayoutConstraint:0x600000096800 H:[UIButton:0x7fe4f1d1d8d0'Return']-(2)-| (Names: '|':UIInputView:0x7fe4f1f04d00)>", 
"<NSLayoutConstraint:0x600000096e40 'UIView-Encapsulated-Layout-Width' H:[UIInputView:0x7fe4f1f04d00(0)]>" 
) 

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6000000967b0 H:[UIButton:0x7fe4f1d1d6f0'Space']-(2)-[UIButton:0x7fe4f1d1d8d0'Return']> 

Все 4 кнопки .translatesAutoresizingMaskIntoConstraints = NO;

Интересно, что не так? помощь очень ценится :)

FYI: Я работаю на iOS8 SDK

+1

Кажется, это совершенно логичный набор ограничений. Я пробивал себе голову над чем-то подобным за последние несколько Дней. Btw, @Chamira Fernando есть ли другие ограничения ширины на кнопках? Внутренний размер контента и т. Д.? Вы пытались установить для параметра compressionResistancePriority или contentHuggingPriority значение high или low? Просто посмотрите, что произойдет? –

+3

Причина неудачи ограничения, очевидно, вызвана шириной 'UIView-Encapsulated-Layout-Width' равной 0. Где находится' UIInputView'? –

+0

Глупый я - я этого не видел (0). Я была такая же проблема. Это UIInputView, предоставляемый UIInputViewController - корневым представлением расширения клавиатуры (iOS8). Я не знаю, почему он хотел бы ширину 0, учитывая поведение по умолчанию (согласно документам), нужно придерживаться ширины экрана. –

ответ

2

По вашему вопросу, что я понял, что вы создали контроль в СИБ, и вы сразу пытаетесь изменить это ограничения из вашего класса.

Здесь вы можете установить ограничения в nib для контроллера вида, а затем связать его с вашим классом и использовать объекты ограничений. Или вы можете создавать представление программно и напрямую устанавливать ограничения.

// Вам также нужно проверить, нужно ли вам переводитьAutoresizingMaskIntoConstraints, если «ДА - супервизор вида смотрит на маску авторезиста представления, создает ограничения, которые ее реализуют, и добавляет эти ограничения к себе (супервизор). »и если„нЕТ -. SuperView мнение, в не смотрит на автоматического изменения маски зрения, и не вызывает трудностей, которые реализуют его“

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

 [_nextKeyboardButton setTranslatesAutoresizingMaskIntoConstraints:YES]; 
    _numPadButton.translatesAutoresizingMaskIntoConstraints = YES; 
    [_numPadButton updateConstraints]; 
    [_nextKeyboardButton updateConstraints]; 

    NSArray *constraints2 = [NSLayoutConstraint 
          constraintsWithVisualFormat:@"H:|-57-[_nextKeyboardButton(96)]" 
          options:0 
          metrics:nil 
          views:NSDictionaryOfVariableBindings(_nextKeyboardButton)]; 

    [self.view addConstraints:constraints2]; 

    NSArray *constraints4 = [NSLayoutConstraint 
          constraintsWithVisualFormat:@"V:|-123-[_nextKeyboardButton(30)]" 
          options:0 
          metrics:nil 
          views:NSDictionaryOfVariableBindings(_nextKeyboardButton)]; 

    [self.view addConstraints:constraints4]; 

    NSArray *constraints1 = [NSLayoutConstraint 
          constraintsWithVisualFormat:@"H:|-207-[_numPadButton(58)]" 
          options:0 
          metrics:nil 
          views:NSDictionaryOfVariableBindings(_numPadButton)]; 

    [self.view addConstraints:constraints1]; 

    NSArray *constraints3 = [NSLayoutConstraint 
          constraintsWithVisualFormat:@"V:|-123-[_numPadButton(30)]" 
          options:0 
          metrics:nil 
          views:NSDictionaryOfVariableBindings(_numPadButton)]; 

    [self.view addConstraints:constraints3]; 

// Create Controls or view programmatically. 

UILabel *label = [UILabel new]; 
    label.text = @"This is a Label"; 
    label.font = [UIFont systemFontOfSize:18]; 
    label.backgroundColor = [UIColor lightGrayColor]; 
    label.translatesAutoresizingMaskIntoConstraints = NO; 
    [self.view addSubview:label]; 

    NSArray *constraints = [NSLayoutConstraint 
          constraintsWithVisualFormat:@"V:|-offsetTop-[label(100)]" 
          options:0 
          metrics:@{@"offsetTop": @100} 
          views:NSDictionaryOfVariableBindings(label)]; 
    [self.view addConstraints:constraints]; 

    UIView *spacer1 = [UIView new]; 
    spacer1.translatesAutoresizingMaskIntoConstraints = NO; 
    [spacer1 setBackgroundColor:[UIColor redColor]]; 
    [self.view addSubview:spacer1]; 

    UIView *spacer2 = [UIView new]; 
    spacer2.translatesAutoresizingMaskIntoConstraints = NO; 
    [spacer2 setBackgroundColor:[UIColor greenColor]]; 
    [self.view addSubview:spacer2]; 

    NSArray *constraints1 = [NSLayoutConstraint 
          constraintsWithVisualFormat:@"V:|-offsetTop-[spacer1(100)]" 
          options:0 
          metrics:@{@"offsetTop": @100} 
          views:NSDictionaryOfVariableBindings(spacer1)]; 

    [self.view addConstraints:constraints1]; 

    NSArray *constraints2 = [NSLayoutConstraint 
          constraintsWithVisualFormat:@"V:|-offsetTop-[spacer2(100)]" 
          options:0 
          metrics:@{@"offsetTop": @100} 
          views:NSDictionaryOfVariableBindings(spacer2)]; 

    [self.view addConstraints:constraints2]; 

    [self.view addConstraints:[NSLayoutConstraint 
           constraintsWithVisualFormat:@"H:|[spacer1]-10-[label]-20-[spacer2(==spacer1)]|" 
           options:0 
           metrics:nil 
           views:NSDictionaryOfVariableBindings(label, spacer1, spacer2)]]; 

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

https://developer.apple.com/library/mac/documentation/userexperience/conceptual/AutolayoutPG/AutoLayoutConcepts/AutoLayoutConcepts.html#//apple_ref/doc/uid/TP40010853-CH14-SW1 Вы также можете ссылаться на ссылку яблока на углубленное исследование, и если вы все еще сталкиваетесь с проблемой, я постараюсь, чтобы мой уровень лучше всего разрешил вам проблему.

8

Мне пришлось бороться с подобной проблемой, когда я пытался вручную создать все ограничения автоматического макета (в Swift, используя Snappy - порт масонства для Swift) в контроллере представления, который основан на раскадровке.

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

Я решил это следующим образом:

  • Открывают вы обработки на Раскадровка контроллер.

  • Выберите контроллер просмотра и выберите Редактора> Resolve вопросов Автокомпоновки> Всех Представления в [] View Controller> Добавить отсутствующие сдерживающие из меню:

enter image description here

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

  • Выбрать все ограничения из вашего контроллера вида:

enter image description here

  • Проверка правой панели следующее флажков: Заполнителя - Удалить во время сборки:

enter image description here

Теперь вы можете добавить все ограничения автоматической компоновки вручную в код.

+1

Это отлично разобрало проблему. – aframe

+0

Я столкнулся с аналогичной проблемой, у меня семь UIButtons, выровненных в строке. В StoryBoard все в порядке, но когда я его создаю, я получил много исключений «Невозможно одновременно удовлетворить ограничения», но он отлично выглядит на симуляторе. Мне интересно, нужно ли мне что-то делать с ними или нет? И если я это сделаю, я не могу использовать редактор для решения проблем ограничения, потому что в моем StoryBoard их нет. – Liumx31

77

Самый простой способ, как найти невыполнимых ограничения:

  • установить уникальный идентификатор для каждого ограничения на ваш взгляд:

enter image description here

  • создать простое расширение для NSLayoutConstraint:

СВИФТ:

extension NSLayoutConstraint { 

    override public var description: String { 
     let id = identifier ?? "" 
     return "id: \(id), constant: \(constant)" //you may print whatever you want here 
    } 
} 

Objective-C

@interface NSLayoutConstraint (Description) 

@end 

@implementation NSLayoutConstraint (Description) 

-(NSString *)description { 
    return [NSString stringWithFormat:@"id: %@, constant: %f", self.identifier, self.constant]; 
} 

@end 
  • строить его еще раз, и теперь у вас есть более читаемым выход для вас:

enter image description here

  • как только вы получили ваш id вы можете просто нажмите на него в вашем Найти Навигатор:

enter image description here

  • и быстро найти его:

enter image description here

КАК УСТРАНЕНИЕ НЕИСПРАВНОСТЕЙ?

  • попытка изменить приоритет к 999 для разбитого ограничения.

Смотрите соответствующий ответ здесь: Unable to simultaneously satisfy constraints, will attempt to recover by breaking constraint

+9

невероятный совет. – Fattie

+1

Это самая полезная вещь, которую я когда-либо читал для устранения проблем с ограничениями. Руки вниз. Спасибо! – Xeaza

+0

ty, эта работа хорошая –

3

Это может быть не так difficult.The вывод на консоль сообщение говорит, что ограничения на UIButton в redefined.It означает просто нравится, что вы помещаете ограничение, ограничить Height и Width кнопки, но, без необходимости, вы наложили еще одно ограничение на то, что кнопка имеет Aspect Ratio. В этом состоянии Xcode не может убедиться, какое ограничение необходимо выполнить, чтобы вы могли видеть это сообщение отладки в консоли.

Есть два Полезные для меня пути:

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

2.Если вы используете storyboard или Xib, выберите ограничение -> Показать инспектор атрибутов -> измените приоритет некоторых ограничений.


Еще одна вещь ...

Вы можете следить за article Джейсона Джарретт. Добавьте контрольную точку символа, чтобы убедиться, что вид ошибки вызывает ошибку.

1

В случае, если кто-то работает в этом простой способ визуально проверить проблем с ограничениями этот сайт (это очень полезно!):

http://www.wtfautolayout.com

Вот проекту GitHub в случае, если сайт снижается: https://github.com/johnpatrickmorgan/wtfautolayout

+0

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