Я немного опоздал на эту вечеринку, но думаю, что мне есть что добавить.
Ответ Кекоа великолепен, но, как упоминает RonLugge, он может заставить кнопку больше не уважать sizeToFit
или, что более важно, может заставить кнопку обрезать ее содержимое, когда оно имеет собственный размер. Хлоп!
Во-первых, хотя,
Краткое объяснение того, как я верю imageEdgeInsets
и titleEdgeInsets
работаю:
В документах дляimageEdgeInsets
имеют следующее сказать, в частности , говорится :
Используйте это свойство, чтобы изменить размер и переместить эффективный прямоугольник рисования для изображения кнопки. Вы можете указать разные значения для каждой из четырех вставок (сверху, слева, снизу, справа). Положительное значение сжимает или вставляет этот край, перемещая его ближе к центру кнопки. Отрицательное значение расширяет или опускает этот край.
Я считаю, что эта документация была написана, представляя, что кнопка не имеет заголовка, только изображение. Это гораздо более разумно думать об этом и ведет себя так, как UIEdgeInsets
обычно. По сути, рамка изображения (или заголовок с titleEdgeInsets
) перемещается внутрь для положительных вставок и наружу для отрицательных вставок.
Ок, и что?
Я получаю там! Вот что у вас есть по умолчанию, установив изображение и заголовок (граница кнопки зеленая, чтобы показать, где она находится):
Если вы хотите установить интервал между изображением и заголовком, не задавая ни один из них, вам нужно установить четыре разных вставки, по две на каждое изображение и заголовок. Это потому, что вы не хотите изменять размеры фреймов этих элементов, а только их положение. Когда вы начинаете думать таким образом, становится очевидным необходимое изменение превосходной категории Кекоа:
@implementation UIButton(ImageTitleCentering)
- (void)centerButtonAndImageWithSpacing:(CGFloat)spacing {
CGFloat insetAmount = spacing / 2.0;
self.imageEdgeInsets = UIEdgeInsetsMake(0, -insetAmount, 0, insetAmount);
self.titleEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, -insetAmount);
}
@end
Но подождите , вы говорите, когда я это делаю, я получаю это:
О да! Я забыл, документы предупредили меня об этом. Они говорят, частично:
Это свойство используется только для позиционирования изображения во время макета. Кнопка не использует это свойство для определения intrinsicContentSize
и sizeThatFits:
.
Но это свойство , которое может помочь, и это contentEdgeInsets
. Документы для этого говорят, частично:
Кнопка использует это свойство для определения intrinsicContentSize
и sizeThatFits:
.
Это звучит неплохо. Итак, давайте настроим категорию еще раз:
@implementation UIButton(ImageTitleCentering)
- (void)centerButtonAndImageWithSpacing:(CGFloat)spacing {
CGFloat insetAmount = spacing / 2.0;
self.imageEdgeInsets = UIEdgeInsetsMake(0, -insetAmount, 0, insetAmount);
self.titleEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, -insetAmount);
self.contentEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, insetAmount);
}
@end
А что ты получаешь?
Выглядит как победитель для меня.
Работаете в Swift и вообще не хотите думать? Вот окончательная версия расширения в Swift:
extension UIButton {
func centerTextAndImage(spacing: CGFloat) {
let insetAmount = spacing / 2
imageEdgeInsets = UIEdgeInsets(top: 0, left: -insetAmount, bottom: 0, right: insetAmount)
titleEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount, bottom: 0, right: -insetAmount)
contentEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount, bottom: 0, right: insetAmount)
}
}