2010-04-19 4 views
5

Каков наилучший способ позиционирования представления относительно размера его супервизора, когда границы супервизора еще не известны?Как я могу программно позиционировать представление с помощью относительных точек?

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

Я столкнулся с этим много раз при работе с пользовательским интерфейсом. Самый последний пример - это то, что я пытаюсь заменить заголовок обычного текста UINavigationItem специальным представлением. Я хочу, чтобы это представление заполнило супервизор, но, кроме того, я хочу, чтобы UIActivityIndicatorView с правой стороны, вставка около 2 пикселей и по центру по вертикали. Вот код:

- (void) viewDidLoad 
{ 
    [super viewDidLoad]; 

    customTitleView = [[UIView alloc] initWithFrame:CGRectZero]; 
    customTitleView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 

    titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 
    titleLabel.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 
    titleLabel.lineBreakMode = UILineBreakModeWordWrap; 
    titleLabel.numberOfLines = 2; 
    titleLabel.minimumFontSize = 11.0; 
    titleLabel.font = [UIFont systemFontOfSize:17.0]; 
    titleLabel.adjustsFontSizeToFitWidth = YES; 
    [customTitleView addSubview:titleLabel]; 

    spinnerView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; 
    spinnerView.center = CGPointMake(customTitleView.bounds.size.width - (spinnerView.bounds.size.width/2) - 2, 
            customTitleView.bounds.size.height/2); 
    spinnerView.hidesWhenStopped = YES; 
    [customTitleView addSubview:spinnerView]; 

    self.navigationItem.titleView = customTitleView; 
    [customTitleView release]; 
} 

Вот моя проблема: в то время, что этот код работает, customTitleView.bounds еще нули. Маска автоматического изменения размера еще не успела сделать свое дело, но мне очень нужны эти значения, чтобы я мог вычислить относительные позиции других под-представлений (здесь, индикатор активности).

Возможно ли это, не будучи уродливым?

+0

'' titleLabel' и spinnerView' оба просочились объекты –

+0

+1 на вопрос, как у меня точно такой же один - с нетерпением жду, чтобы прочитать ответы – Till

+1

'' titleLabel' и spinnerView' не просочились. Они выпущены в другом месте. –

ответ

4

Единственная причина, по которой customTitleView.bounds имеет нулевую ширину и высоту, потому что вы инициализировали ее таким образом, используя CGRectZero. Вы можете инициализировать представление с любым ненулевым размером, а затем определить его subviews относительно этого произвольного размера. До тех пор, пока вы правильно определяете поведение авторезистентности подвью, их макет будет соответствующим образом скорректирован, когда кадр надзора изменится во время выполнения.

Например:

- (void) viewDidLoad 
{ 
    [super viewDidLoad]; 

    customTitleView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 100.0f)]; 
    customTitleView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 

    titleLabel = [[UILabel alloc] initWithFrame:customTitleView.bounds]; 
    titleLabel.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 
    titleLabel.lineBreakMode = UILineBreakModeWordWrap; 
    titleLabel.numberOfLines = 2; 
    titleLabel.minimumFontSize = 11.0; 
    titleLabel.font = [UIFont systemFontOfSize:17.0]; 
    titleLabel.adjustsFontSizeToFitWidth = YES; 
    [customTitleView addSubview:titleLabel]; 
    [titleLabel release]; 

    spinnerView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; 
    spinnerView.center = CGPointMake(customTitleView.bounds.size.width - (spinnerView.bounds.size.width/2) - 2, 
            customTitleView.bounds.size.height/2); 
    spinnerView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; 
    spinnerView.hidesWhenStopped = YES; 
    [customTitleView addSubview:spinnerView]; 
    [spinnerView release]; 

    self.navigationItem.titleView = customTitleView; 
    [customTitleView release]; 
} 
+1

Спасибо. Мне не хватало двух ключевых моментов. Во-первых, содержащее представление требует определенного размера, предположительно, чтобы поведение макета могло сделать разумный выбор. Во-вторых, счетчик не установил свой 'autoresizingMask' для использования полей (сверху, снизу и слева, чтобы заставить его придерживаться правой стороны). –

Смежные вопросы