如何将居中的正方形动画到顶部 [英] How to animate centered square to the top
问题描述
我在仅提供肖像的应用程序中具有 UIView
。
I have a UIView
in a portrait-only app.
- 视图是垂直居中和水平,并带有
AutoLayout
(手动使用情节提要)。 -
宽度
等于(main)view.width * 0.9
-
高度
的宽度与宽度相同(为正方形)。
- The view is centered vertically and horizontally with
AutoLayout
("manually" using storyboards). - The
width
equals the(main)view.width * 0.9
- The
height
is the same size of the width (it is a square).
我想在此 UIView
中点击一个按钮,然后对其进行垂直动画处理,直到到达屏幕的顶部边框为止(例如,高度* 0.9,10磅
I want to tap a button inside this UIView
and animate it only vertically until it reaches the top border of the screen (eg. height*0.9, 10 pts, whatever is possible).
当我再次单击时,我想将视图重新定位到其原始位置(以我第一次轻按时为中心)。
When I click again, I want to reposition back the view to its original position (centered as it was when I first tapped).
在过渡期间,正方形不可轻敲。
During the transition the square should not be tappable.
在阅读了很多帖子之后,我不明白那是什么最好的方法(我主要是向开发人员说,应该避免使用 centerX
的旧技术,而对某些版本的SO表现出奇怪的感叹)。
After reading many posts I could not understand what's the best way to do this (I red mainly developers saying old techniques using centerX
should be avoided and lamentations about some versions of the SO behaving in strange ways).
我想我应该找到一种方法来获取约束的当前位置,并为约束分配最终位置,但是我做不到。
I suppose I should find a way to get the current "position" of the constraints and to assign a constraint the "final" position, but I was not able to do it.
感谢您的帮助
推荐答案
虽然您可以使用自动版式制作动画-采取约束centerY的约束并将其常数设置为将移动到顶部的值(例如, constant =-(UIScreen.main.bounds.height / 2)
) ,我建议使用视图的 transform
属性。
While you can use Autolayout to animate - to take the constraint constraining the centerY and set its constant to a value that would move to the top (e.g., constant = -(UIScreen.main.bounds.height / 2)
), I would recommend using view's transform
property.
因此,将视图移至顶部,您可以使用:
So to move the view to the top you can use:
let topMargin = CGFloat(20)
let viewHalfHeight = self.view.bounds.height / 2
let boxHalfHeight = self.box.bounds.height / 2
UIView.animate(withDuration: 0.2) {
box.transform = CGAffineTransform.identity
.translatedBy(x: 0, y: -(viewHalfHeight - (boxHalfHeight + topMargin)))
}
您正在移动与 view.center
相关的 box.center
-因此,如果要将框移动到顶部,则必须将其 center
移动一半视图高度(因为视图的 centerY
恰好是 height / 2
距视图的 top
远)。但是这还不够,因为那时候只有框的下半部分可见(现在 box.centerY == view.top
)。因此,您必须将其移回 box.bounds.height / 2
(在我的代码 boxHalfHeight
中)-使上半部分可见。然后在 boxHalfHeight
中添加 topMargin
,以使顶部有一定的余量。
You are moving box.center
related to the view.center
- so if you want to move the box to the top, you have to move its center
by half a view's height (because the view's centerY
is exactly height / 2
far from the view's top
). That is not enough though, because then only a bottom half of the box is visible (now the box.centerY == view.top
). Therefore you have to move it back by the box.bounds.height / 2
(in my code boxHalfHeight
) - to make the top half visible. And to that boxHalfHeight
you add topMargin
so that there is some margin to the top.
然后,将框
返回原始位置:
Then, to move the box
back to original position:
UIView.animate(withDuration: 0.2) {
box.transform = CGAffineTransform.identity
}
编辑
如果您确实想使用自动版式,则必须参考 centerY
约束,例如,如果以这种方式创建:
If you really want to go with autolayout, you have to have a reference to the centerY
constraint, so for example if it is created this way:
let boxCenterYConstraint = self.box.centerYAnchor.constraint(equalTo: self.view.centerYAnchor)
boxCenterYConstraint.isActive = true
然后您可以尝试以下操作:
Then you can try this:
// calculating the translation is the same
let topMargin = CGFloat(20)
let viewHalfHeight = self.view.bounds.height / 2
let boxHalfHeight = self.box.bounds.height / 2
let diff = -(viewHalfHeight - (boxHalfHeight + topMargin))
boxCenterYConstraint.constant = diff
self.view.setNeedsLayout()
UIView.animate(withDuration: 0.2) {
self.view.layoutIfNeeded()
}
动画返回:
boxCenterYConstraint.constant = 0
self.view.setNeedsLayout()
UIView.animate(withDuration: 0.2) {
self.view.layoutIfNeeded()
}
这篇关于如何将居中的正方形动画到顶部的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!