iOS: изменение размера UIButton в соответствии с длиной текста - PullRequest
121 голосов
/ 09 ноября 2010

В конструкторе интерфейсов удерживание Command + = изменит размер кнопки, чтобы соответствовать ее тексту.Мне было интересно, если это было возможно сделать программно, прежде чем кнопка была добавлена ​​в представление.

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button.titleLabel setFont:[UIFont fontWithName:@"Arial-BoldMT" size:12]];
[button addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
// I need to know the width needed to accomodate NSStringVariable
[button setTitle:NSStringVariable forState:UIControlStateNormal]; 
// So that I can set the width property of the button before addSubview
[button setFrame:CGRectMake(10, 0, width, fixedHeight)];
[subNavigation addSubview:button];

Ответы [ 12 ]

126 голосов
/ 09 ноября 2010

В UIKit есть дополнения к классу NSString, чтобы получить от заданного объекта NSString размер, который он примет при визуализации определенным шрифтом.

Документы были здесь . Теперь он здесь под устаревшим.

Короче, если вы идете:

CGSize stringsize = [myString sizeWithFont:[UIFont systemFontOfSize:14]]; 
//or whatever font you're using
[button setFrame:CGRectMake(10,0,stringsize.width, stringsize.height)];

... вы установили для рамки кнопки высоту и ширину отрисовываемой строки.

Возможно, вы захотите поэкспериментировать с некоторым буферным пространством вокруг этого CGSize, но вы начнете с правильного места.

96 голосов
/ 25 января 2012

Способ сделать это в коде:

[button sizeToFit];

Если вы создаете подклассы и хотите добавить дополнительные правила, вы можете переопределить:

- (CGSize)sizeThatFits:(CGSize)size;
31 голосов
/ 19 марта 2013

Если ваша кнопка была создана с помощью Interface Builder, и вы меняете заголовок в коде, вы можете сделать это:

[self.button setTitle:@"Button Title" forState:UIControlStateNormal];
[self.button sizeToFit];
19 голосов
/ 14 августа 2015

Swift:

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

var button = UIButton()
button.setTitle("Length of this text determines size", forState: UIControlState.Normal)
button.sizeToFit()
self.view.addSubview(button)
15 голосов
/ 05 декабря 2016

Чтобы сделать это с помощью автоматического размещения, попробуйте установить ограничение переменной ширины:

Width Constraint

Вам также может понадобиться настроить Content Hugging Priority и Content Compression Resistance Priority чтобы получить результаты, которые вам нужны.


UILabel полностью автоматически определяет размер :

Этот UILabel просто устанавливается по центру на экране (дватолько ограничения, горизонтальные / вертикальные):

Изменяет ширину полностью автоматически:

Вам не нужно устанавливать любую ширину или высоту - это полностью автоматически.

enter image description here

enter image description here

Обратите внимание, что маленькие желтые квадраты просто присоединяются («расстояние» от нуля).Они автоматически перемещаются при изменении размера UILabel.

Добавление ограничения "> =" устанавливает минимальную ширину для UILabel:

enter image description here

13 голосов
/ 23 июля 2013

Если вы хотите изменить размер текста в отличие от кнопки, вы можете использовать ...

button.titleLabel.adjustsFontSizeToFitWidth = YES;
button.titleLabel.minimumScaleFactor = .5;
// The .5 value means that I will let it go down to half the original font size 
// before the texts gets truncated

// note, if using anything pre ios6, you would use I think
button.titleLabel.minimumFontSize = 8;
6 голосов
/ 13 ноября 2016

sizeToFit не работает правильно. вместо:

myButton.size = myButton.sizeThatFits(CGSize.zero)

Вы также можете добавить contentInset к кнопке:

myButton.contentEdgeInsets = UIEdgeInsetsMake(8, 8, 4, 8)

5 голосов
/ 19 октября 2015

Просто:

  1. Создать UIView в качестве оболочки с автоматическим макетом для просмотра вокруг.
  2. Поместите UILabel в эту обертку. Добавьте ограничения, которые будут прикреплять ярлык к краям оболочки.
  3. Поместите UIButton в свою оболочку, затем просто добавьте те же ограничения, что и для UILabel.
  4. Наслаждайтесь кнопкой автоматического изменения размера вместе с текстом.
5 голосов
/ 04 июля 2013

В Xcode 4.5 и выше это теперь можно сделать с помощью ' Auto-layout / Constraints '.

Основные преимущества:

  1. Вам вообще не нужно программно устанавливать кадры!
  2. Если все сделано правильно, вам не нужно беспокоиться о сбросе кадров для изменения ориентации.
  3. Кроме того, изменения устройства не должны беспокоить вас (читай, не нужно кодировать отдельно для разных размеров экрана).

Несколько недостатков:

  1. Не поддерживает обратную совместимость - работает только для iOS 6 и выше.
  2. Необходимо ознакомиться (но сэкономит время позже).

Самое классное, что мы можем сосредоточиться на объявлении намерения, например:

  • Я хочу, чтобы эти две кнопки были одинаковой ширины; или
  • Мне нужно, чтобы этот вид был центрирован по вертикали и простирался максимум на 10 пунктов от края суперпредставления; или даже
  • Я хочу, чтобы размер этой кнопки / ярлыка изменялся в соответствии с отображаемым ярлыком!

Здесь - это простое руководство, знакомящее с автоматическим макетом.

Для подробнее .

Сначала это занимает некоторое время, но, похоже, оно того стоит.

3 голосов
/ 14 апреля 2013

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

Итак, я размещаю кнопку для максимального размера, сохраняю этот размер в контроллере и использую следующий метод для изменения размера кнопки при изменении текста:

+ (void) sizeButtonToText:(UIButton *)button availableSize:(CGSize)availableSize padding:(UIEdgeInsets)padding {    

     CGRect boundsForText = button.frame;

    // Measures string
    CGSize stringSize = [button.titleLabel.text sizeWithFont:button.titleLabel.font];
    stringSize.width = MIN(stringSize.width + padding.left + padding.right, availableSize.width);

    // Center's location of button
    boundsForText.origin.x += (boundsForText.size.width - stringSize.width) / 2;
    boundsForText.size.width = stringSize.width;
    [button setFrame:boundsForText];
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...