如何在IOS中逐个设置约束动画?

如何在IOS中逐个设置约束动画?,ios,objective-c,swift,nslayoutconstraint,uiviewanimationtransition,Ios,Objective C,Swift,Nslayoutconstraint,Uiviewanimationtransition,我有6种观点。我想一个接一个地设置约束的动画,也就是说,我只需要在第一个视图之后的第二个视图上设置动画,然后在第二个视图之后设置第三个,依此类推。我已经在动画的完成处理程序中添加了代码,但它不起作用。在情节提要中,所有约束的初始值都设置为300。我想逐一将其更改为0。现在,只有第一个动画正在工作。这就是我所做的 layoutTopFirst.constant = 0.0; [UIView animateWithDuration:1.0 animations:^{ [sel

我有6种观点。我想一个接一个地设置约束的动画,也就是说,我只需要在第一个视图之后的第二个视图上设置动画,然后在第二个视图之后设置第三个,依此类推。我已经在动画的完成处理程序中添加了代码,但它不起作用。在情节提要中,所有约束的初始值都设置为300。我想逐一将其更改为0。现在,只有第一个动画正在工作。这就是我所做的

layoutTopFirst.constant = 0.0;
    [UIView animateWithDuration:1.0 animations:^{
        [self.view layoutIfNeeded];
    } completion:^(BOOL finished) {
        self->layoutTopSecond.constant = 0.0;
        [UIView animateWithDuration:1.0 animations:^{
            [self.view layoutIfNeeded];
        } completion:^(BOOL finished) {
            self->layoutTopThird.constant = 0.0;
            [UIView animateWithDuration:1.0 animations:^{
                [self.view layoutIfNeeded];
            } completion:^(BOOL finished) {
                self->layoutTopFourth.constant = 0.0;
                [UIView animateWithDuration:1.0 animations:^{
                    [self.view layoutIfNeeded];
                } completion:^(BOOL finished) {
                    self->layoutTopFifth.constant = 0.0;
                    [UIView animateWithDuration:1.0 animations:^{
                        [self.view layoutIfNeeded];
                    } completion:^(BOOL finished) {
                        self->layoutTopSixth.constant = 0.0;
                        [UIView animateWithDuration:1.0 animations:^{
                            [self.view layoutIfNeeded];
                        } completion:^(BOOL finished) {
                            
                        }];
                    }];
                }];
            }];
        }];
    }];

如何一个接一个地制作动画?

如果您显示所有代码(如何设置约束等),这会有所帮助

但是,这里有一个简单的例子

它创建6个标签,顶部约束为100。点击“制作动画”按钮,将动画设置到顶部:0.0。。。再次轻按可将动画设置回100:

#import "SequentialAnimViewController.h"

@interface SequentialAnimViewController () {
    NSMutableArray *views;
    NSMutableArray *topConstraints;
}
@end

@implementation SequentialAnimViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
    [button addTarget:self action:@selector(animViews) forControlEvents:UIControlEventTouchUpInside];
    [button setTitle:@"Do Anim" forState:UIControlStateNormal];
    button.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0];
    button.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:button];
    
    [button.centerXAnchor constraintEqualToAnchor:[self.view centerXAnchor]].active = YES;
    [button.centerYAnchor constraintEqualToAnchor:[self.view centerYAnchor]].active = YES;
    [button.widthAnchor constraintEqualToConstant:200.0].active = YES;

    views = [NSMutableArray new];
    topConstraints = [NSMutableArray new];
    
    CGFloat x = 40.0;
    CGFloat w = 40.0;

    UILayoutGuide *g = [self.view safeAreaLayoutGuide];

    for (int i = 0; i < 6; i++) {
        UILabel *v = [UILabel new];
        v.backgroundColor = [UIColor blueColor];
        v.textColor = [UIColor yellowColor];
        v.textAlignment = NSTextAlignmentCenter;
        v.text = [NSString stringWithFormat:@"%i", i];
        v.translatesAutoresizingMaskIntoConstraints = NO;

        [self.view addSubview:v];
        [v.widthAnchor constraintEqualToConstant:w].active = YES;
        [v.heightAnchor constraintEqualToConstant:w].active = YES;
        [v.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:x].active = YES;

        [topConstraints addObject:[v.topAnchor constraintEqualToAnchor:g.topAnchor constant:100.0]];
        [views addObject:v];

        x += w + 8;
    }
    
    [NSLayoutConstraint activateConstraints:topConstraints];
}

-(void)animViews {
    __block int i = 0;
    __block CGFloat newConstant = ((NSLayoutConstraint *)self->topConstraints[0]).constant == 0.0 ? 100.0 : 0.0;
    ((NSLayoutConstraint *)self->topConstraints[i++]).constant = newConstant;
    [UIView animateWithDuration:1.0 animations:^{
        [self.view layoutIfNeeded];
    } completion:^(BOOL finished) {
        ((NSLayoutConstraint *)self->topConstraints[i++]).constant = newConstant;
        [UIView animateWithDuration:1.0 animations:^{
            [self.view layoutIfNeeded];
        } completion:^(BOOL finished) {
            ((NSLayoutConstraint *)self->topConstraints[i++]).constant = newConstant;
            [UIView animateWithDuration:1.0 animations:^{
                [self.view layoutIfNeeded];
            } completion:^(BOOL finished) {
                ((NSLayoutConstraint *)self->topConstraints[i++]).constant = newConstant;
                [UIView animateWithDuration:1.0 animations:^{
                    [self.view layoutIfNeeded];
                } completion:^(BOOL finished) {
                    ((NSLayoutConstraint *)self->topConstraints[i++]).constant = newConstant;
                    [UIView animateWithDuration:1.0 animations:^{
                        [self.view layoutIfNeeded];
                    } completion:^(BOOL finished) {
                        ((NSLayoutConstraint *)self->topConstraints[i++]).constant = newConstant;
                        [UIView animateWithDuration:1.0 animations:^{
                            [self.view layoutIfNeeded];
                        } completion:^(BOOL finished) {
                            NSLog(@"All Done!");
                        }];
                    }];
                }];
            }];
        }];
    }];
}
@end
#导入“SequentialAnimViewController.h”
@接口顺序视图控制器(){
NSMutableArray*视图;
NSMUTABLEARRY*topConstraints;
}
@结束
@实现顺序视图控制器
-(无效)viewDidLoad{
[超级视图下载];
UIButton*按钮=[UIButton按钮类型:UIButtonTypeSystem];
[按钮添加目标:自我操作:@selector(AnimView)for ControlEvents:UIControlEventTouchUpInside];
[按钮设置标题:@“执行动画”状态:uicontrol状态正常];
button.backgroundColor=[UIColor colorWithWhite:0.9 alpha:1.0];
button.translatesAutoresizingMaskIntoConstraints=否;
[self.view addSubview:按钮];
[button.centerXAnchor constraintEqualToAnchor:[self.view centerXAnchor]]。active=是;
[button.centerYAnchor constraintEqualToAnchor:[self.view centerYAnchor]]。active=是;
[button.widthAnchor constraintEqualToConstant:200.0]。活动=是;
视图=[NSMUTABLEARRY new];
topConstraints=[NSMutableArray new];
CGX=40.0;
CGW=40.0;
UILayoutGuide*g=[self.view安全区域LayoutGuide];
对于(int i=0;i<6;i++){
UILabel*v=[UILabel new];
v、 背景色=[UIColor blueColor];
v、 textColor=[UIColor yellowColor];
v、 textAlignment=NSTextAlignmentCenter;
v、 text=[NSString stringWithFormat:@“%i”,i];
v、 translatesAutoresizingMaskIntoConstraints=否;
[self.view addSubview:v];
[v.widthAnchor constraintEqualToConstant:w]。活动=是;
[v.heightAnchor constraintEqualToConstant:w]。活动=是;
[v.leadingAnchor constraintEqualToAnchor:g.leadingAnchor常量:x]。活动=是;
[topConstraints addObject:[v.topAnchor constraintEqualToAnchor:g.topAnchor常量:100.0];
[视图添加对象:v];
x+=w+8;
}
[NSLayoutConstraint activateConstraints:topConstraints];
}
-(无效)视图{
__块int i=0;
__块CGFloat newConstant=((NSLayoutConstraint*)self->topConstraints[0])。constant==0.0?100.0:0.0;
((NSLayoutConstraint*)self->topConstraints[i++])。常量=新常量;
[UIView animateWithDuration:1.0动画:^{
[self.view layoutifneed];
}完成:^(布尔完成){
((NSLayoutConstraint*)self->topConstraints[i++])。常量=新常量;
[UIView animateWithDuration:1.0动画:^{
[self.view layoutifneed];
}完成:^(布尔完成){
((NSLayoutConstraint*)self->topConstraints[i++])。常量=新常量;
[UIView animateWithDuration:1.0动画:^{
[self.view layoutifneed];
}完成:^(布尔完成){
((NSLayoutConstraint*)self->topConstraints[i++])。常量=新常量;
[UIView animateWithDuration:1.0动画:^{
[self.view layoutifneed];
}完成:^(布尔完成){
((NSLayoutConstraint*)self->topConstraints[i++])。常量=新常量;
[UIView animateWithDuration:1.0动画:^{
[self.view layoutifneed];
}完成:^(布尔完成){
((NSLayoutConstraint*)self->topConstraints[i++])。常量=新常量;
[UIView animateWithDuration:1.0动画:^{
[self.view layoutifneed];
}完成:^(布尔完成){
NSLog(@“全部完成!”);
}];
}];
}];
}];
}];
}];
}
@结束

如果只有第一个正在设置动画,请确保

  • 其他五个约束引用都指向不同的垂直约束。。。例如,如果它们是
    nil
    ,则不会看到任何更改
  • 他们都是活跃的
  • 没有任何其他约束阻止更新的常量产生更改

对于它的价值,你可以考虑用关键帧动画消除你的完成处理塔,例如

CGFloat relativeDuration = 1.0 / 6.0;

[UIView animateKeyframesWithDuration:6 delay:0 options:kNilOptions animations:^{
    [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:relativeDuration animations:^{
        self.topConstraint1.constant = 0;
        [self.view layoutIfNeeded];
    }];

    [UIView addKeyframeWithRelativeStartTime:1.0 * relativeDuration relativeDuration:relativeDuration animations:^{
        self.topConstraint2.constant = 0;
        [self.view layoutIfNeeded];
    }];

    [UIView addKeyframeWithRelativeStartTime:2.0 * relativeDuration relativeDuration:relativeDuration animations:^{
        self.topConstraint3.constant = 0;
        [self.view layoutIfNeeded];
    }];

    [UIView addKeyframeWithRelativeStartTime:3.0 * relativeDuration relativeDuration:relativeDuration animations:^{
        self.topConstraint4.constant = 0;
        [self.view layoutIfNeeded];
    }];

    [UIView addKeyframeWithRelativeStartTime:4.0 * relativeDuration relativeDuration:relativeDuration animations:^{
        self.topConstraint5.constant = 0;
        [self.view layoutIfNeeded];
    }];

    [UIView addKeyframeWithRelativeStartTime:5.0 * relativeDuration relativeDuration:relativeDuration animations:^{
        self.topConstraint6.constant = 0;
        [self.view layoutIfNeeded];
    }];
} completion:nil];
或者更简单一点:

NSArray <NSLayoutConstraint *> *constraints = @[self.topConstraint1, self.topConstraint2, self.topConstraint3, self.topConstraint4, self.topConstraint5, self.topConstraint6];

CGFloat relativeDuration = 1.0 / (CGFloat) constraints.count;

[UIView animateKeyframesWithDuration:totalDuration delay:0 options:kNilOptions animations:^{
    for (NSInteger i = 0; i < constraints.count; i++) {
        [UIView addKeyframeWithRelativeStartTime: ((CGFloat) i) * relativeDuration relativeDuration:relativeDuration animations:^{
            constraints[i].constant = 0;
            [self.view layoutIfNeeded];
        }];
    }
} completion:nil];
NSArray*constraints=@[self.topsconstraint1、self.topsconstraint2、self.topsconstraint3、self.topsconstraint4、self.topsconstraint5、self.topsconstraint6];
CGFloat relativeDuration=1.0/(CGFloat)constraints.count;
[UIView animateKeyframesWithDuration:totalDuration延迟:0选项:针织动画:^{
对于(NSInteger i=0;i
这将产生:


“它不起作用”是以什么方式出现的?所有的动画都是一次完成的吗?没有动画吗?只有第一个动画吗?请详细说明我已经更新了这个问题。现在只有第一个正在制作动画。你能在每次完成时添加一个日志来查看发生了什么吗?注意,这并不是一个快速的话题,但没关系。这是否回答了你的问题