问题
I have a UIView
(popup
) and multiple UIButton
s (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 UIView
s 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 NSLayoutConstraint
s 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