更改背景图像时容器视图动画无法正常工作
Container View animations not working properly when changing out a background image
我在 IB 中有 3 个视图。 View One(1) 有一个视图和一个 UIImage,我将其用作此 ViewController 的背景。视图二(2)(详细信息视图)和视图三(3)(选项视图)是容器视图,两者都放置在彼此之上。我在 View 2 中有一个按钮,它使 View 2 向左移动并从右侧移动 View 3。我可以从 View 3 向右移动并从左侧返回 View 2。
我的文档大纲如下所示:
White BG,只是标题栏下面的背景,以防万一有人想知道。
这是我用来制作这些动画的代码:
func showOptions(){
println("show options")
optionsView.center.x = self.view.bounds.width + self.view.bounds.width / 2
optionsView.hidden = false
UIView.animateWithDuration(0.5, animations: {
self.blurView.alpha = 1
// slide containers around
// println(self.view.bounds.width)
self.detailsView.center.x = -self.view.bounds.width * 2
self.optionsView.center.x = self.view.bounds.width / 2
})
}
func showDetails(){
println("show detials")
optionsView.center.x = self.view.bounds.width / 2
UIView.animateWithDuration(0.5, animations: {
self.blurView.alpha = 0
// slide containers around
// println(self.view.bounds.width)
self.detailsView.center.x = self.view.bounds.width / 2
println("\(self.optionsView.center.x) this is center X value 1")
self.optionsView.center.x = self.view.bounds.width * 2
println("\(self.optionsView.center.x) this is center X value 2")
}, completion: {
(value: Bool) in
println("\(self.optionsView.center.x) this is center X value 3")
})
}
那些对我从打印语句中得到什么感到好奇的人
当我不尝试更改背景照片并且事情像这样工作时,我应该得到这个:
- 160.0 这是中心 X 值 1
- 640.0 这是中心 X 值 2
- 640.0 这是中心 X 值 3
当我更改照片时,我得到这些值:
- 160.0 这是中心 X 值 1
- 640.0 这是中心 X 值 2
- 160.0 这是中心 X 值 3
当我尝试更改此视图控制器的背景视图图像时不起作用。
let par3 = UIImage(named: "par3.png")
backgroundImage.image = par3
// println("par three")
showDetails()
当我更改背景照片时,视图 2 和视图 3 都从左侧动画到屏幕上。我只是不确定为什么。是否与切换出背景图片时修改View Controller的宽度有关?
感谢您的帮助!
感觉你对 Auto Layout 还只是半信半疑。您最初使用它来布置您的视图,但是当您为视图设置动画时您没有使用它。您正在修改中心 x 位置,这是旧的动画方式。它有点工作,但后来我认为当你换掉背景图像时,一切都被重置为你的初始约束,因为这会导致在引擎盖下调用 layoutIfNeeded()
,它使用约束将所有东西重新定位最初是。
您无需修改视图的中心 x 位置,而是需要更改修改约束的方法。这意味着即使你换掉图像,你的约束仍然是准确的,一切都应该按预期工作。这需要以特定方式设置约束,我将尝试演示。
首先,我设置了一个带有几个子视图控制器的父视图控制器。每个子项都有一个按钮,可以调用父项中的委托方法。
我的故事板是这样的:
检查员长这样:
关于故事板设置的几点:
- 我有一个主容器视图,它是父视图的子视图。这个主容器视图将 clipSubviews 设置为 YES,这样当我们左右移动视图时,它们不会出现在主容器的边界之外。
- 选项和详细容器视图都设置了约束以匹配主容器视图的宽度和高度。
- 详细信息容器视图的左侧设置为紧靠选项容器视图的右侧,即 [选项][详细信息]。它们并不直接重叠。
- 详细容器视图有一个约束,因此它的顶边与选项容器视图的顶边对齐。
- 选项容器视图设置了约束,与主容器视图的左上角对齐。这与前面的 2 个项目符号相结合意味着最初详细信息容器视图位于屏幕右侧。我在父视图控制器中引用了约束,该约束将选项容器视图的左侧与 mainContainerView 的左侧(在上面的屏幕截图中选择的那个)对齐,这就是我用来为所有内容设置动画的方法.
这是父 class 的样子:
class ParentViewController: UIViewController, OptionsViewControllerDelegate, DetailViewControllerDelegate {
struct Constants {
static let optionsEmbedSegue = "optionsEmbedSegue"
static let detailEmbedSegue = "detailEmbedSegue"
}
@IBOutlet weak var mainContainerView: UIView!
@IBOutlet weak var optionsLeadingSpaceConstraint: NSLayoutConstraint!
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == Constants.optionsEmbedSegue {
let childViewController = segue.destinationViewController as OptionsViewController
childViewController.delegate = self
} else if segue.identifier == Constants.detailEmbedSegue {
let childViewController = segue.destinationViewController as DetailViewController
childViewController.delegate = self
}
}
func optionsViewControllerDidSelectToShowDetail(optionsViewController: OptionsViewController) {
animateOptionsToNewXPosition(-CGRectGetWidth(mainContainerView.bounds))
}
func detailViewControllerDidSelectToGoBack(detailViewController: DetailViewController) {
animateOptionsToNewXPosition(0)
}
func animateOptionsToNewXPosition(xPosition: CGFloat) {
optionsLeadingSpaceConstraint.constant = xPosition
UIView.animateWithDuration(0.5, animations: { () -> Void in
self.mainContainerView.layoutIfNeeded()
})
}
}
如果您查看 optionsViewControllerDidSelectToShowDetail
方法,您会看到行 animateOptionsToNewXPosition(-CGRectGetWidth(mainContainerView.bounds))
。这是将选项视图控制器向左移动主容器视图的宽度。这意味着它会消失在屏幕的左侧,并且由于所有其他约束,它会拖动详细视图控制器,在 mainContainerView
中显示详细视图控制器。相反的情况发生在 detailViewControllerDidSelectToGoBack
方法中,只需将该约束中的常量设置回 0,这会将选项视图控制器带回,并将 detailViewController 推到右侧。
希望对您有所帮助。
我在 IB 中有 3 个视图。 View One(1) 有一个视图和一个 UIImage,我将其用作此 ViewController 的背景。视图二(2)(详细信息视图)和视图三(3)(选项视图)是容器视图,两者都放置在彼此之上。我在 View 2 中有一个按钮,它使 View 2 向左移动并从右侧移动 View 3。我可以从 View 3 向右移动并从左侧返回 View 2。
我的文档大纲如下所示:
White BG,只是标题栏下面的背景,以防万一有人想知道。
这是我用来制作这些动画的代码:
func showOptions(){
println("show options")
optionsView.center.x = self.view.bounds.width + self.view.bounds.width / 2
optionsView.hidden = false
UIView.animateWithDuration(0.5, animations: {
self.blurView.alpha = 1
// slide containers around
// println(self.view.bounds.width)
self.detailsView.center.x = -self.view.bounds.width * 2
self.optionsView.center.x = self.view.bounds.width / 2
})
}
func showDetails(){
println("show detials")
optionsView.center.x = self.view.bounds.width / 2
UIView.animateWithDuration(0.5, animations: {
self.blurView.alpha = 0
// slide containers around
// println(self.view.bounds.width)
self.detailsView.center.x = self.view.bounds.width / 2
println("\(self.optionsView.center.x) this is center X value 1")
self.optionsView.center.x = self.view.bounds.width * 2
println("\(self.optionsView.center.x) this is center X value 2")
}, completion: {
(value: Bool) in
println("\(self.optionsView.center.x) this is center X value 3")
})
}
那些对我从打印语句中得到什么感到好奇的人
当我不尝试更改背景照片并且事情像这样工作时,我应该得到这个:
- 160.0 这是中心 X 值 1
- 640.0 这是中心 X 值 2
- 640.0 这是中心 X 值 3
当我更改照片时,我得到这些值:
- 160.0 这是中心 X 值 1
- 640.0 这是中心 X 值 2
- 160.0 这是中心 X 值 3
当我尝试更改此视图控制器的背景视图图像时不起作用。
let par3 = UIImage(named: "par3.png")
backgroundImage.image = par3
// println("par three")
showDetails()
当我更改背景照片时,视图 2 和视图 3 都从左侧动画到屏幕上。我只是不确定为什么。是否与切换出背景图片时修改View Controller的宽度有关?
感谢您的帮助!
感觉你对 Auto Layout 还只是半信半疑。您最初使用它来布置您的视图,但是当您为视图设置动画时您没有使用它。您正在修改中心 x 位置,这是旧的动画方式。它有点工作,但后来我认为当你换掉背景图像时,一切都被重置为你的初始约束,因为这会导致在引擎盖下调用 layoutIfNeeded()
,它使用约束将所有东西重新定位最初是。
您无需修改视图的中心 x 位置,而是需要更改修改约束的方法。这意味着即使你换掉图像,你的约束仍然是准确的,一切都应该按预期工作。这需要以特定方式设置约束,我将尝试演示。
首先,我设置了一个带有几个子视图控制器的父视图控制器。每个子项都有一个按钮,可以调用父项中的委托方法。
我的故事板是这样的:
检查员长这样:
关于故事板设置的几点:
- 我有一个主容器视图,它是父视图的子视图。这个主容器视图将 clipSubviews 设置为 YES,这样当我们左右移动视图时,它们不会出现在主容器的边界之外。
- 选项和详细容器视图都设置了约束以匹配主容器视图的宽度和高度。
- 详细信息容器视图的左侧设置为紧靠选项容器视图的右侧,即 [选项][详细信息]。它们并不直接重叠。
- 详细容器视图有一个约束,因此它的顶边与选项容器视图的顶边对齐。
- 选项容器视图设置了约束,与主容器视图的左上角对齐。这与前面的 2 个项目符号相结合意味着最初详细信息容器视图位于屏幕右侧。我在父视图控制器中引用了约束,该约束将选项容器视图的左侧与 mainContainerView 的左侧(在上面的屏幕截图中选择的那个)对齐,这就是我用来为所有内容设置动画的方法.
这是父 class 的样子:
class ParentViewController: UIViewController, OptionsViewControllerDelegate, DetailViewControllerDelegate {
struct Constants {
static let optionsEmbedSegue = "optionsEmbedSegue"
static let detailEmbedSegue = "detailEmbedSegue"
}
@IBOutlet weak var mainContainerView: UIView!
@IBOutlet weak var optionsLeadingSpaceConstraint: NSLayoutConstraint!
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == Constants.optionsEmbedSegue {
let childViewController = segue.destinationViewController as OptionsViewController
childViewController.delegate = self
} else if segue.identifier == Constants.detailEmbedSegue {
let childViewController = segue.destinationViewController as DetailViewController
childViewController.delegate = self
}
}
func optionsViewControllerDidSelectToShowDetail(optionsViewController: OptionsViewController) {
animateOptionsToNewXPosition(-CGRectGetWidth(mainContainerView.bounds))
}
func detailViewControllerDidSelectToGoBack(detailViewController: DetailViewController) {
animateOptionsToNewXPosition(0)
}
func animateOptionsToNewXPosition(xPosition: CGFloat) {
optionsLeadingSpaceConstraint.constant = xPosition
UIView.animateWithDuration(0.5, animations: { () -> Void in
self.mainContainerView.layoutIfNeeded()
})
}
}
如果您查看 optionsViewControllerDidSelectToShowDetail
方法,您会看到行 animateOptionsToNewXPosition(-CGRectGetWidth(mainContainerView.bounds))
。这是将选项视图控制器向左移动主容器视图的宽度。这意味着它会消失在屏幕的左侧,并且由于所有其他约束,它会拖动详细视图控制器,在 mainContainerView
中显示详细视图控制器。相反的情况发生在 detailViewControllerDidSelectToGoBack
方法中,只需将该约束中的常量设置回 0,这会将选项视图控制器带回,并将 detailViewController 推到右侧。
希望对您有所帮助。