如果我设置不同的约束,我的UIView不会改变的任何原因?

时间:2017-03-14 17:29:45

标签: ios swift uiview

我在普通的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秒的上滑动画弹出它?

3 个答案:

答案 0 :(得分:1)

  

"这就是我想要的:我想改变的UIView高度为   * 0.25的根视图。我希望我的UIView正好在我的根视图的边界之外,所以它需要是根视图的25%   高度,然后是一个约束的运动,将推动我的UIView   向下"

这正是自动布局和约束的用途,因此您不必经常计算尺寸。

使用约束" pin"您对超级视图左侧,右侧和底部的视图,然后将其高度设置为超级视图高度,乘数(比率)为1:4

这将使其高度保持在"根视图的#25;并将保持"卡住"到底。

enter image description here

无需代码:)

要为视图输入和输出设置动画,将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)