Я трохи запізнююсь на цю вечірку, але думаю, що я можу додати щось корисне.
Відповідь Кекоа чудова, але, як зазначає RonLugge, вона може змусити кнопку більше не поважати sizeToFit
або, що ще важливіше, може змусити кнопку обрізати її вміст, коли він має власний розмір. Yikes!
По-перше, хоча
Коротке пояснення того, як я вірю 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:
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)
}
}