CABasicAnimation在UIStackView中不可靠



我有一个垂直轴的UIStackView,它显示一些类似于UITableView的项目。然而,我正在使用DispatchQueue.main.asyncAfter.在.Delay中为它们设置动画

这是我用来创建CABasicAnimation:的代码

let anim = CABasicAnimation(keyPath: "transform.translation.x")
anim.duration = 0.2
anim.fromValue = UIScreen.main.bounds.size.width
anim.toValue = 0
anim.isRemovedOnCompletion = true
anim.fillMode = kCAFillModeRemoved

出于某种原因,至少在模拟器上(我认为这不重要,因为这个应用程序应该在旧设备或iPhone 7+等功能强大的设备上运行),动画并不总是出现在同一个位置。

有时,单元将飞入,并且从左边起大约为8个像素,有时大约为12个,有时大约是20个。这似乎并不一致。但我认为我的toValue为0,如果我不向层中添加动画,它应该出现在正常显示的位置。

我尝试将isRemovedOnCompletion设置为true,将fillMode设置为removed,但这似乎并没有修复动画。

另一方面,随着动画的继续,有一点是,一个单元格是由水平的UIStackView创建的,其中排列的子视图隐藏在其中。我使用UIView.animateWithDuration方法将其隐藏值设置为false,从而使子视图动画化。

我注意到这一点的原因是,当这种情况发生时,上面的单元格会弹回到它们应该的位置,而不是偏离几个像素

我试着在单元设置动画后在它们上设置NeedsDisplay,也在垂直StackView上设置NeedsDisplay,但也不起作用。我不明白发生了什么,也不明白为什么这些层不能动画化到正确的位置。有什么想法吗?

附言:垂直堆栈视图都是在ViewController的init方法中初始化的。动画出现在viewDidPear方法中。我尝试通过添加DispatchQueue.main.asyncAfter来偏移动画,在super.viewDidPear(动画)之后也尝试了第一件事,但两者都有相同的结果。

在堆栈视图中设置项目动画实际上非常容易。

您所要做的就是在将视图添加到堆栈视图之前,将视图的帧设置到希望它开始的位置,然后在添加新视图后立即在动画块内调用layoutIfNeedd()。以下是从一个工作应用程序中提取的一些示例代码:

let newView = createNewView()
self.stackView.addArrangedSubview(newView)
if sender != nil {
UIView.animate(withDuration: 0.2) {
self.stackView.layoutIfNeeded()
}
}

解决了这个问题。问题是。。。

1) 您只想设置表示层的动画,但由于UIStackView的定位非常适合您,因此要保持元素的实际位置。所以CoreAnimation看起来是个不错的选择。

2) 因为您处理的是UIStackView,所以乍一看,您无法为其排列的子视图设置位置约束的动画。因此,这是您不想设置约束动画的另一个原因,请使用CoreAnimation。

所以你选择了CoreAnimation。既然只有表示层才重要,就不需要设置约束的动画了,对吧?只有当你想让视图的用户交互部分遵守约束时,才真正需要这样做,对吗?是的,不是。

但无论出于什么原因,CoreAnimation都没有做它应该做的事情。也许苹果将来会解决这个问题。但也许不是。哦,没关系。解决方案如下:

对stackview中所有排列的子视图使用占位符。对我来说,这只是一个UIView,它会根据其中的内容调整自己的大小

现在,让这个占位符没有背景色。只允许它包含您不想设置动画的可见内容。由于我正在为整个单元格设置动画,所以我只有一个没有背景颜色的空白UIView。

针对此占位符视图设置此占位符视图的子视图的约束。现在,可以使用常用的自动布局动画工具设置这些约束的动画。例如:

constraint.constant = 0
UIView.animate(withDuration: 0.2, 
delay: 0.1, 
options: UIViewAnimationOptions.curveEaseOut, 
animations: {
cell.layoutIfNeeded()
}, completion: nil)

Booyah!动画是平滑的,相对于排列的子视图,它们实际上会到达您想要的位置。呜呜!

相关内容

  • 没有找到相关文章

最新更新