Autolayout ломает анимацию UIView

Пытаюсь заставить мое приложение работать как на iPhone 5, так и на более раннем iPhone. Был бы рад потребовать iOS6 и использовать Autolayout, потому что это прекрасно работает.

Однако в приложении есть 4 кнопки, которые регулярно меняются местами, поэтому я назначаю каждой кнопке отдельное местоположение из массива, а затем анимирую движение примерно так:

[UIView animateWithDuration:0.5 animations:^{
    button1.center = [[locations objectAtIndex:0] CGPointValue];
    button2.center = [[locations objectAtIndex:1] CGPointValue];
    button3.center = [[locations objectAtIndex:2] CGPointValue];
    button4.center = [[locations objectAtIndex:3] CGPointValue];
}];

Это не работает с Autolayout. Ничего не меняется. Лучшее, что я получил, это то, что он будет анимироваться в нужное положение, а затем сразу же вернется обратно.

Однако, когда я удаляю Autolayout, все кнопки сжимаются на меньших iPhone, и поскольку я использую точки, установленные размером iPhone 5, они заканчиваются ниже, убирая нижний ряд с экрана. У меня изначально были другие числа CGPoint, которые я получил от Interface Builder, но они были «неправильными», хотя я думаю, что они были «неправильными», потому что это были числа для использования Autolayout. Массив, чтобы вы могли видеть:

buttonLocations = [NSArray arrayWithObjects:
        [NSValue valueWithCGPoint:CGPointMake(57, 523)],
        [NSValue valueWithCGPoint:CGPointMake(109, 523)],
        [NSValue valueWithCGPoint:CGPointMake(57, 471)],
        [NSValue valueWithCGPoint:CGPointMake(109, 471)],
        nil];

Что мне делать, чтобы решить эту проблему? Установка разных точек для каждого размера устройства не кажется очень эффективной.


person William Robinson    schedule 14.12.2012    source источник


Ответы (3)


Решение состоит в том, что вы анимируете свойство преобразования элементов, а не их положение.

Позиция будет установлена ​​автоматическим расположением, и вы не хотите с этим бороться. Однако фактическое положение на экране будет его «правильным» (установленным автоматическим макетом) положением, смещенным его свойством преобразования.

Таким образом, вы можете сказать button.transform = CGTransformMake(x,y), и он будет отображаться на x и y вне своего центрального положения.

Существует множество макросов CGWhatever, позволяющих легко выполнять эти преобразования, и вы можете просто изменить их в блоке анимации, чтобы перемещать элементы.

person nirvana    schedule 06.06.2013
comment
Я получаю эту проблему: Назначение «CGAffineTransform» (он же «struct CGAffineTransform») из несовместимого типа «int»? - person William Robinson; 08.06.2013
comment
какой тип button.transform? Это должен быть CGAffineTransform. Вы назначаете вывод CGAffineTransformMakeTranslation() или какой-либо другой функции, которая создает CGAffineTransform, верно? Похоже, вы пытаетесь передать int. CGAffineTransform производит преобразование. - person nirvana; 09.06.2013

Одним из способов было бы использовать систему автоматической компоновки и анимировать «постоянное» значение ограничения. В приведенном ниже примере кода у меня есть три кнопки в горизонтальном ряду, каждая из которых имеет ограничение переднего края для суперпредставления, которое я анимирую. side1, side2 и side3 — это IBOutlets для этих ограничений, а button1, button2 и button3 — это выходы для 3 кнопок.

-(void)animateButton {
    [self.view removeConstraint:self.side1];
    [self.view removeConstraint:self.side2];
    [self.view removeConstraint:self.side3];

    NSLayoutConstraint *con1 = [NSLayoutConstraint constraintWithItem:self.button1 attribute:NSLayoutAttributeLeading relatedBy:0 toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1 constant:114];
    NSLayoutConstraint *con2 = [NSLayoutConstraint constraintWithItem:self.button2 attribute:NSLayoutAttributeLeading relatedBy:0 toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1 constant:213];
    NSLayoutConstraint *con3 = [NSLayoutConstraint constraintWithItem:self.button3 attribute:NSLayoutAttributeLeading relatedBy:0 toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1 constant:20];

    [self.view addConstraints:@[con1,con2,con3]];
    [UIView animateWithDuration:2 animations:^{
        [self.view layoutIfNeeded];
    }];
}
person rdelmar    schedule 14.12.2012
comment
если кнопка 1, кнопка 2 и кнопка 3 являются IBOutlet для UIButtons в построителе интерфейса, как мне настроить стороны 1, стороны 2 и стороны 3 в проекте? - person William Robinson; 14.12.2012
comment
@WilliamRobinson, когда вы добавляете кнопки в представление, ограничения будут добавлены автоматически. Хотя, возможно, вам придется их изменить. Если все кнопки выстроены вертикально и либо имеют явные размеры, либо настроены на использование внутреннего размера содержимого, то единственным другим ограничением, которое им нужно, будет передний край для супервизора - если есть какие-либо другие (например, от заднего края ) их можно удалить. После того, как у вас есть правильные ограничения, вы можете подключить к ним выходы, как и к любому другому объекту. - person rdelmar; 15.12.2012
comment
Это когда я нажимаю кнопку UIButton, а в представлении «Утилиты» нажимаю на линейку и вижу длинный список таких вещей, как: «Ограничения, равные высоте: 50», «Выровнять ведущий к: кнопка -4» и т. д.? - person William Robinson; 15.12.2012
comment
@WilliamRobinson, это одно из мест, где вы их видите, но вам нужно установить соединения в списке объектов в левой части рабочего пространства. Если щелкнуть треугольник раскрытия для представления, содержащего эти кнопки, должна быть запись ограничений. - person rdelmar; 15.12.2012

Вы можете решить эту проблему с очень небольшими изменениями в вашем коде. Вместо того, чтобы менять местами кнопки, поменяйте местами их ограничения макета. Вы можете использовать Cocopod SBP, чтобы поменять местами ограничения макета, импортировав эту категорию.

    #import "UIViewController+SBP.h"

Затем с помощью этого метода

    - (void)switchViewConst:(UIView*)firstView secondView:(UIView*)secondView durationInSeconds:(double)durationInSeconds

Вот видеоруководство.

person Arjay Waran    schedule 15.11.2015