【问题标题】:Auto-Layout, animation, and layers in subview子视图中的自动布局、动画和图层
【发布时间】:2013-06-20 13:06:05
【问题描述】:

在基于约束的视图中,有几个标签(顶部)、按钮(底部)和一个自定义的 UIView 子类(检查器),它由许多 CALayer 组成。 我正在尝试通过删除和添加约束来设置视图大小的动画:

// self.containerWidth is a constraint instance 
// from Interface Builder Outlet, which is set to
// constrain the width of the whole view.
[self.calendarContainer removeConstraint:self.containerWidth];

[UIView animateWithDuration:4.0 animations:^{
    [self.calendarContainer addConstraint:
      [NSLayoutConstraint constraintWithItem:self.calendarContainer 
        attribute:NSLayoutAttributeWidth 
        relatedBy:NSLayoutRelationEqual 
        toItem:self.view 
        attribute:NSLayoutAttributeWidth
        multiplier:0
        constant:700]];
    [self.calendarContainer layoutIfNeeded];
}];

动画后,视图如下所示:

在动画期间,标签(顶部)和按钮(底部)根据上面给出的持续时间平稳移动,但是,在发生任何其他转换之前,检查器视图非常快速地反弹到最终状态。

我怀疑有些东西隐含地与一些 CATransaction 混合在一起。

在棋盘格视图中,我重新排列了-layoutSubviews中的图层框架:

- (void)layoutSubviews {
    [super layoutSubviews];
    if (!self.layer.sublayers.count) {
        [self prepareLayers];
    }
    int rowCount = [self rowCount];
    CGFloat rowHeight = [self rowHeight];
    [self.layer.sublayers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        CALayer *rowLayer = obj;
        NSNumber *rowIndex = [rowLayer valueForKey:@"rowindex"];
        if (rowIndex) {
            NSUInteger rowIndexValue = rowIndex.integerValue;
            if (rowIndexValue < rowCount) {
                rowLayer.hidden = NO;
                rowLayer.frame = CGRectMake(0, rowHeight * rowIndexValue, self.frame.size.width, rowHeight);
                [rowLayer.sublayers enumerateObjectsUsingBlock:^(id obj2, NSUInteger idx2, BOOL *stop2) {
                    CALayer *cellLayer = obj2;
                    NSUInteger colIndex = [[cellLayer valueForKey:@"cellindex"] integerValue] - rowIndexValue * 7 - 1;
                    cellLayer.frame = CGRectMake(colIndex*self.frame.size.width/7, 0, self.frame.size.width/7, rowHeight);
                }];
            } else {
                // hide
                rowLayer.hidden = YES;
            }
        }
    }];

}

如何纠正这些动画?

顺便说一句,最推荐插入这些图层重新定位代码的位置在哪里?

【问题讨论】:

    标签: ios animation calayer autolayout


    【解决方案1】:

    似乎效果是由图层的隐式动画产生的。

    以下代码可能会修复所有动画不匹配问题。

    NSTimeInterval duration = 4.0;
    [UIView animateWithDuration:duration animations:^{
    
        [CATransaction begin];
        [CATransaction setValue:@(duration)
                         forKey:kCATransactionAnimationDuration];
        CAMediaTimingFunction *func = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    
        [CATransaction setAnimationTimingFunction:func];
        [self.calendarContainer removeConstraint:self.containerWidth];
    
        [self.calendarContainer addConstraint:[NSLayoutConstraint constraintWithItem:self.calendarContainer attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0 constant:700]];
        [self.calendarContainer layoutIfNeeded];
        [CATransaction commit];
    }];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-04
      • 1970-01-01
      • 2021-11-14
      • 2015-11-30
      • 1970-01-01
      • 1970-01-01
      • 2015-05-02
      • 1970-01-01
      相关资源
      最近更新 更多