1

制約ベースのビューには、いくつかのラベル (上)、ボタン (下)、カスタマイズされた 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;
            }
        }
    }];

}

これらのアニメーションを修正するにはどうすればよいですか?

ところで、これらのレイヤー再配置コードを挿入する最も推奨される場所はどこですか?

4

1 に答える 1

2

この効果は、レイヤーの暗黙のアニメーションから生じたものと思われます。

次のコードは、すべてのアニメーションの不一致を修正する可能性があります。

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];
}];
于 2013-06-20T13:51:35.437 に答える