2015-06-24 2 views
0

Использование автозапуска Я хочу понять, почему происходит следующее: Создание простой UIButton и настройка ее названия. Однако, несмотря на то, что я ожидаю, что внутренний размер содержимого представления будет установлен и, следовательно, правильно получить его фрейм, отображается рамка кнопки (0, 0, 0, 0). Что мне нужно сделать, чтобы получить значение фрейма кнопки?iOS: Размер автозапуска UIButton равен нулю

-(void)viewDidLoad { 

    [super viewDidLoad]; 

    UIButton *button = [[UIButton alloc] init]; 

    [button.titleLabel setText:@"My button"]; 

    //button frame is zero 

} 

Но если я сделать это, то все работает, как ожидалось:

-(void)viewDidLoad { 

    [super viewDidLoad]; 

    UILabel *label = [[UILabel alloc] init]; 

    [label setText:@"My label"]; 

    [label sizeToFit]; 

    //label frame has the expected width and height 

} 
+0

Вы не установили размер, тогда он всегда равен нулю. !! –

+0

Я не устанавливаю размер, так как я использую Autolayout. Имея код выше - я ожидаю, что на нем будет кнопка с заголовком «Моя кнопка». – Petar

+0

В автозапуске вы должны установить ограничения –

ответ

2

Autolayout устанавливает рамки кадров только после прохода макета, это то, что имеет цикл и не называется evertimetime, когда вы добавляете представление или изменяете ограничения, поэтому иногда вам нужно вызвать -setNeedsLayout на конкретном представлении.
Другое дело, что если вы не создаете ограничений с помощью конструктора интерфейса или программно, автоопределение автоматически преобразует маски аурезизации представления в ограничения (свойство -translatesAutoresizingMaskIntoConstraints).
В этом случае, если вы установите текст, вы вынуждаете представление выражать свой собственный размер содержимого, в основном это размер метки, если внутренний размер содержимого не конфликтует с другими ограничениями, которые он выигрывает, но вы можете задайте размер кнопки после прохода макета. Попробуйте проверить размер кнопки внутри .viewDidLayout после вызова одного и того же метода суперкласса

+0

Да, я понимаю, однако, похоже, что UIButton не имеет своего внутреннего размера контента, применяемого на этом этапе. Добавление кнопки в основное представление и печать ее размера на 'viewDidLayoutSubviews' показывает 0 0 снова ... – Petar

+0

Вызывается [super viewDidLayoutSubviews]?попробуйте попросить setNeedsLayout на главном представлении после добавления метки – Andrea

+0

@ pe60t0 Если вы не добавите метку в качестве подзаголовка, она не будет проходить в вычислении автоопределения – Andrea

0

Добавить кнопку как вид к югу и вызвать layoutIfNeeded на подвид. После этого получите доступ к его кадру.

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

+0

Я могу понять, что представление должно иметь супервизор чтобы механизм компоновки вычислил свой кадр. Однако я не понимаю, что если вместо использования кнопки я использую метку в приведенном выше примере, тогда размер метки - это то, что я ожидаю (после вызова 'sizeThatFits'). Я предполагаю, что intininsContentSize как UILabel, так и UIButton будут работать одинаково? – Petar

1
- (void)viewDidLoad { 
    [super viewDidLoad]; 

    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem]; 
    button.translatesAutoresizingMaskIntoConstraints = NO; 
    [button setTitle:@"My button" forState:UIControlStateNormal]; 
    [self.view addSubview:button]; 
} 

- (void)viewDidLayoutSubviews { 
    //check frame of button 
} 
1

Как @Andrea сказал: потому что вы не добавили кнопку в IB, то недобросовестный с помощью autoResizingMask , который сохранит нулевой размер кадра, который инициализируется кнопкой.

Если вы хотите autolayout работать, вам необходимо установить

button.translatesAutoresizingMaskIntoConstraints = NO; 

прямо перед вызовом -addSubview:.

Кроме того, вам необходимо добавить по крайней мере 1 горизонтальное ограничение и 1 вертикальное ограничение, чтобы поместить кнопку. Даже после этого кадр кнопки будет установлен только после следующего прохода макета, который вы можете инициировать вручную, вызывая -layoutIfNeeded.

+0

Но это не так - кнопка должна иметь свой собственный размер содержимого, определенный независимо от его положения в иерархии представлений – Petar

+1

@ pe60t0 да, он должен иметь внутренний атрибутContentSize, но ограничения autoResizingMask имеют приоритет над этим. Если вы отключите autoResizingMask, он начнет работать. SizeToFit работал для вас, потому что он вручную устанавливает кадр в intrinsicContentSize, но теперь, даже если содержимое (то есть название или изображение) изменяется, размер не будет обновляться автоматически. –