动画期间的layoutsubviews?
-
02-10-2019 - |
题
我有一个 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,这些定位呼叫也是动画的,最终结果是一切都适当地动画起来,可以在上帝的位置进行动画。