如何将居中的正方形动画到顶部 [英] How to animate centered square to the top

查看:102
本文介绍了如何将居中的正方形动画到顶部的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在仅提供肖像的应用程序中具有 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆