Я создал пользовательский UIView
, который я использую для отображения UIToolbar
и UIPickerView
. Я пытаюсь сделать его очень многоразовым, поэтому я создаю весь пользовательский интерфейс в коде, включая ограничения установки.Autolayout «конфликтующие ограничения»
Вот кусок метода, который я использую, чтобы установить представление для добавления в другое представление, а затем анимировать элементы управления вверх на вид снизу.
Мое мнение иерархия выглядит следующим образом:
"Owner" view (view to which this view is added):<br>
|-->"Background" view (set to the full size of "Owner", but mainly used as a dimmed background)<br>
|-->"Container" view (view which holds the toolbar and picker)
|--> Toolbar
|--> Picker
Вот код, я использую для настройки пользовательского интерфейса:
- (void)prepareForView:(UIView *)view {
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
[containerView setTranslatesAutoresizingMaskIntoConstraints:NO];
self.containerView = containerView;
UIPickerView *picker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 162.0f)];
[picker setTranslatesAutoresizingMaskIntoConstraints:NO];
self.picker = picker;
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 44.0f)];
[toolbar setTranslatesAutoresizingMaskIntoConstraints:NO];
UIBarButtonItem *done = ...;
UIBarButtonItem *flexSpace = ...;
UIBarButtonItem *cancel = ...;
toolbar.items = @[done, flexSpace, cancel];
[containerView addSubview:picker];
[containerView addSubview:toolbar];
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[picker]|" options:NSLayoutFormatAlignAllBaseline metrics:nil views:NSDictionaryOfVariableBindings(picker)]];
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[toolbar]|" options:NSLayoutFormatAlignAllBaseline metrics:nil views:NSDictionaryOfVariableBindings(toolbar)]];
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[toolbar(==44)][picker(==162)]|" options:NSLayoutFormatAlignAllLeading metrics:nil views:NSDictionaryOfVariableBindings(toolbar, picker)]];
[containerView layoutIfNeeded];
[self addSubview:containerView];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[containerView]|" options:NSLayoutFormatAlignAllBaseline metrics:nil views:NSDictionaryOfVariableBindings(containerView)]];
self.containerTop = [NSLayoutConstraint constraintWithItem:containerView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0f constant:self.frame.size.height];
[self addConstraint:self.containerTop];
[self layoutIfNeeded];
}
В принципе, я хочу containerView
быть размером в соответствии с его содержимым (что должен быть статичным 206 баллов). Затем я устанавливаю вертикальное ограничение пространства между его вершиной и вершиной своего супервизора (self
). Позже я изменяю это так, чтобы панель инструментов и сборщик «скользнули вверх» на экран.
Вот код анимации (ошибка всегда срабатывает до этого момента):
// Add the view as a subview
[view addSubview:self];
// Setup view for display (here's what triggers the message)
[self prepareForView:view];
// Animate into view
[UIView animateWithDuration:animated?0.4f:0.0f
animations:^{
self.alpha = 1.0f;
}
completion:^(BOOL finished) {
// Now, slide the container view in from the bottom of the screen
self.containerTop.constant = self.frame.size.height - self.containerView.frame.size.height;
[UIView animateWithDuration:animated?0.4f:0.0f
animations:^{
[self layoutIfNeeded];
}
completion:^(BOOL finished) {
if (postDisplay != nil) {
postDisplay();
}
}
];
}
];
Это в настоящее время правильно отображаться на всех тренажерах и устройств в тестировании, но я ненавижу предупреждения/ошибки, и я м беспокоился, что это возможно NOT работа по желанию в некоторой степени.
Вот фактическое сообщение об ошибке, отображаемый (я уверен, что это точно такая же ошибка каждый раз):
Unable to simultaneously satisfy constraints.
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:0x170283430 V:|-(0)-[UIToolbar:0x137590850] (Names: '|':UIView:0x170382b10)>",
"<NSLayoutConstraint:0x170283480 V:[UIToolbar:0x137590850(44)]>",
"<NSLayoutConstraint:0x174084ba0 V:[UIToolbar:0x137590850]-(0)-[UIPickerView:0x137586100]>",
"<NSLayoutConstraint:0x174081fe0 V:[UIPickerView:0x137586100(162)]>",
"<NSLayoutConstraint:0x17409bbc0 V:[UIPickerView:0x137586100]-(0)-| (Names: '|':UIView:0x170382b10)>",
"<NSLayoutConstraint:0x174095b80 V:[UIView:0x170382b10(736)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x174084ba0 V:[UIToolbar:0x137590850]-(0)-[UIPickerView:0x137586100]>
То, что я не понимаю, что все ограничения, как ожидается, и то отображаемый интерфейс - это то, что я намерен. Когда я проверяю макет представления с po [self.containerView recursiveDescription]
в отладчике, я вижу, что фреймы являются именно тем, что я думаю, что они должны быть. Где я иду не так?
Хорошо, но почему это так? Я вижу, где он получает 736 из начального фрейма, который я установил, но разве это не просто отправная точка? Разве это не "исправлено", когда я называю '[self.containerView layoutIfNeeded]'? Как я могу «исправить» эту проблему? Может быть, просто «alloc» init] 'вид без рамки? – mbm29414
Я попробовал 'alloc] init]' (который я понимаю, по сути, 'alloc] initWithFrame: CGRectZero]'), и он придумал ту же ошибку, за исключением того, что (736) был теперь (0). Поэтому, я думаю, я не понимаю, почему существует ограничение, связанное с высотой 'self.containerView' вообще. Откуда это происходит и как его удалить? – mbm29414
Я обновил свой ответ так, надеюсь, что это поможет. – egarlock