В чем разница между Object obj (args ...) и Object obj {args ...}? и почему Скотт говорит так.
blockquote>. Разница в том, что в первом случае порядок оценки аргументов не имеет значения (т. е. неуказан), но в последнем случае порядок остается слева (например, в котором они появляются).
Следующий текст из 5.2.2 / 8 [expr.call] (n3690) относится к форме
Object(args...)
:Оценки постфиксного выражения и аргументов не имеют никакого значения относительно друг друга. Все побочные эффекты оценок аргументов секвенированы до ввода функции (см. 1.9).
blockquote>И текст из $ 8.5.4 / 4 [dcl.init.list] (n3690) имеет дело с
Object{args...}
form:В списке инициализаторов списка с привязкой-инициализацией предложения инициализатора, включая все, которые являются результатом разложений пакетов (14.5.3), оцениваются в порядок, в котором они появляются. То есть вычисление каждого значения и побочный эффект, связанный с заданным предложением инициализатора, секвенируются перед вычислением каждого значения и побочным эффектом, связанным с любым предложением инициализатора, которое следует за ним в списке списка инициализаторов, разделенных запятыми. [Примечание: это порядок оценки выполняется независимо от семантики инициализации; например, он применяется, когда элементы списка инициализатора интерпретируются как аргументы вызова конструктора, хотя обычно нет ограничений последовательности для аргументов вызова. - end note]
blockquote>Ну, это означает:
int f() { static int i = 10; return ++i; } //increment the static int! Object obj(f(), f()); //is it obj(11,12) or obj(12,11)? Unspecified. Object obj{f(), f()}; //it is obj(11,12). Guaranteed.
Обратите внимание, что GCC (4.7.0 и 4.7.2) имеют ошибку из-за форма
{}
не работает так, как должна . Я не уверен, исправлена ли она в текущей версии.Надеюсь, что это поможет.
Как правило, неплохо смешивать фреймы с Auto Layout. (Исключение представляет собой иерархию представлений, которая использует ограничения, содержащие неотображение, которое затем не использует никаких ограничений с этой точки вниз [и дополнительных оговорок]). Одна из больших проблем заключается в том, что система ограничений обычно не получает никакой информации из setFrame.
Другое эмпирическое правило заключается в том, что setFrame и традиционное дерево макета вычисляются до системы ограничений. Это может показаться интуитивно понятным с первой частью, но помните, что 1) в традиционном дереве макетов представления выкладывают свои подпрограммы, а затем вызывают на них layoutSubviews, поэтому каждый кадр супервизора устанавливается перед тем, как он выйдет, но 2) в система ограничения, он пытается вычислить кадр супервизора из подзонов, снизу вверх. Но после получения информации снизу вверх, каждый подзаголовок сообщает информацию, макет работы выполняется сверху вниз.
Куда это вас покидает? Вы правы, что вам нужно установить это программно. В IB нет способа указать, что вы должны переключаться с верхнего уровня на бок о бок. Вот как вы можете это сделать:
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomViewToTopConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *rightViewToLeftConstraint;
.
-(void)updateViewConstraints
{
//first remove the constraints
[self.view removeConstraints:@[self.rightViewToLeftConstraint, self.bottomViewToTopConstraint]];
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) {
//align the tops equal
self.bottomViewToTopConstraint = [NSLayoutConstraint constraintWithItem:self.bottomRightView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.topLeftView
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0];
//align to the trailing edge by spacer
self.rightViewToLeftConstraint = [NSLayoutConstraint constraintWithItem:self.bottomRightView
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:self.topLeftView
attribute:NSLayoutAttributeTrailing
multiplier:1.0
constant:self.spacer];
} else { //portrait
//right view atached vertically to the bottom of topLeftView by spacer
self.bottomViewToTopConstraint = [NSLayoutConstraint constraintWithItem:self.bottomRightView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.topLeftView
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:self.spacer];
//bottom view left edge aligned to left edge of top view
self.rightViewToLeftConstraint = [NSLayoutConstraint constraintWithItem:self.bottomRightView
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:self.topLeftView
attribute:NSLayoutAttributeLeading
multiplier:1.0
constant:0];
}
[self.view addConstraints:@[self.rightViewToLeftConstraint, self.bottomViewToTopConstraint]];
[super updateViewConstraints];
}
Поскольку вы не можете изменять ограничения после их добавления ( кроме константы), мы должны сделать этот шаг удаления-добавления. Обратите внимание, что те, что в IB, также могут быть заполнителями, поскольку мы удаляем их каждый раз (сначала мы могли проверить). Мы могли бы изменить константу на некоторое значение смещения, например, относящееся к супервизору с помощью spacer + topViewHight + spacer. Но это означает, что когда авто макет идет для расчета этого представления, вы сделали предположения на основе другой информации, которая могла бы измениться. Обмен мнениями и изменение того, что они связывают с факторами, которые должны изменить друг друга.
Обратите внимание, что поскольку Auto Layout будет использовать ограничения при передаче информации вверх, сначала мы их модифицируем, тогда мы называем super. Это вызов частной реализации суперкласса для выполнения вычислений для этого представления, а не для просмотра этого представления в иерархии представлений, хотя на самом деле следующий шаг будет дальше по дереву.
UIView
. Поскольку они прикреплены к верхним левому и нижнему правым углам супервизора, это все, что нужно изменить, чтобы правильно выровнять представления. Еще раз спасибо! – Kate 3 February 2015 в 23:22self.superview.frame.size.width - 2 * spacer
– Kate 4 February 2015 в 00:06UIViewController
полностью программно и, следовательно, должны создатьUIView
вloadView()
и установить его как свойство представления контроллера представления, могут ли ограничения заменить необходимость когда-либо явно устанавливать кадр представления? – sconewolf 3 October 2017 в 02:24