Ios 如何在单独的动画中将CGAffineTransform链接在一起?

Ios 如何在单独的动画中将CGAffineTransform链接在一起?,ios,objective-c,cocoa-touch,animation,cgaffinetransform,Ios,Objective C,Cocoa Touch,Animation,Cgaffinetransform,我需要一个UIView上的两个动画: 使视图向下移动并略微增长 使新中心的视野变得更大 当我尝试这样做时,第二个动画从一个奇怪的位置开始,但最终以正确的位置和大小结束。如何使第二个动画在第一个动画结束的相同位置开始 有一个警告:我被迫使用setTransform而不是setFrame。在我的真实代码中,我没有使用棕色框。我真正的代码使用的是一个复杂的UIView子类,当我使用setFrame时,它不能平滑地伸缩 这看起来可能是一个UIKit错误,当您在现有视图上应用转换时,UIView如何解析

我需要一个UIView上的两个动画:

  • 使视图向下移动并略微增长
  • 使新中心的视野变得更大
  • 当我尝试这样做时,第二个动画从一个奇怪的位置开始,但最终以正确的位置和大小结束。如何使第二个动画在第一个动画结束的相同位置开始

    有一个警告:我被迫使用setTransform而不是setFrame。在我的真实代码中,我没有使用棕色框。我真正的代码使用的是一个复杂的UIView子类,当我使用setFrame时,它不能平滑地伸缩

    这看起来可能是一个UIKit错误,当您在现有视图上应用转换时,UIView如何解析其布局。通过在第二个完成块的最开始处执行以下操作,我至少能够正确获得第二个动画的起始坐标:

      [UIView animateWithDuration:2.0
                            delay:1.0
           usingSpringWithDamping:1.0
            initialSpringVelocity:0.0
                          options:0
                       animations:^{
                         self.box.transform = [self _transformForSize:50.0 centerY:kEndCenterY];
                       }
                       completion:^(BOOL finished) {
                         // <new code here>
                         CGRect newFrame = self.box.frame;
                         self.box.transform = CGAffineTransformIdentity;
                         self.box.frame = newFrame;
                         // </new code>
                         [UIView animateWithDuration:2.0
                                               delay:1.0
                              usingSpringWithDamping:1.0
                               initialSpringVelocity:0.0
                                             options:0
                                          animations:^{
                                            self.box.transform = [self _transformForSize:100.0 centerY:kEndCenterY];
                                          }
                                          completion:^(BOOL finished) {
                                          }];
                       }];
    
    它应该会起作用

    更新


    我应该说,我认为这个“技巧”比实际的解决方案更有效,但是在动画流水线的每一个阶段,盒子的框架和变换看起来都是正确的,所以如果有一个真正的“解决方案”,我现在就无法回避。这个技巧至少为您解决了平移问题,因此您可以尝试使用更复杂的视图层次结构,看看您能走多远。

    所以您希望第二个动画保持在相同的位置,只是变大吗?@TejaNandamuri Correct。第一个和第二个动画之间不应存在断开连接。相关:(我知道它不会解决您的问题,因为无法更改
    帧,但可能对遇到此问题的任何其他人有用)。重置转换确实解决了问题。我希望我知道原因。作为一名计算机科学家,应用伏都教修正法让我感到痛苦。我同意。我认为,如果你真的想解决你的问题,并停留在“变换空间”中,而不是通过“变换”->“帧”->“变换”在两者之间移动,你可能需要调整我对你的变换所做的,在第一个动画的完成块中,将转换为“帧空间”,第二个转换更像是
    self.box.transform=CGAffineTransformConcat(self.box.transform,[self\u transformForSize:100.0 centerY:kendcentry])最终您将需要第二个转换,该转换可以应用于第一个转换之上。
    
      [UIView animateWithDuration:2.0
                            delay:1.0
           usingSpringWithDamping:1.0
            initialSpringVelocity:0.0
                          options:0
                       animations:^{
                         self.box.transform = [self _transformForSize:50.0 centerY:kEndCenterY];
                       }
                       completion:^(BOOL finished) {
                         // <new code here>
                         CGRect newFrame = self.box.frame;
                         self.box.transform = CGAffineTransformIdentity;
                         self.box.frame = newFrame;
                         // </new code>
                         [UIView animateWithDuration:2.0
                                               delay:1.0
                              usingSpringWithDamping:1.0
                               initialSpringVelocity:0.0
                                             options:0
                                          animations:^{
                                            self.box.transform = [self _transformForSize:100.0 centerY:kEndCenterY];
                                          }
                                          completion:^(BOOL finished) {
                                          }];
                       }];
    
    - (CGAffineTransform)_transformForSize:(CGFloat)newSize centerY:(CGFloat)newCenterY
    {
      CGFloat newScale = newSize / kStartSize;
      // Replace this line:
      CGFloat startCenterY = kStartY + kStartSize / 2.0;
      // With this one:
      CGFloat startCenterY = self.box.frame.origin.y + self.box.frame.size.height / 2.0;
      // </replace>
      CGFloat deltaY = newCenterY - startCenterY;
      CGAffineTransform translation = CGAffineTransformMakeTranslation(0.0, deltaY);
      CGAffineTransform scaling = CGAffineTransformMakeScale(newScale, newScale);
      return CGAffineTransformConcat(scaling, translation);
    }