Для чего это стоит, вот общее решение для размещения изображения по центру над текстом без использования каких-либо магических чисел. Обратите внимание, что следующий код устарел, и вам, вероятно, следует использовать одну из обновленных версий ниже :
// the space between the image and text
CGFloat spacing = 6.0;
// lower the text and push it left so it appears centered
// below the image
CGSize imageSize = button.imageView.frame.size;
button.titleEdgeInsets = UIEdgeInsetsMake(
0.0, - imageSize.width, - (imageSize.height + spacing), 0.0);
// raise the image and push it right so it appears centered
// above the text
CGSize titleSize = button.titleLabel.frame.size;
button.imageEdgeInsets = UIEdgeInsetsMake(
- (titleSize.height + spacing), 0.0, 0.0, - titleSize.width);
Следующая версия содержит изменения для поддержки iOS 7+ , которые были рекомендованы в комментариях ниже. Я не тестировал этот код сам, поэтому я не уверен, насколько хорошо он работает или сломается, если его использовать в предыдущих версиях iOS.
// the space between the image and text
CGFloat spacing = 6.0;
// lower the text and push it left so it appears centered
// below the image
CGSize imageSize = button.imageView.image.size;
button.titleEdgeInsets = UIEdgeInsetsMake(
0.0, - imageSize.width, - (imageSize.height + spacing), 0.0);
// raise the image and push it right so it appears centered
// above the text
CGSize titleSize = [button.titleLabel.text sizeWithAttributes:@{NSFontAttributeName: button.titleLabel.font}];
button.imageEdgeInsets = UIEdgeInsetsMake(
- (titleSize.height + spacing), 0.0, 0.0, - titleSize.width);
// increase the content height to avoid clipping
CGFloat edgeOffset = fabsf(titleSize.height - imageSize.height) / 2.0;
button.contentEdgeInsets = UIEdgeInsetsMake(edgeOffset, 0.0, edgeOffset, 0.0);
Версия Swift 5.0
extension UIButton {
func alignVertical(spacing: CGFloat = 6.0) {
guard let imageSize = imageView?.image?.size,
let text = titleLabel?.text,
let font = titleLabel?.font
else { return }
titleEdgeInsets = UIEdgeInsets(
top: 0.0,
left: -imageSize.width,
bottom: -(imageSize.height + spacing),
right: 0.0
)
let titleSize = text.size(withAttributes: [.font: font])
imageEdgeInsets = UIEdgeInsets(
top: -(titleSize.height + spacing),
left: 0.0,
bottom: 0.0, right: -titleSize.width
)
let edgeOffset = abs(titleSize.height - imageSize.height) / 2.0
contentEdgeInsets = UIEdgeInsets(
top: edgeOffset,
left: 0.0,
bottom: edgeOffset,
right: 0.0
)
}
}
button.currentTitle
вместо того,button.titleLabel.text
особенно если текст кнопки когда-либо изменится.currentTitle
сразу же заселяется, в то время как измененияtitleLabel.text
могут происходить медленно, что может привести к смещению вставок.Нашел как.
Сначала настройте текст
titleLabel
(из-за стилей, например, жирный, курсив и т. Д.). Затем используйте,setTitleEdgeInsets
учитывая ширину вашего изображения:После этого используйте
setTitleEdgeInsets
ширину текстовых границ:Теперь изображение и текст будут центрированы (в этом примере изображение появляется над текстом).
Приветствия.
источник
Вы можете сделать это с помощью этого расширения Swift, которое частично основано на ответе Джесси Кроссена:
Это определяет функцию,
centerLabelVerticallyWithPadding
которая устанавливает заголовок и вставки изображения соответственно.Он также устанавливает contentEdgeInsets, что, я считаю, необходимо для обеспечения
intrinsicContentSize
правильной работы, для чего необходимо использовать Auto Layout.Я считаю, что все решения, которые подкласс UIButton, технически незаконны, так как вы не должны подкласс UIKit управления. То есть теоретически они могут сломаться в будущих выпусках.
источник
Редактировать: Обновлено для Swift 3
Если вы ищете быстрое решение ответа Джесси Кроссена, вы можете добавить его в подкласс UIButton:
источник
Здесь есть несколько замечательных примеров, но я не мог заставить это работать во всех случаях, когда также имел дело с несколькими строками текста (перенос текста). Чтобы наконец заставить его работать, я объединил несколько приемов:
Я использовал пример Джесси Кроссен выше. Однако я исправил проблему с высотой текста и добавил возможность указать горизонтальное поле для текста. Поле полезно для переноса текста, чтобы оно не касалось края кнопки:
Убедитесь, что вы установили текстовую метку для переноса
Это будет в основном работать сейчас. Тем не менее, у меня были кнопки, которые не отображали их изображение правильно. Изображение было смещено далеко вправо или влево (не по центру). Поэтому я использовал технику переопределения макета UIButton, чтобы заставить imageView центрироваться.
источник
Я сделал метод для ответа @ TodCunningham
источник
Обновлено для Xcode 11+
Вставки, описанные в моем первоначальном ответе, были перемещены в инспектор размера в более поздних версиях Xcode. Я не уверен на 100%, когда произошло переключение, но читатели должны просмотреть инспектор размера, если информация о вставке не найдена в инспекторе атрибутов. Ниже приведен пример нового экрана вставки (расположен в верхней части инспектора атрибутов размера по состоянию на 11.5).
Оригинальный ответ
В других ответах нет ничего плохого, однако я просто хотел отметить, что такое же поведение можно выполнить визуально в XCode, используя ноль строк кода. Это решение полезно, если вам не нужно рассчитанное значение или вы строите с раскадровкой / XIB (в противном случае применяются другие решения).
Примечание. Я понимаю, что вопрос ОП требует кода. Я просто предоставляю этот ответ для полноты и в качестве логической альтернативы для тех, кто использует раскадровки / XIBS.
Чтобы изменить интервал на изображении, заголовке и представлении содержимого кнопки с помощью вставок ребер, вы можете выбрать кнопку / элемент управления и открыть инспектор атрибутов. Прокрутите вниз к середине инспектора и найдите раздел для вставок Edge.
Можно также получить доступ и изменить определенные граничные вставки для заголовка, изображения или просмотра содержимого.
источник
Не борись с системой. Если ваши макеты становятся слишком сложными для управления с помощью Interface Builder +, возможно, некоторого простого кода конфигурации, сделайте макеты вручную более простым способом
layoutSubviews
- вот для чего он! Все остальное будет равносильно взлому.Создайте подкласс UIButton и переопределите его
layoutSubviews
метод для программного выравнивания текста и изображения. Или используйте что-то вроде https://github.com/nickpaulson/BlockKit/blob/master/Source/UIView-BKAdditions.h, чтобы вы могли реализовать layoutSubviews, используя блок.источник
Подкласс UIButton
источник
Обновленный ответ Джесси Кроссена для Swift 4 :
Используйте этот способ:
источник
С этим фрагментом кода вы получите что-то вроде этого
источник
Расширение UIButton с синтаксисом Swift 3+ :
Оригинальный ответ: https://stackoverflow.com/a/7199529/3659227
источник
Просто небольшое изменение в ответе Джесси Кроссена, которое сделало его идеальным для меня:
вместо того:
Я использовал это:
источник
Использование
button.titleLabel.frame.size.width
работает нормально только до тех пор, пока метка достаточно короткая, чтобы ее нельзя было усечь. Когда текст метки становится усеченным, позиционирование не работает. Взятиеработает для меня, даже когда текст метки обрезан.
источник
Я посмотрел на существующие ответы, но также обнаружил, что установка фрейма кнопки - важный первый шаг.
Вот функция, которую я использую, которая заботится об этом:
источник
Или вы можете просто использовать эту категорию:
источник
CGSize titleSize = [button.titleLabel.text sizeWithAttributes: @{NSFontAttributeName: button.titleLabel.font}];
Мой случай использования сделал вставки неуправляемыми:
Это то, что я в итоге сделал, и я очень доволен этим:
Создайте кнопку на раскадровке с фоновым изображением (круглый круг с размытием и цветом).
Объявите UIImageView в моем классе:
Создайте экземпляр представления изображения в init:
В viewDidLoad добавьте новый слой к кнопке для нашего изображения и установите выравнивание текста:
В методе нажатия кнопки добавьте выбранное мной изображение наложения к размеру изображения, измените его размер, чтобы он соответствовал изображению, и отцентрируйте его по кнопке, но переместите его вверх на 15, чтобы я мог поместить смещение текста под ним:
Примечание: ceilf () важен для обеспечения качества изображения на границе пикселей.
источник
Предполагая, что вы хотите, чтобы текст и изображение были центрированы по горизонтали, изображение над текстом: отцентрируйте текст в конструкторе интерфейса и добавьте верхнюю вставку (освобождая место для изображения). (оставьте левую вставку в 0). Используйте конструктор интерфейса, чтобы выбрать изображение - его фактическое положение будет установлено из кода, поэтому не беспокойтесь, что в IB все будет выглядеть не очень хорошо. В отличие от других ответов выше, это на самом деле работает на всех поддерживаемых в настоящее время версиях ios (5,6 и 7).
В коде просто отмените ImageView кнопки (установив изображение кнопки на ноль) после захвата изображения (это также автоматически центрирует текст, при необходимости оборачивая). Затем создайте свой собственный ImageView с тем же размером кадра и изображением и поместите его посередине.
Таким образом, вы все равно можете выбрать образ из конструктора интерфейса (хотя он не будет выровнен в IB, как в симуляторе, но опять же, другие решения несовместимы во всех поддерживаемых версиях ios)
источник
Я изо всех сил пытался сделать это, потому что я не мог получить размер изображения и ширину текста в конструкторе моего представления. У меня сработали два небольших изменения в ответе Джесси :
Изменения:
[NSString sizeWithAttributes]
для получения ширины текста;UIImage
вместоUIImageView
источник
Это хорошо работает для меня, для нескольких кнопок, с разной шириной изображения и разной длиной заголовка:
Подкласс
UIButton
источник
Работает нормально для кнопки размером 80х80 пикселей.
источник
Я сделал некоторые корректировки, чтобы выровнять изображение по центру по горизонтали:
источник
обязательно ли использовать краевые вставки? Если нет, вы можете попытаться позиционировать уважение к центру родительского представления
источник
Вам нужно переместить изображение вправо по ширине текста. Затем переместите текст влево на ширину изображения.
Затем отрегулируйте верхнюю и нижнюю вставки, чтобы отрегулировать ось Y. Скорее всего, это можно сделать и программно, но оно должно быть постоянным для вашего размера изображения. Принимая во внимание, что вставки оси X необходимо будет изменить в зависимости от размера текстовой метки в каждой кнопке.
источник
Добавьте этот код в расширение Swift 4.2
источник
Просто скинуть мои 2 цента, это сработало для меня:
источник