【问题标题】:how to animate both the frame of an UIView and the frame of one of its sublayers?如何为 UIView 的框架及其子层之一的框架设置动画?
【发布时间】:2017-06-25 02:03:00
【问题描述】:

我有什么:

我有一个 UIView(名为 pView),它有一个 CAGradientLayer 作为子层。实际上是这样的: ViewController -> View ->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的frame和layer的frame都是动态变化的)但是他们不同步;也就是layer的frame变化比pView的frame变化稍微快一点(但可以感知)。当 pView 的高度降低时,这种效果更加明显。

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

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

link1

link2

link3

link4

无论如何,有人知道我该如何解决这个问题吗?提前致谢。

【问题讨论】:

    标签: objective-c animation uiview calayer


    【解决方案1】:

    我结束了将 Pview 的 backgroundColor 设置为 ecolor = [UIColor colorWithRed:(6/255.0) green:(216/255.0) blue:(69/255.0) alpha:1。这样,我评论层的动画比视图的动画快的效果现在不明显了。我认为这可能不是正确的答案,但它适合我。

    【讨论】:

      猜你喜欢
      • 2018-01-03
      • 1970-01-01
      • 1970-01-01
      • 2015-01-02
      • 1970-01-01
      • 2014-08-31
      • 1970-01-01
      • 1970-01-01
      • 2013-07-30
      相关资源
      最近更新 更多