Auto Layout center UIView above another UIView at its center

孤街浪徒 提交于 2020-01-06 01:32:12

问题


I have a UIView (popup) and multiple UIButtons (sender). If I touch the sender I would like to center the popup at the coordinates of the sender.

However, as of Auto Layout the popup always moves back to the initial position at refresh. I understand that I have to use constraints and change those programmatically.

Unfortunately I don't know how I can adjust below code with constraints. Especially as the popup is larger as the sender.

Could anybody give me some advice on how to move UIViews center at sender's center with Auto Layout enabled ? Thanks!!

Here is a screen image of below code that shows the issue:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var number: UIImageView!
    @IBOutlet weak var popup: UIView!

    @IBAction func openPopup(sender: UIButton) {
        self.popup.center = sender.center
        //old position: (190.5, 124.0) - new Position: (173.0, 414.0)
    }

    @IBAction func updateImage(sender: UIButton) {
        self.number.image = UIImage(named: "img-1")
    }
}

Here is what I have so far, but I don't know if this is correct and what type of NSLayoutConstraint I have to use to achieve this:

import UIKit

class ViewController: UIViewController {

    var id = 1
    @IBOutlet weak var number: UIImageView!
    @IBOutlet weak var popup: UIView!

    @IBOutlet weak var popupy: NSLayoutConstraint!
    @IBOutlet weak var popupx: NSLayoutConstraint!

    @IBAction func openPopup(sender: UIButton) {

    popupx.constant = reposition(popup, position: sender.center).y
    popupy.constant = reposition(popup, position: sender.center).x

    }

    @IBAction func updateImage(sender: UIButton) {
        if id == 1 {
            id = 2
        }else {
            id = 1
        }

        self.number.image = UIImage(named: "\(id)")

    }


    func reposition (element: UIView, position: CGPoint)->CGPoint
    {
        var p = CGPoint()

        p.x = position.x - (element.frame.size.height / 2 )
        p.y = position.y - (element.frame.size.width / 2)

        return p
    }
}

回答1:


Since you want to center your view relative to different views over time, one way to do that is to add and remove constraints as needed.

The following code creates NSLayoutConstraints to center the view relative to another view:

class ViewController: UIViewController {

    @IBOutlet weak var boxView: UIView!
    var boxCenterX: NSLayoutConstraint?
    var boxCenterY: NSLayoutConstraint?

    func centerBoxOnView(v: UIView) {
        // Remove previous constraints on center, if any
        boxCenterX?.active = false
        boxCenterY?.active = false

        boxCenterX = NSLayoutConstraint(item: boxView, attribute: .CenterX,
            relatedBy: .Equal, toItem: v, attribute: .CenterX,
            multiplier: 1, constant: 0)
        boxCenterX?.active = true

        boxCenterY = NSLayoutConstraint(item: boxView, attribute: .CenterY,
            relatedBy: .Equal, toItem: v, attribute: .CenterY,
            multiplier: 1, constant: 0)
        boxCenterY?.active = true

        self.view.layoutIfNeeded()
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Start box at center of screen
        centerBoxOnView(self.view)
    }

    @IBAction func buttonPressed(button: UIButton) {
        centerBoxOnView(button)
    }
}

When you set up the constraints for the boxView (the view you are moving around), make sure the centerX and centerY constraints you create in the Storyboard are marked as Placeholder so that they will be removed at build time and not interfere with the constraints created in code.


If you want the view to be animated into place, replace:

self.view.layoutIfNeeded()

with:

UIView.animateWithDuration(1) {
    self.view.layoutIfNeeded()
}



回答2:


Instead of changing self.popup.center you should make an IBOutlet for the layoutconstraint and change the constant of that constraint to place the popup.

Alternatively you can try setting translatesAutoresizingMaskIntoConstraints = true and using .frame = to change the position. That should translate the frame changes to auto layout constraints. This might create issues as you already have auto layout constraints active that conflicts with the new ones though so I would recommend going with the IBOutlet for constraints solution.



来源:https://stackoverflow.com/questions/33720197/auto-layout-center-uiview-above-another-uiview-at-its-center

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!