我在普通的UIView中有一个UIView。这是我的代码:
override func viewDidAppear(_ animated: Bool) {
print(canvasUnder.frame.origin.y)
let getRelativePosition = view.frame.size.height * 0.25
canvasUnder.frame.origin.y = canvasUnder.frame.origin.y + getRelativePosition
self.view.layoutIfNeeded()
print(canvasUnder.frame.origin.y)
print(getRelativePosition)
}
然而它确实保持在原始位置。这是我的印刷品:
240.0
320.0
80.0
这怎么可能?谢谢。编辑:这就是我想要的:我想要改变的UIView的根视图高度为* 0.25。我希望我的UIView在我的根视图的边界之外,所以它需要是根视图高度的25%,然后是一个约束的移动,这将推动我的UIView。
编辑2:我设法以这种方式:
override func viewDidLayoutSubviews() {
print("called")
let getRelativePosition = view.frame.size.height * 0.25
self.CanvasUnder.frame.origin.y = self.CanvasUnder.frame.origin.y + getRelativePosition
}
然而,每次发生变化时都会调用此方法。我只是希望我的canvasUnder在显示视图时就在屏幕右侧。然后,每当我想要时,我想要动画那个UIView弹出。我想使用这段代码:
let getRelativePosition = view.frame.size.height * 0.25
self.CanvasUnder.frame.origin.y = self.CanvasUnder.frame.origin.y - getRelativePosition
UIView.animate(withDuration: 1.0, animations: {
self.view.layoutIfNeeded()
})
或者将帧的更改置于animate函数内是行不通的。它只是一直触发viewDidLayoutSubviews方法,它会再次隐藏我的UIView。
那么我怎样才能在我的根视图下隐藏该视图,然后用一个需要1秒的上滑动画弹出它?
答案 0 :(得分:1)
"这就是我想要的:我想改变的UIView高度为 * 0.25的根视图。我希望我的UIView正好在我的根视图的边界之外,所以它需要是根视图的25% 高度,然后是一个约束的运动,将推动我的UIView 向下"
这正是自动布局和约束的用途,因此您不必经常计算尺寸。
使用约束" pin"您对超级视图左侧,右侧和底部的视图,然后将其高度设置为超级视图高度,乘数(比率)为1:4
这将使其高度保持在"根视图的#25;并将保持"卡住"到底。 p>
无需代码:)
要为视图输入和输出设置动画,将IBOutlet添加到Bottom约束,并使用此代码......
class TestViewController: UIViewController {
@IBOutlet weak var trayBottomView: UIView!
@IBOutlet weak var trayBottomConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// hide the "tray" view
trayBottomView.isHidden = true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// constraints and frame sizes are fully calculated by AutoLayout here, so...
// move the tray offscreen (below the view), and "un-hide" it
self.trayBottomConstraint.constant = -self.trayBottomView.frame.height
self.trayBottomView.isHidden = false
// this first part will just put the tray view into position, below the screen
UIView.animate(withDuration: 0.01, animations: {
self.view.layoutIfNeeded()
}, completion: { (finished: Bool) in
// now, set the tray Bottom constraint to 0, so it will end up "sitting" on the bottom of the screen
self.trayBottomConstraint.constant = 0
// animate it into view - use delay to "wait a bit" before sliding the view up
// duration of 0.75 (3/4 of a second) may be too slow, just tweak as desired
UIView.animate(withDuration: 0.75, delay: 0.25, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.view.layoutIfNeeded()
}, completion: nil)
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func buttonTapped(_ sender: Any) {
// if the tray Bottom Constraint is Zero, that means it is visible, so
// set it to -(its own height) to position it offscreen, below the view
// otherwise, it is already offscreen, so set it to Zero to bring it back up
if self.trayBottomConstraint.constant == 0 {
self.trayBottomConstraint.constant = -self.trayBottomView.frame.height
} else {
self.trayBottomConstraint.constant = 0
}
// animate it in or out of view
// duration of 0.75 (3/4 of a second) may be too slow, just tweak as desired
UIView.animate(withDuration: 0.75, delay: 0.0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.view.layoutIfNeeded()
})
}
}
答案 1 :(得分:1)
如果设置不同的约束,我的UIView不会改变的原因是什么?
您不更改约束。你在说canvasUnder.frame.origin.y
。这不是约束的变化。这是frame
的变化。但是如果视图是通过约束定位的,那么无法直接更改框架!约束是视图的定位,而不是框架。
这怎么可能?
因为你改变了框架,它确实在那个小时刻发生了变化。但是当你看到视图时,约束已经将它改回来了!
答案 2 :(得分:0)
当你调用self.view.layoutIfNeeded()时,它会触发你的视图重新布局。它是通过viewWillLayoutSubviews / viewDidLayoutSubviews函数中的自动布局或布局代码移动的。
而不是直接更新帧,更新约束,例如:
canvasUnderHeightConstraint.constant = view.frame.size.height * 0.25
或者,更好的解决方案是使用约束的乘数字段来获得所需的结果。
NSLayoutConstraint(item: view,
attribute: .height,
relatedBy: .equal,
toItem: canvasUnder,
attribute: .height,
multiplier: 0.25,
constant: 0)