如何将居中的方块设置为顶部

时间:2017-11-16 06:53:05

标签: ios swift animation autolayout constraints

我在纵向应用中有UIView

  • 视图垂直居中水平 AutoLayout("手动"使用故事板)。
  • width等于(main)view.width * 0.9
  • height与宽度大小相同(为正方形)。

我想点按此UIView内的一个按钮,并垂直制作它,直到它到达屏幕的顶部边框(例如,高度* 0.9,10点,无论什么可能)。

当我再次点击时,我想将视图重新定位到其原始位置(居中于我第一次点击时)。

在过渡期间,广场不应该是可点击的。

在阅读了很多帖子后,我无法理解最好的方法是什么(我主要是开发人员说使用centerX的旧技术应该避免,并且对某些版本的SO表现出奇怪的哀叹方式)。

我想我应该找到一种方法来获得当前的#34;位置"约束和分配约束" final"位置,但我无法做到。

感谢任何帮助

2 个答案:

答案 0 :(得分:0)

虽然您可以使用Autolayout进行动画处理 - 采用限制centerY的约束并将其常量设置为可移动到顶部的值(例如constant = -(UIScreen.main.bounds.height / 2)),我建议使用view' s 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

修改

如果您真的想要使用自动布局,则必须引用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()
}

然后你可以试试这个:

boxCenterYConstraint.constant = 0
self.view.setNeedsLayout()
UIView.animate(withDuration: 0.2) {
    self.view.layoutIfNeeded()
}

动画回来了:

GROUP BY

答案 1 :(得分:0)

你们都错了。

添加一个将视图固定到顶部的约束,并添加一个约束,将视图固定到centerY。它会抱怨,所以选择一个并禁用它(我认为Interface Builder中的属性称为Installed)。

如果初始状态是中心的视图,请禁用将其固定到顶部的约束,反之亦然。

现在为控制器中的两个约束编写IBOutlets并将它们连接到这些约束。确保该变量的声明不是weak,否则当禁用约束时变量将变为nil。

每当您想要切换动画时,您可以启用一个约束并禁用另一个约束。

@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()
  }
}