Обновления автоопределения в анимированном UIView [дубликат]

В чем разница между 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) имеют ошибку из-за форма {} не работает так, как должна . Я не уверен, исправлена ​​ли она в текущей версии.

Надеюсь, что это поможет.

8
задан Kate 2 February 2015 в 22:22
поделиться

1 ответ

Как правило, неплохо смешивать фреймы с Auto Layout. (Исключение представляет собой иерархию представлений, которая использует ограничения, содержащие неотображение, которое затем не использует никаких ограничений с этой точки вниз [и дополнительных оговорок]). Одна из больших проблем заключается в том, что система ограничений обычно не получает никакой информации из setFrame.

Другое эмпирическое правило заключается в том, что setFrame и традиционное дерево макета вычисляются до системы ограничений. Это может показаться интуитивно понятным с первой частью, но помните, что 1) в традиционном дереве макетов представления выкладывают свои подпрограммы, а затем вызывают на них layoutSubviews, поэтому каждый кадр супервизора устанавливается перед тем, как он выйдет, но 2) в система ограничения, он пытается вычислить кадр супервизора из подзонов, снизу вверх. Но после получения информации снизу вверх, каждый подзаголовок сообщает информацию, макет работы выполняется сверху вниз.


Фиксация

Куда это вас покидает? Вы правы, что вам нужно установить это программно. В IB нет способа указать, что вы должны переключаться с верхнего уровня на бок о бок. Вот как вы можете это сделать:

  1. Выберите одно из поворота и убедитесь, что все ограничения настроены так, как вы хотите, в построителе интерфейса - например, каждый цветной вид помещает 8 точек (ваш spacer view) от супервизора. Кнопки «clear constraints» и «update frames» внизу помогут вам, и вы захотите часто щелкнуть по нему, чтобы убедиться, что он синхронизирован.
  2. Очень важно, чтобы вид сверху слева был подключен к надзору левой (верхней) и верхней сторонами, а нижний правый - только правой (задней) и нижней сторонами. Если вы очистите размеры, задающие высоту и ширину, это приведет к предупреждению. нормальный, и в этом случае можно решить, установив при необходимости равные ширины и «равные высоты» и часть шага 3. (Обратите внимание, что константа должна быть равна нулю, чтобы значения были действительно равными.) В других случаях мы должны положить ограничение и отметьте его «заполнителем», чтобы заставить замолчать компилятор, если мы уверены, что будем заполнять информацию, но компилятор этого не знает.
  3. Определить (или создать) два ограничения, которые связывают правый / нижний вид на что-то слева и сверху. Возможно, вы захотите использовать браузер объектов слева от IB. Crea те два выхода в viewController.h с помощью помощника редактора. Будет выглядеть так: @property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomViewToTopConstraint; @property (weak, nonatomic) IBOutlet NSLayoutConstraint *rightViewToLeftConstraint;
  4. Внедрить updateConstraints в viewController. Вот где логика будет идти:

.

-(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. Это вызов частной реализации суперкласса для выполнения вычислений для этого представления, а не для просмотра этого представления в иерархии представлений, хотя на самом деле следующий шаг будет дальше по дереву.

10
ответ дан Mike Sand 22 August 2018 в 13:22
поделиться
  • 1
    Большое спасибо за это. Единственное существенное изменение, которое я сделал для вашего предложения, заключается в том, что я понял, что единственными ограничениями, которые необходимо изменить, были высота и ширина каждого UIView. Поскольку они прикреплены к верхним левому и нижнему правым углам супервизора, это все, что нужно изменить, чтобы правильно выровнять представления. Еще раз спасибо! – Kate 3 February 2015 в 23:22
  • 2
    Рад, что может помочь, проблема была хорошо настроена, я понимаю, что Auto Layout лучше после ответа. Вопрос: Я вижу, как будет работать только настройка высоты и ширины двух цветных представлений, но где суммы, которые вы корректируете? – Mike Sand 3 February 2015 в 23:44
  • 3
    Они рассчитываются как процент от надзора. например self.superview.frame.size.width - 2 * spacer – Kate 4 February 2015 в 00:06
  • 4
    Это то, что я думал, и на практике, вероятно, вполне управляемый, но все же смешение кадров и ограничений может быть проблематичным, особенно если что-то в этих ограничениях должно повлиять на кадр супервизора. В этом случае не проблема. Есть и другие трюки. Удачи. – Mike Sand 4 February 2015 в 00:13
  • 5
    @MikeSand, если вы создаете UIViewController полностью программно и, следовательно, должны создать UIView в loadView() и установить его как свойство представления контроллера представления, могут ли ограничения заменить необходимость когда-либо явно устанавливать кадр представления? – sconewolf 3 October 2017 в 02:24
Другие вопросы по тегам:

Похожие вопросы: