Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programmatically Centering UIViews

I've seen a bunch of similar questions to this, but nothing seems to be completely what I'm looking for. Do forgive me if I have missed the solution answered in another question, though!

Right. I have a view. 160 pixels both tall and wide. I know that this view is going to be used as a subview, and I know that it always needs to be centered about both axis in whatever situation it's used.

If defining the view programmatically, how can I be sure that it is always perfectly centered, horizontally and vertically, relative to its superview?

So far, all I have is this simple code:

- (void)loadView {
    self.view = [[UIView alloc] initWithFrame:CGRectMake(80, 150, 160, 160)];
    self.view.backgroundColor = [UIColor greenColor];
    self.view.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
    [self.view release];
}

This does the centralization, but only in the simplest of cases. Any insight is greatly appreciated.

EDIT 1:

With the addition of the following line of code:

 self.view.center = self.view.superview.center;

The subview's center point becomes the (0,0) coordinate of the superview. Perhaps I haven't set up the superview correctly?

like image 640
David Foster Avatar asked Mar 26 '10 16:03

David Foster


4 Answers

In addition to what @Jasarien and @Brad have said, don't forget that you can force auto-centering using the Autosizing springs and struts. Essentially (in Interface Builder) you click around until there are no Autosizing lines visible, like this:

alt text http://gallery.me.com/davedelong/100084/Screen-20shot-202010-03-26-20at-2010-49-18-20AM/web.jpg?ver=12696222220001

In code, you set the -[UIView autoresizingMask] to:

Objective C :

(UIViewAutoresizingFlexibleLeftMargin   | 
 UIViewAutoresizingFlexibleRightMargin  | 
 UIViewAutoresizingFlexibleTopMargin    | 
 UIViewAutoresizingFlexibleBottomMargin)

Swift 3.x :

[.flexibleLeftMargin, .flexibleRightMargin, .flexibleTopMargin, .flexibleBottomMargin]

If you do these, then the view stays centered automatically.

EDIT #1

Answering your edit, you can't do:

self.view.center = self.view.superview.center;

Unless your view has been added as a subview of another view ([anotherView addSubview:self.view];). My guess is that self.view.superview is returning nil, and so you're (luckily) getting {0,0} as the return value when trying to invoke center on nil.

The proper place to center your view would probably be in the viewWillAppear: method of the view controller. Once the view is about to appear, you know that it must have a superview (otherwise how else would it be about to appear?). You could safely set your view's center there.

like image 101
Dave DeLong Avatar answered Nov 05 '22 13:11

Dave DeLong


I'd say the simplest way to do this is to set the center of the view to be at the center of it's superview (which you can obtain from the superview's height and width attributes):

// Init as above and then...
// Get superview's CGSize
CGSize size = self.superview.frame.size;
[self.view setCenter:CGPointMake(size.width/2, size.height/2)];

I don't think you can do the simpler:

self.view.center = self.view.superview.center;

As the superview's center is defined in the superview's superview. Thus the superview could be centered about (0,0), but you wouldn't want to center your view at this point.

Quote from Apple docs:

The center is specified within the coordinate system of its superview

like image 22
pheelicks Avatar answered Nov 05 '22 13:11

pheelicks


Assuming you are inside of a subclass of UIView, you could do this:

-(void) layoutSubviews {
  self.center = self.superview.center;
}

Or, if as above, you are working inside of a ViewController, you could

- (void)loadView {
//...
    self.view.center = self.view.superview.center;
}
like image 3
Brad The App Guy Avatar answered Nov 05 '22 12:11

Brad The App Guy


Brad Smith beat me to the punch, with a slightly more elegant solution :D

Let me know if this isn't what you're looking for, but have you tried:

// when adding to a subview, try this, where myView is the view you need centered,
// and myMainView is the view you'll be adding it to as a subview
myView.center = myMainView.center;
[myMainView addSubview:myView];
like image 1
Jasarien Avatar answered Nov 05 '22 11:11

Jasarien