【问题标题】:Apply and animate many constraints to outlet collection of uiviews将许多约束应用于 uiview 的出口集合并为其设置动画
【发布时间】:2020-07-20 00:12:01
【问题描述】:

我有一个标签集。标签位于堆栈视图的父级堆栈视图中。当视图加载时,我想让每个标签淡入并一个接一个地向右移动。我可以在循环中应用约束来抵消它。但只有一个会动画回到最终位置。

-(void)viewDidLoad {
[super viewDidLoad];
for (UILabel *lbl in _constructionlabels) {
    lbl.alpha = 0.0;
    leadingCnst=[NSLayoutConstraint
    constraintWithItem:lbl
    attribute:NSLayoutAttributeLeading
    relatedBy:NSLayoutRelationEqual
    toItem:[lbl superview]
    attribute:NSLayoutAttributeLeading
    multiplier:1.0
    constant:-25];
    [self.view addConstraint:leadingCnst];
}

}

-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];

leadingCnst.constant = 0;
[UIView animateWithDuration:0.33 delay:2 options:UIViewAnimationOptionCurveEaseOut animations:^{
    for (UILabel *lbl in self->_constructionlabels) {
        lbl.alpha = 1.0;
    }
    [self.view layoutIfNeeded];
} completion:^(BOOL finished) {
}];

}

如何将约束应用于每个需要的标签,然后一个接一个地为它们设置动画?

【问题讨论】:

  • 标记此处使用的编程语言以获得更好的可见性可能很有用。对我来说,它看起来像 Objective-c,但因为我从来没有做过 Objective-c,所以我不是 100% :)

标签: objective-c xcode animation nslayoutconstraint iboutletcollection


【解决方案1】:

保留对每个标签约束的引用并立即启动所有动画,每个动画都有延迟。

// Declare array to hold references to constraints
NSMutableArray* _labelConstraints = [NSMutableArray array];

-(void) viewDidLoad {
    [super viewDidLoad];
    for (UILabel * lbl in _constructionlabels) {
        lbl.alpha = 0.0;

        NSLayoutConstraint* leadingCnst = [NSLayoutConstraint
            constraintWithItem: lbl
            attribute: NSLayoutAttributeLeading
            relatedBy: NSLayoutRelationEqual
            toItem: [lbl superview]
            attribute: NSLayoutAttributeLeading
            multiplier: 1.0
            constant: -25
        ];
        [self.view addConstraint: leadingCnst];

        // Add constraint reference
        [_labelConstraints addObject: @(leadingCnst)];
    }
}

-(void) viewDidAppear: (BOOL) animated {
    [super viewDidAppear: animated];

    for (i = 0; i < [_constructionlabels count]; i++) {

        // Get label
        Label* lbl = [_constructionlabels objectAtIndex:i];        

        // Get constraint
        NSLayoutConstraint* labelConstraint = [_labelConstraints objectAtIndex:i];      

        // Animate
        [UIView animateWithDuration: 0.33 delay: i options: UIViewAnimationOptionCurveEaseOut animations: ^ {
                lbl.alpha = 1.0;
                labelConstraint.constant = 0;
                [self.view layoutIfNeeded];
            }
            completion: ^ (BOOL finished) {}
        ];  
    }
}

注意:这只是一个概念证明 - 您可能需要重构代码。

(我写ObjC已经有一段时间了,如果你让我知道任何错误我会纠正它们。)

【讨论】:

    【解决方案2】:

    您将需要放置一个递归函数来为每个标签一个一个地设置动画,而无需 for 循环。在动画中添加完成块。

        func animate(_ label: UILabel, completion: @escaping () -> Void) {
            UIView.animate(withDuration: 1, animations: {
                // add animation here
            }, completion: { _ in
                completion()
            })
        }
    
        let labelCollection = [UILabel]()
        var index = 0
    
        func startAnimation() {
            animate(labelCollection[index], completion: {
                if self.index < self.labelCollection.count - 1 {
                    self.index = self.index + 1
                    self.startAnimation()
                }
            })
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-02
      • 2015-02-06
      • 2020-08-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多