Программно центрирование 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) супервизора. Возможно, я неправильно настроил надзор?
Ответы
Ответ 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.