简体   繁体   中英

Autolayout breaks UIView Animation

Struggling to make my app work on both the iPhone 5 and the smaller iPhone's prior. Would be happy to require iOS6 and use Autolayout because that works great.

However, the app has 4 buttons that regularly swap positions, so I assign each button a different location from an array and then animate the movement with something like this:

[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];
}];

This doesn't work with Autolayout. Nothing changes. The best I've gotten is that it will animate to a position then immediately snap back.

When I remove Autolayout however all the buttons are scrunched up on the smaller iPhones, and because I'm using points set by the iPhone 5 size they end up lower down, putting the bottom row off the screen. I original had different CGPoint numbers that I got from Interface Builder, but they were "wrong", though I'm thinking they were "wrong" because they were the numbers for Autolayout to use. The array just so you can see:

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

What should I do to fix this problem? Setting different points for each sized device doesn't seem very efficient.

The solution is that you animate the items transform property, not its position.

The position is going to be set by autolayout and you don't want to fight it. The actual position on the screen, though, is going to be its "correct" (set by auto layout) position, offset by its transform property.

So you can say button.transform = CGTransformMake(x,y) and it will appear x and y off from it's center position.

There are a variety of CGWhatever macros to make these transforms easily, and you can just change them in an animation block to move the items around.

One way would be to use the auto layout system, and animate the "constant" value of the constraint. In the example code below, I have three buttons in a horizontal row, each with a leading edge constraint to the superview, which is what I animate. side1, side2, and side3 are IBOutlets to those constraints, and button1, button2, and button3 are the outlets to the 3 buttons.

-(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];
    }];
}

You can fix this problem with very little changes in your code. Instead of swapping the button locations, swap their layout constrains. You can use the cocoapod SBP to swap the layout constrains by importing this category

    #import "UIViewController+SBP.h"

Then using this method

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

Here is a video tutorial .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM