Я немного опоздал на эту вечеринку, но думаю, мне есть что добавить.
Ответ Кекоа великолепен, но, как упоминает 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)
}
}