Подтвердить что ты не робот

Программно центрирование UIViews

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

Right. У меня есть точка зрения. 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];
}

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

EDIT 1:

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

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

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

4b9b3361

Ответ 1

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

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

В коде вы установите для параметра -[UIView autoresizingMask] значение:

(UIViewAutoresizingFlexibleLeftMargin   | 
 UIViewAutoresizingFlexibleRightMargin  | 
 UIViewAutoresizingFlexibleTopMargin    | 
 UIViewAutoresizingFlexibleBottomMargin)

Если вы сделаете это, тогда просмотр будет автоматически центрирован.

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

Отвечая на ваше редактирование, вы не можете:

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

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

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

Ответ 2

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

// Init as above and then...
// Get superview 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

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

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

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

- (void)loadView {
//...
    self.view.center = self.view.superview.center;
}

Ответ 4

Брэд Смит победил меня до удара, немного более элегантным решением: 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];

Ответ 5

У меня была такая же проблема. Каждый раз, когда я пытался получить доступ к 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.