How to center a subview of UIView
You can do this and it will always work:
child.center = [parent convertPoint:parent.center fromView:parent.superview];
And for Swift:
child.center = parent.convert(parent.center, from:parent.superview)
I would use:
self.childView.center = CGPointMake(CGRectGetMidX(self.parentView.bounds),
CGRectGetMidY(self.parentView.bounds));
I like to use the CGRect
options...
SWIFT 3:
self.childView.center = CGPoint(x: self.parentView.bounds.midX,
y: self.parentView.bounds.midY);
Objective-C
yourSubView.center = CGPointMake(yourView.frame.size.width / 2,
yourView.frame.size.height / 2);
Swift
yourSubView.center = CGPoint(x: yourView.frame.size.width / 2,
y: yourView.frame.size.height / 2)
Before we'll begin, let's just remind that origin point is the Upper Left corner CGPoint
of a view.
An important thing to understand about views and parents.
Lets take a look at this simple code, a view controller that adds to it's view a black square:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
createDummyView()
super.view.backgroundColor = UIColor.cyanColor();
}
func createDummyView(){
var subView = UIView(frame: CGRect(x: 15, y: 50, width: 50 , height: 50));
super.view.addSubview(subView);
view.backgroundColor = UIColor.blackColor()
}
}
This will create this view: the black rectangle origin and center does fit the same coordinates as it's parent
Now let's try to add subView another SubSubView, and giving subSubview same origin as subView, but make subSubView a child view of subView
We'll add this code:
var subSubView = UIView();
subSubView.frame.origin = subView.frame.origin;
subSubView.frame.size = CGSizeMake(20, 20);
subSubView.backgroundColor = UIColor.purpleColor()
subView.addSubview(subSubView)
And this is the result:
Because of this line:
subSubView.frame.origin = subView.frame.origin;
You expect for the purple rectangle's origin to be same as it's parent (the black rectangle) but it goes under it, and why is that? Because when you add a view to another view, the subView frame "world" is now it's parent BOUND RECTANGLE, if you have a view that it's origin on the main screen is at coords (15,15) for all it's sub views, the upper left corner will be (0,0)
This is why you need to always refer to a parent by it's bound rectangle, which is the "world" of it's subViews, lets fix this line to:
subSubView.frame.origin = subView.bounds.origin;
And see the magic, the subSubview is now located exactly in it's parent origin:
So, you like "ok I only wanted to center my view by my parents view, what's the big deal?" well, it isn't big deal, you just need to "translate" the parent Center point which is taken from it's frame to parent's bounds center by doing this:
subSubView.center = subView.convertPoint(subView.center, fromView: subSubView);
You're actually telling him "take parents view center, and convert it into subSubView world".
And you'll get this result: