如何将居中的方形设置为顶部
我有一个只有肖像的应用程序UIView
。
- 视图以垂直和水平方向 居中 放置
AutoLayout
(使用故事板“手动”)。 -
width
等于(main)view.width * 0.9
-
height
是相同的宽度(这是一个正方形)的大小。
我想在这个UIView
里面点击一个button,并且只是垂直地animation它,直到它到达屏幕的顶部边界(例如height * 0.9,10 pts,无论怎样)。
当我再次点击时,我想重新定位视图到原来的位置(居中,就像我第一次点击时那样)。
在过渡期间,广场不应该放倒。
在阅读了很多post后,我无法理解这样做的最好方法是什么(我主要是开发者说使用centerX
旧技术应该避免,并且对某些版本的SO以奇怪的方式performance感到悲叹)。
我想我应该find一种方法来获得约束的当前“位置”,并将约束分配给“最终”位置,但是我无法做到这一点。
任何帮助表示赞赏
虽然你可以使用Autolayoutanimation – 约束约束中心Y和设置其常数值将移动到顶部(例如, constant = -(UIScreen.main.bounds.height / 2)
),我会build议使用视图的transform
属性。
所以要将视图移动到顶端,您可以使用:
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))) }
你正在移动与box.center
相关的view.center
– 所以如果你想要移动框到顶端,你必须移动它的center
一半的视图的高度(因为视图的中心centerY
是height / 2
远离视图top
)。 这是不够的,因为那么只有框的下半部分是可见的(现在box.centerY == view.top
)。 因此,您必须将其移回box.bounds.height / 2
(在我的代码boxHalfHeight
) – 使上半部分可见。 而对于boxHalfHeight
你添加topMargin
以便有一些边缘的顶部。
然后,将box
移回到原来的位置:
UIView.animate(withDuration: 0.2) { box.transform = CGAffineTransform.identity }
编辑
如果你真的想要自动布局,你必须有一个centerY
约束的引用,例如,如果它是这样创build的:
let boxCenterYConstraint = self.box.centerYAnchor.constraint(equalTo: self.view.centerYAnchor) boxCenterYConstraint.isActive = true
那么你可以试试这个:
// 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() }
和animation回来:
boxCenterYConstraint.constant = 0 self.view.setNeedsLayout() UIView.animate(withDuration: 0.2) { self.view.layoutIfNeeded() }
这一切都是错误的。
添加一个将视图固定到顶部的约束,并添加一个将视图固定到centerY
。 它会抱怨,所以select一个并禁用它(我认为Interface Builder中的属性被称为Installed
)。
如果初始状态是中间的视图,则禁用将其固定到顶部的约束,反之亦然。
现在在您的控制器中为这两个约束编写IBOutlets并将它们连接到这些约束。 确保该variables的声明不weak
,否则当约束被禁用时variables将变为零。
每当你想切换你的animation,你可以启用一个约束,禁用另一个。
@IBOutlet var topConstraint: NSLayoutConstraint! @IBOutlet var centerConstraint: NSLayoutConstraint! func toggleState(moveToTop: Bool) { UIView.animateWithDuration(0.25) { self.topConstraint.isActive = moveToTop self.centerConstraint.isActive = !moveToTop self.view.layoutIfNeeded() } }