如何动画UIView的框架和其子层的框架?

时间:2017-02-07 17:40:31

标签: objective-c animation uiview calayer

我有什么:

我有一个UIView(名为pView),它有一个CAGradientLayer子层。实际上是这样的: ViewController - >查看 - > pView - > CAGradientLayer

这是创建所有这些的代码:

@implementation ViewController  

- (void)viewDidLoad {
  [super viewDidLoad];

  UITestView * pView = nil;
  UIColor * scolor = nil, *ecolor = nil;
  self.view.backgroundColor = [UIColor yellowColor];

  pView = [[UITestView alloc] initWithFrame: CGRectMake(self.view.frame.origin.x, 100.0, self.view.frame.size.width, 100.0)];
  scolor = [UIColor colorWithRed:(14/255.0) green: (238/255.0) blue:(123/255.0) alpha:1];
  ecolor = [UIColor colorWithRed:(6/255.0) green: (216/255.0) blue:(69/255.0) alpha:1];

  // creating the gradient layer    
  CAGradientLayer * layer = [[CAGradientLayer alloc] init];
  layer.frame = self.bounds;
  layer.colors = @[(id)scolor.CGColor,(id)ecolor.CGColor];
  [pView.layer insertSublayer:layer atIndex:0];

  // creating a tapGestureRecognizer
  [pView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapInViews:)]];
  [self.view addSubview:pView];

  touched = NO;
}
....
@end

我想做的事

一旦在pView上检测到轻击手势,我想将pView的高度增加100.0但是动画效果。如果之前触摸了pView(也就是说,它的高度已经增加了100.0),我想将pView的高度减少100.0(即将其恢复为原始大小);

我已经知道

我知道,因为我想要更改pView的框架,我还必须更改附加到pView的CAGradientLayer的框架(或边界)。由于我想要动画这些更改,我希望这些动画同时发生并具有相同的持续时间。

我知道图层的边框(或边界)只能在动画块内设置动画。

我做了什么:

这是我测试的选项:

- (void) handleTapInViews: (nonnull UITapGestureRecognizer *) sender {
  pView = sender.view;

  if (touched) {
    [UIView animateWithDuration:0.4 animations:^{

      pView.frame = CGRectMake(pView.frame.origin.x, pView.frame.origin.y, pView.frame.size.width, pView.frame.size.height - 100.0);
      pView.layer.sublayers[0].frame = pView.bounds;

      [self.view setNeedsLayout];
    } completion:^(BOOL finished) {
      touched = NO;
    }];

  }
  else {
    [UIView animateWithDuration:0.4 animations:^{

      pView.frame = CGRectMake(pView.frame.origin.x, pView.frame.origin.y, pView.frame.size.width, pView.frame.size.height + 100.0);
      pView.layer.sublayers[0].frame = pView.bounds;

      [self.view setNeedsLayout];
    } completion:^(BOOL finished) {
      touched = YES;
    }];

  }

}

这个选项实际上是有效的(也就是说,pView的框架和图层的框架都是动画改变的)但是它们没有同步;也就是说,图层框架中的变化略微(但可感知)比pView框架中的变化更快。当pView的高度降低时,这种效果更明显。

我还阅读了有关CABasicAnimation和CAAnimationGroup的内容,以便为图层的边界和位置设置动画。在这种情况下,图层的动画也比视图的动画快一点(它是可感知的,如果有人询问设置持续时间或其他事情,这不是几秒钟的事情),在这种情况下,在动画之后图层的边界恢复到原始尺寸,这不是所需的效果。我已经知道最后一件事可以修复,在动画结束时将新值分配给图层,但我确定不知道我的代码放在哪里。

我读到的关于这个其他选项的大部分内容来自以下链接:

link1

link2

link3

link4

在任何情况下,有人请知道我该如何解决这个问题?提前谢谢。

1 个答案:

答案 0 :(得分:0)

我结束了将Pview的backgroundColor设置为ecolor = [UIColor colorWithRed:(6 / 255.0)绿色:(216 / 255.0)蓝色:(69 / 255.0)alpha:1。这样,我评论的关于图层动画的效果比视图的动画现在更加明显。我想也许这不是正确的答案,但它适合我。