How to center a subview of UIView

IphoneObjective CIosIpad

Iphone Problem Overview


I have a UIView inside a UIViewm and I want the inner UIView to be always centered inside the outer one, without it having to resize the width and height.

I've set the struts and springs so that it's on top/left/right/bottom without setting the resize. But it still doesn't center. Any idea?

Iphone Solutions


Solution 1 - Iphone

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)

Solution 2 - Iphone

###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)

Solution 3 - Iphone

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

enter image description here

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:

enter image description here

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:

enter image description here

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:

enter image description here

Solution 4 - Iphone

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);

Solution 5 - Iphone

1. If you have autolayout enabled:
  • Hint: For centering a view on another view with autolayout you can use same code for any two views sharing at least one parent view.

First of all disable child views autoresizing

UIView *view1, *view2;
[childview setTranslatesAutoresizingMaskIntoConstraints:NO];
  1. If you are UIView+Autolayout or Purelayout:

     [view1 autoAlignAxis:ALAxisHorizontal toSameAxisOfView:view2];
     [view1 autoAlignAxis:ALAxisVertical toSameAxisOfView:view2];
    
  2. If you are using only UIKit level autolayout methods:

     [view1 addConstraints:({
         @[ [NSLayoutConstraint
            constraintWithItem:view1
            attribute:NSLayoutAttributeCenterX
            relatedBy:NSLayoutRelationEqual
            toItem:view2
            attribute:NSLayoutAttributeCenterX
            multiplier:1.f constant:0.f],
    
            [NSLayoutConstraint
             constraintWithItem:view1
             attribute:NSLayoutAttributeCenterY
             relatedBy:NSLayoutRelationEqual
             toItem:view2
             attribute:NSLayoutAttributeCenterY
             multiplier:1.f constant:0.f] ];
     })];
    
2. Without autolayout:

I prefer:

UIView *parentView, *childView;
[childView setFrame:({
    CGRect frame = childView.frame;
   
    frame.origin.x = (parentView.frame.size.width - frame.size.width) / 2.0;
    frame.origin.y = (parentView.frame.size.height - frame.size.height) / 2.0;

    CGRectIntegral(frame);
})];

Solution 6 - Iphone

The easiest way:

child.center = parent.center

Solution 7 - Iphone

You can use

yourView.center = CGPointMake(CGRectGetMidX(superview.bounds), CGRectGetMidY(superview.bounds))

And In Swift 3.0

yourView.center = CGPoint(x: superview.bounds.midX, y: superview.bounds.midY)

Solution 8 - Iphone

enter image description here

Set this autoresizing mask to your inner view.

Solution 9 - Iphone

With IOS9 you can use the layout anchor API.

The code would look like this:

childview.centerXAnchor.constraintEqualToAnchor(parentView.centerXAnchor).active = true
childview.centerYAnchor.constraintEqualToAnchor(parentView.centerYAnchor).active = true

The advantage of this over CGPointMake or CGRect is that with those methods you are setting the center of the view to a constant but with this technique you are setting a relationship between the two views that will hold forever, no matter how the parentview changes.

Just be sure before you do this to do:

        self.view.addSubview(parentView)
        self.view.addSubView(chidview)

and to set the translatesAutoresizingMaskIntoConstraints for each view to false.

This will prevent crashing and AutoLayout from interfering.

Solution 10 - Iphone

Using the same center in the view and subview is the simplest way of doing it. You can do something like this,

UIView *innerView = ....;
innerView.view.center = self.view.center;
[self.view addSubView:innerView];

Solution 11 - Iphone

Another solution with PureLayout using autoCenterInSuperview.

// ...
UIView *innerView = [UIView newAutoLayoutView];
innerView.backgroundColor = [UIColor greenColor];
[innerView autoSetDimensionsToSize:CGSizeMake(100, 30)];

[outerview addSubview:innerView];

[innerView autoCenterInSuperview];

This is it how it looks like:

Center with PureLayout

Solution 12 - Iphone

In c# or Xamarin.ios, we can use like this

imageView.Center = new CGPoint(tempView.Frame.Size.Width / 2, tempView.Frame.Size.Height / 2);

Solution 13 - Iphone

This worked for me

childView.centerXAnchor.constraint(equalTo: parentView.centerXAnchor).isActive = true
childView.centerYAnchor.constraint(equalTo: parentView.centerYAnchor).isActive = true

Solution 14 - Iphone

I would use:

child.center = CGPointMake(parent.bounds.height / 2, parent.bounds.width / 2)

This is simple, short, and sweet. If you use @Hejazi's answer above and parent.center is set to anything other than (0,0) your subview will not be centered!

Solution 15 - Iphone

func callAlertView() {
    
    UIView.animate(withDuration: 0, animations: {
        let H = self.view.frame.height * 0.4
        let W = self.view.frame.width * 0.9
        let X = self.view.bounds.midX - (W/2)
        let Y = self.view.bounds.midY - (H/2)
        self.alertView.frame = CGRect(x:X, y: Y, width: W, height: H)
        self.alertView.layer.borderWidth = 1
        self.alertView.layer.borderColor = UIColor.red.cgColor
        self.alertView.layer.cornerRadius = 16
        self.alertView.layer.masksToBounds = true
        self.view.addSubview(self.alertView)
        
    })
    
    
}// calculation works adjust H and W according to your requirement

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionxonegirlzView Question on Stackoverflow
Solution 1 - IphoneHejaziView Answer on Stackoverflow
Solution 2 - Iphonehappy pigView Answer on Stackoverflow
Solution 3 - IphoneDaniel KromView Answer on Stackoverflow
Solution 4 - IphonetheprojectabotView Answer on Stackoverflow
Solution 5 - IphoneCemal EkerView Answer on Stackoverflow
Solution 6 - IphonejuancazallaView Answer on Stackoverflow
Solution 7 - IphoneSayali ShindeView Answer on Stackoverflow
Solution 8 - IphoneMayank JainView Answer on Stackoverflow
Solution 9 - IphoneFoobarView Answer on Stackoverflow
Solution 10 - IphonecodeFoodView Answer on Stackoverflow
Solution 11 - IphoneH6.View Answer on Stackoverflow
Solution 12 - IphoneAnisetti NagendraView Answer on Stackoverflow
Solution 13 - IphoneKamyFCView Answer on Stackoverflow
Solution 14 - IphoneOld NameView Answer on Stackoverflow
Solution 15 - IphoneSidd RedkarView Answer on Stackoverflow