Программно центрирование UIViews - PullRequest
31 голосов
/ 26 марта 2010

Я видел кучу похожих вопросов на это, но, похоже, ничего не совсем то, что я ищу. Прошу прощения, если я пропустил решение, на которое дан ответ в другом вопросе!

правый. У меня есть вид. 160 пикселей в высоту и ширину. Я знаю, что это представление будет использоваться как подпредставление, и я знаю, что его всегда необходимо центрировать вокруг обеих осей в любой ситуации, в которой оно используется.

Если программно определить вид, как я могу быть уверен, что он всегда идеально отцентрирован по горизонтали и вертикали относительно его суперпредставления?

Пока все, что у меня есть, это простой код:

- (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];
}

Это делает централизацию, но только в простейших случаях. Любое понимание очень ценится.

РЕДАКТИРОВАТЬ 1:

С добавлением следующей строки кода:

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

Центральная точка подпредставления становится (0,0) координатой суперпредставления. Возможно, я не настроил суперпредставление правильно?

Ответы [ 5 ]

47 голосов
/ 26 марта 2010

В дополнение к тому, что сказали @Jasarien и @Brad, не забывайте, что вы можете форсировать автоцентрирование, используя пружины и распорки Autosizing. По сути (в Интерфейсном Разработчике) вы щелкаете мышью, пока не останется видимых линий Авторазмера, например:

альтернативный текст http://gallery.me.com/davedelong/100084/Screen-20shot-202010-03-26-20at-2010-49-18-20AM/web.jpg?ver=12696222220001

В коде вы устанавливаете -[UIView autoresizingMask] на:

Цель C:

(UIViewAutoresizingFlexibleLeftMargin   | 
 UIViewAutoresizingFlexibleRightMargin  | 
 UIViewAutoresizingFlexibleTopMargin    | 
 UIViewAutoresizingFlexibleBottomMargin)

Swift 3.x:

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

Если вы сделаете это, то изображение останется центрированным автоматически.

РЕДАКТИРОВАТЬ # 1

Отвечая на ваши изменения, вы не можете сделать:

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

Если ваш вид не был добавлен как подпредставление другого вида ([anotherView addSubview:self.view];). Я предполагаю, что self.view.superview возвращает nil, и поэтому (к счастью) вы получаете {0,0} в качестве возвращаемого значения при попытке вызвать center для nil.

Правильное место для центрирования вашего вида, вероятно, будет в viewWillAppear: методе контроллера вида. Как только представление должно появиться, вы знаете, что оно должно иметь суперпредставление (иначе, как еще оно должно появиться?). Вы можете смело установить там center вашего вида.

41 голосов
/ 26 марта 2010

Я бы сказал, что самый простой способ сделать это - установить центр вида в центр его суперпредставления (которое можно получить из атрибутов высоты и ширины суперпредставления):

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

Я не думаю, что вы можете сделать проще:

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

Поскольку центр суперпредставления определен в суперпредставлении суперпредставления.Таким образом, суперпредставление может быть сосредоточено около (0,0), но вы не захотите центрировать свое представление в этой точке.

Цитата из Apple docs:

Центруказанный в системе координат его суперпредставления

3 голосов
/ 26 марта 2010

Предполагая, что вы находитесь в подклассе UIView, вы можете сделать это:

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

Или, если, как указано выше, вы работаете внутри ViewController, вы можете

- (void)loadView {
//...
    self.view.center = self.view.superview.center;
}
1 голос
/ 26 марта 2010

Брэд Смит победил меня с помощью более элегантного решения: D

Дайте мне знать, если это не то, что вы ищете, но пытались ли вы:

// 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];
0 голосов
/ 14 апреля 2010

У меня была такая же проблема. Каждый раз, когда я пытался получить доступ к self.view.superview или self.view.window в viewDidLoad, они возвращали ноль. В viewDidLoad (я думаю, это то же самое для loadView) эти указатели еще не инициализированы. Чтобы решить эту проблему, я могу дать вам хитрость:

- (void)viewDidLoad 
{
    [super viewDidLoad];

    // both equal to nil
    id lwindow = self.view.window;
    id lparent = self.view.superview;

    [self performSelector:@selector(myViewDidLoad) withObject:nil afterDelay:0.01];
}

- (void)myViewDidLoad
{
    // both not equal to nil!
    id lwindow = self.view.window;
    id lparent = self.view.superview;
} 

Похоже, что self.view.parent и self.view.window инициализируются после viewDidLoad и loadView.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...