【发布时间】:2019-11-12 11:30:46
【问题描述】:
所以我在 swift 中使用容器视图来获得一个覆盖视图,该视图在导航控制器中的多个视图控制器之间共享。
它的工作方式是我有许多子视图为流创建“背景”。在这些视图之上,我有一个容器视图,其中嵌入了一个导航控制器。该导航控制器通过多个视图控制器引导用户完成入职流程。在这个容器视图上方是“进度视图”,它的前缘与超级视图的前缘对齐,并且随着用户在引导过程中导航,它的宽度会增加,直到最终,栏的宽度等于屏幕的宽度并且用户已经创建了他们的个人资料。 这是它的外观示例: Skip to 1:53 to see the main issue
这就是包含视图控制器的样子。注意背景的分层,然后是容器视图,然后是进度条视图:
此视图控制器有一个名为updateProgressBar 的函数,该函数将屏幕宽度的百分比设置为动画,然后执行动画。
func updateProgressBar(to percentAsDecimal: CGFloat!) {
UIView.animate(withDuration: 0.25) {
self.progressBarWidth.constant = self.view.frame.width * percentAsDecimal
self.view.layoutIfNeeded()
}
}
问题: 因为包含的导航控制器在进度条动画期间推送了一个新的视图控制器,所以当这个新的视图控制器布置它的子视图时,这个布置是动画的。
我尝试过的:
我创建了自定义类,它们是 UIView 的子类,它们使用 UIView.performWithoutAnimation 函数来避免子视图的这种动画。
import UIKit
class NonAnimatingView: UIView {
override func layoutSubviews() {
UIView.performWithoutAnimation {
super.layoutSubviews()
}
}
}
我用按钮做了类似的事情。
import UIKit
class NonAnimatingButton: UIButton {
override func layoutSubviews() {
UIView.performWithoutAnimation {
super.layoutSubviews()
}
}
}
但是,当我尝试使用 UISearchBar 执行此操作时,某些动画已解决,但不是全部。
import UIKit
class NonAnimatingSearchBar: UISearchBar {
override func layoutSubviews() {
UIView.performWithoutAnimation {
super.layoutSubviews()
}
}
override func addSubview(_ view: UIView) {
UIView.performWithoutAnimation {
super.addSubview(view)
}
}
override func insertSubview(_ view: UIView, at index: Int) {
UIView.performWithoutAnimation {
super.insertSubview(view, at: index)
}
}
override func insertSubview(_ view: UIView, aboveSubview siblingSubview: UIView) {
UIView.performWithoutAnimation {
super.insertSubview(view, aboveSubview: siblingSubview)
}
}
override func insertSubview(_ view: UIView, belowSubview siblingSubview: UIView) {
UIView.performWithoutAnimation {
super.insertSubview(view, belowSubview: siblingSubview)
}
}
override func sendSubviewToBack(_ view: UIView) {
UIView.performWithoutAnimation {
super.sendSubviewToBack(view)
}
}
override func bringSubviewToFront(_ view: UIView) {
UIView.performWithoutAnimation {
super.bringSubviewToFront(view)
}
}
override func exchangeSubview(at index1: Int, withSubviewAt index2: Int) {
UIView.performWithoutAnimation {
super.exchangeSubview(at: index1, withSubviewAt: index2)
}
}
}
我还确保在推送导航控制器视图控制器之前调用的任何布局更改都不会被动画化:
override func viewDidLoad() {
UIView.performWithoutAnimation {
super.viewDidLoad()
femaleButton.backgroundColor = UIColor.lightGray.withAlphaComponent(0.25)
maleButton.backgroundColor = UIColor.lightGray.withAlphaComponent(0.25)
otherGenderButton.backgroundColor = UIColor.lightGray.withAlphaComponent(0.25)
femaleButton.layer.cornerRadius = 5
maleButton.layer.cornerRadius = 5
otherGenderButton.layer.cornerRadius = 5
nextButton.layer.cornerRadius = nextButton.frame.height/2
}
}
我在想什么:
有什么我可以调用而不是 UIView.animate 以便我可以在指定的视图控制器中设置动画而不影响当前可见的所有视图控制器吗?如果不是,解决此问题的最佳方法是什么?
【问题讨论】:
-
为什么不用 CAShapeLayer 和 CoreAnimation 来代替?
标签: ios swift uiview core-animation