我有一个 UIView 带有一堆子视图,全部使用 layoutSubviews. 。当。。。的时候 view 调整大小,相对位置都在变化。我希望这些重新计算在动画调整大小期间发生(使用 +[UIView beginAnimations:] 电话)。这似乎没有发生。有任何想法吗?

有帮助吗?

解决方案

假设:您想具有多个动画步骤(即位置不会随帧大小线性变化)。

单个“标准” Uiview动画不可能。为什么?帧/边界仅设置一次。

核心动画 有三个“层树”:

  • 模型树 是您的应用程序认为事物的地方。
  • 演示树 大约是在屏幕上显示的内容。
  • 渲染树 大约是核心动画正在合成的内容。

Uiview是围绕模型层的(有点薄)包装器。在Uiview动画中,核心动画更新了演示文稿/渲染树 - 模型树代表动画的终点。结果是,您的代码(大多数情况下)可以将动画视为即时 - 将视图从A转移到B将其移动到B;更改恰好是对用户动画的。

您可以直接使用Calayer/Caanimation来做些复杂的事情,但我没有进行太多研究。

您可以使用 - [uiview setAnimationDidStopSelector:]将多个动画链接在一起。 (您还可以尝试将多个动画与setAnimationDelay一起使用:但是我不确定同一属性上的多个动画会发生什么;您可能会顺利进行SetAnimationBeginSfromCurrentState:.。)

如果您想要真正细粒度的控件,则CadisPlayLink(OS 3.1+)是一个计时器,在每个屏幕刷新后发射。后备选项(用于3.0支持)是在30/60 Hz左右使用NSTIMER。

其他提示

完成 @grizzlynetch的anwer,您可以设置 UIViewAnimationOptionLayoutSubviews 动画选项,因此您无需致电 layoutIfNeeded:

-(void)someMethod{
    double duration = ...;
    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{
        self.frame = ...;
    } completion:nil];
}

我知道这是一个古老的问题,但是此代码非常适合我(适合您更改框架的示例)。

-(void)layoutSubviews{
     [super layoutSubviews];
     // layout your subviews here, or whatever
}

-(void)someMethod{
    double duration=...;
    [UIView animateWithDuration:duration animations:^{
        self.frame = ...;
        [self layoutIfNeeded];
    }];
}

当然,您可以从另一个对象调用此方法。 “窍门”是调用layoutifneed(或直接layoutsubviews - 同一件事 - 如果更改框架,则调用setneedslayout)。

作为TC。很好地解释了“图层树”,您只需强迫演示层以动画显示模型层的最后阶段。

该方法的优点有可能控制何时将帧/边界更改动画以及何时即时。

希望这对某人有帮助:)。

发布完整性。感谢TC。为了解释我想做的事情,核心动画不支持我要做的事情。

我最终提出了一个合理的解决方案。然后在-layoutsubviews中布局我的子视图,而是在-setbounds:。。然后,当我包裹一个-setbounds时:呼叫uiview +beginanimations:block,这些定位呼叫也是动画的,最终结果是一切都适当地动画起来,可以在上帝的位置进行动画。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top