Я пытаюсь создать кнопку с текстом под значком (вроде кнопок приложения), однако этого довольно трудно достичь. Любые идеи, как я могу получить текст для отображения под изображением с UIButton?
Довольно легко и выполнимо создать собственный подкласс UIbutton, содержащий UIImage и UILabel, расположенные так, как вам нужно ...
NP Compete
7
Или просто используйте UIButton и UILabel.
raidfive
Чтобы точно контролировать размер и автоматическое расположение, вы можете попробовать это: https://github.com/albert-zhang/AZCenterLabelButton( Ссылка )
Я думаю, что это лучший ответ, так как он использует edgeInsets вместо ручной настройки кадра. Он отлично работает и с автоматической разметкой, когда вызывается из layoutSubviews в суперпредставлении кнопки. Единственное предложение - использовать CGRectGetHeight()и CGRectGetWidth()при получении imageView и titleLabel высоту и ширину.
Джесси
1
Когда я использую это, изображение всплывает над видом кнопки, чтобы CGFloat inset = (self.frame.size.height - totalHeight)/2; self.contentEdgeInsets = UIEdgeInsetsMake(inset, 0.0f, inset, 0.0f);
Алекс Хедли
12
Расширение Swift не разработало его для меня правильно.
Патрик
Это работает, если Image был установлен как setImage, а не как setBackgroundImage.
В XCode вы можете просто установить левую вставку заголовка края, чтобы уменьшить ширину изображения. Это будет отображать метку в центре изображения.
Чтобы метка отображалась под изображением (вроде кнопок приложения), вам может потребоваться установить для верхнего края заголовка края какое-нибудь положительное число.
Это способ сделать это ... если вы не делаете это несколько раз с несколькими кнопками (разных размеров) ... в этом случае у меня были хорошие результаты с измененной версией решения Эрика В.
Кенни Уинкер
5
Просто чтобы люди это поняли. Значение должно быть отрицательной шириной изображения, даже если кнопка шире, чем ширина изображения.
Лирон
1
Это не сработало для меня. Мой текст по-прежнему отображается справа от изображения, то есть не переносится под ним.
Cindeselia
1
@Cindeselia Это удивительно. Какую ценность вы использовали для Top Inset? Может быть, попытаться увеличить его до еще большего значения?
Крис
3
В iOS7 похоже не работает. Ярлык перемещается только вниз изображения и скрывается, больше не отображается.
Храбрый
51
Это простая по центру кнопка заголовка, реализованная в Swift путем переопределения titleRect(forContentRect:)и imageRect(forContentRect:). Он также реализует intrinsicContentSizeдля использования с AutoLayout.
Это самое правильное решение. Но некоторые изменения необходимы для внутреннего размера контента. Он должен возвращать МАКСИМАЛЬНУЮ ширину между изображением и меткой: вернуть CGSizeMake (MAX (labelSize.width, self.imageView.image.size.width), self.imageView.image.size.height + labelHeight)
Мне лично пришлось установить значение titleLabel y в 0 и высоту в высоту рамки, чтобы он отображал текст с изображением. Это не имеет смысла для меня, но это работает ... хотя я все еще изучаю способ настройки элементов управления Apple.
Расс
6
На самом деле, лучший способ переопределить titleRectForContentRectиimageRectForContentRect
Mazyod
28
Рефакторированный ответ ледяного кристалла23.
Swift 3, работает с автопутешествиями, XIB, раскадровками, может быть анимированным.
Кнопка в исходном ответе icecrystal23 имела плохо рассчитанный кадр. Я думаю, что исправил это.
Изменить: Обновлен до Swift 5 и сделал работу внутри Interface Builder / Раскадровки
Существует проблема с этим при удалении изображения. Я использую изображение для выбранного состояния и не изображение для состояния по умолчанию. Когда состояние изменяется с выбранного на значение по умолчанию, метка портится. Поэтому необходимо внести несколько исправлений: не проверять вид изображения, а использовать «изображение (для: состояние)». Установите нулевые вставки ребер, когда в операторе else нет изображения layoutSubviews.
Облак
Единственное решение здесь, которое работает. Другие ответы, кажется, работают, но на самом деле границы кнопок не меняются в соответствии с меткой и размером изображения. Установите цвет фона, чтобы увидеть это.
Мануэль
Это решение не сработало, я думаю, что оно вызвало какой-то бесконечный цикл и, в конечном итоге, сбой Xcode. Я удалил часть intrinsicContentSize, и она работала нормально (Xcode 11.5)
Это модифицированная версия отличного ответа Эрика В. Но вместо того, чтобы размещать изображение по центру в верхней части вида, оно размещает изображение и метку по центру в виде группы.
Разница в том, что:
+-----------+|()||Hello|// Erik W's code||||+-----------+
против
+-----------+|||()|// My modified version|Hello|||+-----------+
Источник ниже:
-(void)layoutSubviews {[super layoutSubviews];CGRect titleLabelFrame =self.titleLabel.frame;CGSize labelSize =[self.titleLabel.text sizeWithFont:self.titleLabel.font constrainedToSize:CGSizeMake(self.frame.size.width, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping];CGRect imageFrame =self.imageView.frame;CGSize fitBoxSize =(CGSize){.height = labelSize.height + kTextTopPadding + imageFrame.size.height,.width = MAX(imageFrame.size.width, labelSize.width)};CGRect fitBoxRect =CGRectInset(self.bounds,(self.bounds.size.width - fitBoxSize.width)/2,(self.bounds.size.height - fitBoxSize.height)/2);
imageFrame.origin.y = fitBoxRect.origin.y;
imageFrame.origin.x =CGRectGetMidX(fitBoxRect)-(imageFrame.size.width/2);self.imageView.frame = imageFrame;// Adjust the label size to fit the text, and move it below the image
titleLabelFrame.size.width = labelSize.width;
titleLabelFrame.size.height = labelSize.height;
titleLabelFrame.origin.x =(self.frame.size.width /2)-(labelSize.width /2);
titleLabelFrame.origin.y = fitBoxRect.origin.y + imageFrame.size.height + kTextTopPadding;self.titleLabel.frame = titleLabelFrame;}
К вашему сведению: это может нарушиться при объединении с анимациями UIView, так как layoutSubviews вызывается во время них.
Хороший ответ. Добавьте @IBDesignable в свой подкласс и посмотрите на раскадровку.
Джоэл Тепли
16
Если вы подкласс UIButtonи override layoutSubviews, вы можете использовать ниже, чтобы центрировать изображение и разместить заголовок по центру под ним:
kTextTopPadding это константа, которую вы должны ввести, которая определяет пространство между изображением и текстом под ним.
-(void)layoutSubviews {[super layoutSubviews];// Move the image to the top and center it horizontallyCGRect imageFrame = self.imageView.frame;
imageFrame.origin.y =0;
imageFrame.origin.x =(self.frame.size.width /2)-(imageFrame.size.width /2);
self.imageView.frame = imageFrame;// Adjust the label size to fit the text, and move it below the imageCGRect titleLabelFrame = self.titleLabel.frame;CGSize labelSize =[self.titleLabel.text sizeWithFont:self.titleLabel.font
constrainedToSize:CGSizeMake(self.frame.size.width, CGFLOAT_MAX)
lineBreakMode:NSLineBreakByWordWrapping];
titleLabelFrame.size.width = labelSize.width;
titleLabelFrame.size.height = labelSize.height;
titleLabelFrame.origin.x =(self.frame.size.width /2)-(labelSize.width /2);
titleLabelFrame.origin.y = self.imageView.frame.origin.y + self.imageView.frame.size.height + kTextTopPadding;
self.titleLabel.frame = titleLabelFrame;}
Вы можете получить границы метки заголовка, вызвав sizeToFit после установки его текста. Горизонтальный интервал должен работать независимо от размера текста, шрифта и изображения, но я не знаю ни одного решения для согласования вертикального интервала и нижнего края содержимого.
Вот ответ "Медведь со мной" в качестве подкласса в Swift 2.0. Чтобы использовать его, просто измените класс кнопки Interface Builderна, VerticalButtonи он волшебным образом обновит предварительный просмотр.
Я также обновил его, чтобы вычислить правильный размер внутреннего содержимого для автоматического размещения.
Заканчивается как бесконечный цикл , в котором layoutSubviews()вызывается несколько раз в моем случае: intrinsicContentSizeдоступы , imageViewкоторый делает layoutSubviewsвремя называется , которая доступы и imageViewт.д.
ctietze
3
@Tiago Я изменил твой ответ следующим образом. Работает нормально со всеми размерами
Я взял комбинацию ответов здесь и нашел тот, который, кажется, работает для меня, в Свифте. Я не люблю, как я только что преодолел вставки, но это работает. Я был бы открыт для предложенных улучшений в комментариях. Кажется, работает правильно с sizeToFit()и с автоматической разметкой.
importUIKit/// A button that displays an image centered above the title. This implementation /// only works when both an image and title are set, and ignores/// any changes you make to edge insets.classCenteredButton:UIButton{let padding:CGFloat=0.0override func layoutSubviews(){if imageView?.image !=nil&& titleLabel?.text !=nil{let imageSize:CGSize= imageView!.image!.size
titleEdgeInsets =UIEdgeInsetsMake(0.0,-imageSize.width,-(imageSize.height + padding),0.0)let labelString =NSString(string: titleLabel!.text!)let titleSize = labelString.sizeWithAttributes([NSFontAttributeName: titleLabel!.font])
imageEdgeInsets =UIEdgeInsetsMake(-(titleSize.height + padding),0.0,0.0,-titleSize.width)let edgeOffset = abs(titleSize.height - imageSize.height)/2.0;
contentEdgeInsets =UIEdgeInsetsMake(edgeOffset,0.0, edgeOffset,0.0)}super.layoutSubviews()}override func sizeThatFits(size:CGSize)->CGSize{let defaultSize =super.sizeThatFits(size)iflet titleSize = titleLabel?.sizeThatFits(size),let imageSize = imageView?.sizeThatFits(size){returnCGSize(width: ceil(max(imageSize.width, titleSize.width)), height: ceil(imageSize.height + titleSize.height + padding))}return defaultSize
}override func intrinsicContentSize()->CGSize{let size = sizeThatFits(CGSize(width:CGFloat.max, height:CGFloat.max))return size
}}
Я обнаружил, что ответ Симеона был, вероятно, лучшим, но он давал мне странные результаты на некоторых кнопках, и я просто не мог понять, почему. Таким образом, используя его ответ в качестве основы, я реализовал свои кнопки, как показано ниже:
Это работает как шарм действительно! И с автоматической версткой тоже. Большое спасибо за то, что поделились этим решением. Я сходил с ума от этого и прибегал к созданию своего собственного подкласса UIControl.
Я думаю, что intrinsicContentSize не является правильным здесь. Я не понимаю, для чего предназначена часть с CGSizeEqualToSize, но у вас есть размер метки> 0, только если размер метки совпадает с intrinsicContentSize UILabel. Этого должно быть достаточно, чтобы просто вернуться CGSizeMake(MAX(labelSize.width, image.size.width), image.size.height + labelSize.height + 5.0)в случае, если
Оливер
1
Если вы используете пользовательские шрифты, расчет размера titleLabel не будет работать должным образом, его следует заменить на
let titleLabelSize = self.titleLabel?.text?.size(withAttributes: [NSAttributedStringKey.font: self.titleLabel!.font!])
Вместо того, чтобы идти в ад, пытаясь расположить значок и текст с помощью вставок с краями, вы можете создать NSAttributedString с вашим изображением в качестве вложения и установить вместо него присвоенный заголовок вашей кнопки:
let titleText =NSAttributedString(string: yourTitle, attributes: attributes)let imageAttachment =NSTextAttachment()
imageAttachment.image = yourImage
let title =NSMutableAttributedString(string:"")
title.append(NSAttributedString(attachment: imageAttachment))
title.append(titleText)
button.setAttributedTitle(title,for:.normal)
Не работает для вопроса ОП, где текст должен быть центрирован ниже изображения. UIButtonМакеты текстового поля A отображают только 1 строку, следовательно, он не работает даже при использовании разрыва строки в приписанной строке. В противном случае было бы хорошим решением.
Мануэль
Также важно установить button.titleLabel?.numberOfLinesдля того, чтобы получить необходимое количество строк
swearwolf
1
Локализация Дружественное Решение:
Так много отличных решений, ребята, но я бы хотел добавить примечание для тех, кто использует локализацию.
Вам нужно повернуть левое и правое значения EdgeInstets, чтобы правильно расположить кнопку в случае изменения направления языка с LtR на RtL.
Используя подобное решение, я реализовал бы его следующим образом:
extension UIButton{
func alignVertical(spacing:CGFloat, lang:String){
guard let imageSize =self.imageView?.image?.size,let text =self.titleLabel?.text,let font =self.titleLabel?.font
else{return}let labelString =NSString(string: text)let titleSize = labelString.size(
withAttributes:[NSAttributedString.Key.font: font])var titleLeftInset:CGFloat=-imageSize.width
var titleRigtInset:CGFloat=0.0var imageLeftInset:CGFloat=0.0var imageRightInset:CGFloat=-titleSize.width
ifLocale.current.languageCode!!="en"{// If not Left to Right language
titleLeftInset =0.0
titleRigtInset =-imageSize.width
imageLeftInset =-titleSize.width
imageRightInset =0.0}self.titleEdgeInsets =UIEdgeInsets(
top:0.0,
left: titleLeftInset,
bottom:-(imageSize.height + spacing),
right: titleRigtInset
)self.imageEdgeInsets =UIEdgeInsets(
top:-(titleSize.height + spacing),
left: imageLeftInset,
bottom:0.0,
right: imageRightInset
)let edgeOffset = abs(titleSize.height - imageSize.height)/2.0;self.contentEdgeInsets =UIEdgeInsets(
top: edgeOffset,
left:0.0,
bottom: edgeOffset,
right:0.0)}}
Это определенно является излишним для этого вопроса, однако ... В одном из моих проектов мне сначала пришлось реализовать кнопку с иконкой, выровненной по левому краю. Затем мы получили еще одну кнопку с заголовком под изображением. Я искал существующее решение, но безуспешно Итак, здесь идет настраиваемая кнопка:
@IBDesignableclassAlignableButton:UIButton{overrideclassvar requiresConstraintBasedLayout:Bool{returntrue}@objcenumIconAlignment:Int{case top, left, right, bottom
}// MARK: - Designables@IBInspectablevar iconAlignmentValue:Int{set{
iconAlignment =IconAlignment(rawValue: newValue)??.left
}get{return iconAlignment.rawValue
}}var iconAlignment:IconAlignment=.left
@IBInspectablevar titleAlignmentValue:Int{set{
titleAlignment =NSTextAlignment(rawValue: newValue)??.left
}get{return titleAlignment.rawValue
}}var titleAlignment:NSTextAlignment=.left
// MARK: - Corner Radius@IBInspectablevar cornerRadius:CGFloat{get{return layer.cornerRadius
}set{
layer.masksToBounds =(newValue !=0)
layer.cornerRadius = newValue
}}// MARK: - Content sizeoverridevar intrinsicContentSize:CGSize{switch iconAlignment {case.top,.bottom:return verticalAlignedIntrinsicContentSize
default:returnsuper.intrinsicContentSize
}}privatevar verticalAlignedIntrinsicContentSize:CGSize{iflet imageSize = imageView?.intrinsicContentSize,let labelSize = titleLabel?.intrinsicContentSize {let width = max(imageSize.width, labelSize.width)+ contentEdgeInsets.left + contentEdgeInsets.right
let height = imageSize.height + labelSize.height + contentEdgeInsets.top + contentEdgeInsets.bottom
returnCGSize(
width: ceil(width),
height: ceil(height))}returnsuper.intrinsicContentSize
}// MARK: - Image Rectoverride func imageRect(forContentRect contentRect:CGRect)->CGRect{switch iconAlignment {case.top:return topAlignedImageRect(forContentRect: contentRect)case.bottom:return bottomAlignedImageRect(forContentRect: contentRect)case.left:return leftAlignedImageRect(forContentRect: contentRect)case.right:return rightAlignedImageRect(forContentRect: contentRect)}}
func topAlignedImageRect(forContentRect contentRect:CGRect)->CGRect{let rect =super.imageRect(forContentRect: contentRect)let x =(contentRect.width - rect.width)/2.0+ contentRect.minX
let y = contentRect.minY
let w = rect.width
let h = rect.height
returnCGRect(
x: x,
y: y,
width: w,
height: h
).inset(by: imageEdgeInsets)}
func bottomAlignedImageRect(forContentRect contentRect:CGRect)->CGRect{let rect =super.imageRect(forContentRect: contentRect)let x =(contentRect.width - rect.width)/2.0+ contentRect.minX
let y = contentRect.height - rect.height + contentRect.minY
let w = rect.width
let h = rect.height
returnCGRect(
x: x,
y: y,
width: w,
height: h
).inset(by: imageEdgeInsets)}
func leftAlignedImageRect(forContentRect contentRect:CGRect)->CGRect{let rect =super.imageRect(forContentRect: contentRect)let x = contentRect.minX
let y =(contentRect.height - rect.height)/2+ contentRect.minY
let w = rect.width
let h = rect.height
returnCGRect(
x: x,
y: y,
width: w,
height: h
).inset(by: imageEdgeInsets)}
func rightAlignedImageRect(forContentRect contentRect:CGRect)->CGRect{let rect =super.imageRect(forContentRect: contentRect)let x =(contentRect.width - rect.width)+ contentRect.minX
let y =(contentRect.height - rect.height)/2+ contentRect.minY
let w = rect.width
let h = rect.height
returnCGRect(
x: x,
y: y,
width: w,
height: h
).inset(by: imageEdgeInsets)}// MARK: - Title Rectoverride func titleRect(forContentRect contentRect:CGRect)->CGRect{switch iconAlignment {case.top:return topAlignedTitleRect(forContentRect: contentRect)case.bottom:return bottomAlignedTitleRect(forContentRect: contentRect)case.left:return leftAlignedTitleRect(forContentRect: contentRect)case.right:return rightAlignedTitleRect(forContentRect: contentRect)}}
func topAlignedTitleRect(forContentRect contentRect:CGRect)->CGRect{let rect =super.titleRect(forContentRect: contentRect)let x = contentRect.minX
let y = contentRect.height - rect.height + contentRect.minY
let w = contentRect.width
let h = rect.height
returnCGRect(
x: x,
y: y,
width: w,
height: h
).inset(by: titleEdgeInsets)}
func bottomAlignedTitleRect(forContentRect contentRect:CGRect)->CGRect{let rect =super.titleRect(forContentRect: contentRect)let x = contentRect.minX
let y = contentRect.minY
let w = contentRect.width
let h = rect.height
returnCGRect(
x: x,
y: y,
width: w,
height: h
).inset(by: titleEdgeInsets)}
func leftAlignedTitleRect(forContentRect contentRect:CGRect)->CGRect{let titleRect =super.titleRect(forContentRect: contentRect)let imageRect =self.imageRect(forContentRect: contentRect)let x = imageRect.width + imageRect.minX
let y =(contentRect.height - titleRect.height)/2.0+ contentRect.minY
let w = contentRect.width - imageRect.width *2.0let h = titleRect.height
returnCGRect(
x: x,
y: y,
width: w,
height: h
).inset(by: titleEdgeInsets)}
func rightAlignedTitleRect(forContentRect contentRect:CGRect)->CGRect{let titleRect =super.titleRect(forContentRect: contentRect)let imageRect =self.imageRect(forContentRect: contentRect)let x = contentRect.minX + imageRect.width
let y =(contentRect.height - titleRect.height)/2.0+ contentRect.minY
let w = contentRect.width - imageRect.width *2.0let h = titleRect.height
returnCGRect(
x: x,
y: y,
width: w,
height: h
).inset(by: titleEdgeInsets)}// MARK: - Lifecycleoverride func awakeFromNib(){super.awakeFromNib()
titleLabel?.textAlignment = titleAlignment
}override func prepareForInterfaceBuilder(){super.prepareForInterfaceBuilder()
titleLabel?.textAlignment = titleAlignment
}}
https://github.com/albert-zhang/AZCenterLabelButton
( Ссылка )Ответы:
Или вы можете просто использовать эту категорию:
ObjC
Быстрое расширение
Предложение: Если высота кнопки меньше, чем
totalHeight
изображение, изображение будет рисоваться за пределами границ.imageEdgeInset.top
должно быть:источник
CGRectGetHeight()
иCGRectGetWidth()
при получении imageView и titleLabel высоту и ширину.CGFloat inset = (self.frame.size.height - totalHeight)/2; self.contentEdgeInsets = UIEdgeInsetsMake(inset, 0.0f, inset, 0.0f);
В XCode вы можете просто установить левую вставку заголовка края, чтобы уменьшить ширину изображения. Это будет отображать метку в центре изображения.
Чтобы метка отображалась под изображением (вроде кнопок приложения), вам может потребоваться установить для верхнего края заголовка края какое-нибудь положительное число.
источник
Это простая по центру кнопка заголовка, реализованная в Swift путем переопределения
titleRect(forContentRect:)
иimageRect(forContentRect:)
. Он также реализуетintrinsicContentSize
для использования с AutoLayout.источник
Посмотрите на этот отличный ответ в Swift.
источник
left
вimageEdgeInsets
с(self.frame.size.width - imageSize.width) / 2
layoutSubviews()
вашем суперпредставлении.Подкласс
UIButton
. Переопределить -layoutSubviews
переместить встроенныйsubviews
в новые позиции:источник
titleRectForContentRect
иimageRectForContentRect
Рефакторированный ответ ледяного кристалла23.
Swift 3, работает с автопутешествиями, XIB, раскадровками, может быть анимированным.
Кнопка в исходном ответе icecrystal23 имела плохо рассчитанный кадр. Я думаю, что исправил это.
Изменить: Обновлен до Swift 5 и сделал работу внутри Interface Builder / Раскадровки
источник
исправил один из ответов здесь:
Свифт 3:
источник
Это модифицированная версия отличного ответа Эрика В. Но вместо того, чтобы размещать изображение по центру в верхней части вида, оно размещает изображение и метку по центру в виде группы.
Разница в том, что:
против
Источник ниже:
К вашему сведению: это может нарушиться при объединении с анимациями UIView, так как layoutSubviews вызывается во время них.
источник
Решение Дейва в Swift:
источник
Если вы подкласс
UIButton
иoverride layoutSubviews
, вы можете использовать ниже, чтобы центрировать изображение и разместить заголовок по центру под ним:kTextTopPadding
это константа, которую вы должны ввести, которая определяет пространство между изображением и текстом под ним.источник
Обновлен ответ Кенни Уинкера, поскольку sizeWithFont устарела в iOS 7.
источник
На iOS 11 / Swift 4 ни один из приведенных выше ответов действительно не работал для меня. Я нашел несколько примеров и изложил свое мнение:
Надеюсь, это кому-нибудь поможет.
источник
Используя код Кенни Уинкера и Симеона, я создаю этот быстрый код, который работает для меня.
источник
Вам просто нужно отрегулировать все три вставки по краям в зависимости от размера вашего изображения и заголовка:
Вы можете получить границы метки заголовка, вызвав sizeToFit после установки его текста. Горизонтальный интервал должен работать независимо от размера текста, шрифта и изображения, но я не знаю ни одного решения для согласования вертикального интервала и нижнего края содержимого.
источник
Вот ответ "Медведь со мной" в качестве подкласса в
Swift 2.0
. Чтобы использовать его, просто измените класс кнопкиInterface Builder
на,VerticalButton
и он волшебным образом обновит предварительный просмотр.Я также обновил его, чтобы вычислить правильный размер внутреннего содержимого для автоматического размещения.
источник
layoutSubviews()
вызывается несколько раз в моем случае:intrinsicContentSize
доступы ,imageView
который делаетlayoutSubviews
время называется , которая доступы иimageView
т.д.@Tiago Я изменил твой ответ следующим образом. Работает нормально со всеми размерами
источник
Я взял комбинацию ответов здесь и нашел тот, который, кажется, работает для меня, в Свифте. Я не люблю, как я только что преодолел вставки, но это работает. Я был бы открыт для предложенных улучшений в комментариях. Кажется, работает правильно с
sizeToFit()
и с автоматической разметкой.источник
Используйте эти два метода:
Пример:
И вы можете использовать:
источник
У меня Swift 5 - метод ниже
Убедитесь, что заголовок вашей кнопки не усечен в раскадровке / XIB, иначе перейдите к
решению 2
источник
Я думаю, что один из лучших способов сделать это - создать подкласс UIButton и переопределить некоторые методы рендеринга:
источник
Я обнаружил, что ответ Симеона был, вероятно, лучшим, но он давал мне странные результаты на некоторых кнопках, и я просто не мог понять, почему. Таким образом, используя его ответ в качестве основы, я реализовал свои кнопки, как показано ниже:
источник
Вот мой подкласс,
UIButton
который решает эту проблему:Вот и все. Работает как шарм. Проблема может появиться, если кнопка будет маленькой, чтобы соответствовать заголовку и тексту.
источник
@ решение Симеона в Objective-C
источник
CGSizeMake(MAX(labelSize.width, image.size.width), image.size.height + labelSize.height + 5.0)
в случае, еслиЕсли вы используете пользовательские шрифты, расчет размера titleLabel не будет работать должным образом, его следует заменить на
let titleLabelSize = self.titleLabel?.text?.size(withAttributes: [NSAttributedStringKey.font: self.titleLabel!.font!])
источник
Вместо того, чтобы идти в ад, пытаясь расположить значок и текст с помощью вставок с краями, вы можете создать NSAttributedString с вашим изображением в качестве вложения и установить вместо него присвоенный заголовок вашей кнопки:
источник
UIButton
Макеты текстового поля A отображают только 1 строку, следовательно, он не работает даже при использовании разрыва строки в приписанной строке. В противном случае было бы хорошим решением.button.titleLabel?.numberOfLines
для того, чтобы получить необходимое количество строкЛокализация Дружественное Решение:
Так много отличных решений, ребята, но я бы хотел добавить примечание для тех, кто использует локализацию.
Вам нужно повернуть левое и правое значения EdgeInstets, чтобы правильно расположить кнопку в случае изменения направления языка с LtR на RtL.
Используя подобное решение, я реализовал бы его следующим образом:
источник
Верхнее изображение и нижняя кнопка заголовка с подклассами UIButton
источник
Это определенно является излишним для этого вопроса, однако ... В одном из моих проектов мне сначала пришлось реализовать кнопку с иконкой, выровненной по левому краю. Затем мы получили еще одну кнопку с заголовком под изображением. Я искал существующее решение, но безуспешно Итак, здесь идет настраиваемая кнопка:
Надеюсь, что вы найдете ее полезной.
источник
Как то так внутри
UIButton
подклассаисточник
Это довольно просто.
Вместо этого:
Использовать это:
Затем вы можете легко добавить текст на кнопку, используя:
// button.titleLabel! .font = UIFont (имя: "FontName", размер: 30)
источник