IPhone UIButton - позиция изображения
У меня есть UIButton
с текстом "Исследуйте приложение" и UIImage
( > )
В Interface Builder
это выглядит так:
[ (>) Explore the app ]
Но мне нужно разместить этот UIImage
ПОСЛЕ текста:
[ Explore the app (>) ]
Как переместить UIImage
вправо?
Ответы
Ответ 1
Принудительное использование "справа налево" для кнопки не вариант, если ваше приложение поддерживает "слева направо" и "справа налево".
Решение, которое сработало для меня, - это подкласс, который можно добавить к кнопке в раскадровке и хорошо работает с ограничениями (протестировано в iOS 11):
class ButtonWithImageAtEnd: UIButton {
override func layoutSubviews() {
super.layoutSubviews()
if let imageView = imageView, let titleLabel = titleLabel {
let padding: CGFloat = 15
imageEdgeInsets = UIEdgeInsets(top: 5, left: titleLabel.frame.size.width+padding, bottom: 5, right: -titleLabel.frame.size.width-padding)
titleEdgeInsets = UIEdgeInsets(top: 0, left: -imageView.frame.width, bottom: 0, right: imageView.frame.width)
}
}
}
Где "отступ" будет пространство между заголовком и изображением.
Ответ 2
Мое решение для этого довольно просто
[button sizeToFit];
button.titleEdgeInsets = UIEdgeInsetsMake(0, -button.imageView.frame.size.width, 0, button.imageView.frame.size.width);
button.imageEdgeInsets = UIEdgeInsetsMake(0, button.titleLabel.frame.size.width, 0, -button.titleLabel.frame.size.width);
Ответ 3
В iOS 9, кажется, что простой способ достичь этого - заставить семантику представления.
![введите описание изображения здесь]()
Или программно, используя:
button.semanticContentAttribute = .ForceRightToLeft
Ответ 4
Установите imageEdgeInset
и titleEdgeInset
, чтобы перемещать компоненты вокруг вашего изображения. Вы также можете создать кнопку с использованием полной графики и использовать ее в качестве фонового изображения для кнопки (затем используйте titleEdgeInsets
, чтобы переместить заголовок вокруг).
Ответ 5
Raymond W ответ лучше. Подкласс UIButton с пользовательскими макетами. Чрезвычайно прост в использовании, здесь реализована реализация layoutSubviews, которая сработала для меня:
- (void)layoutSubviews
{
// Allow default layout, then adjust image and label positions
[super layoutSubviews];
UIImageView *imageView = [self imageView];
UILabel *label = [self titleLabel];
CGRect imageFrame = imageView.frame;
CGRect labelFrame = label.frame;
labelFrame.origin.x = imageFrame.origin.x;
imageFrame.origin.x = labelFrame.origin.x + CGRectGetWidth(labelFrame);
imageView.frame = imageFrame;
label.frame = labelFrame;
}
Ответ 6
Как насчет подкласса UIButton
и переопределения layoutSubviews
?
Затем после обработки местоположения self.imageView
и self.titleLabel
Ответ 7
Еще один простой способ (это НЕ только iOS 9) заключается в подклассе UIButton для переопределения этих двух методов
override func titleRectForContentRect(contentRect: CGRect) -> CGRect {
var rect = super.titleRectForContentRect(contentRect)
rect.origin.x = 0
return rect
}
override func imageRectForContentRect(contentRect: CGRect) -> CGRect {
var rect = super.imageRectForContentRect(contentRect)
rect.origin.x = CGRectGetMaxX(contentRect) - CGRectGetWidth(rect)
return rect
}
contentEdgeInsets
уже учтен с использованием супер.
Ответ 8
В Свифте:
override func layoutSubviews(){
super.layoutSubviews()
let inset: CGFloat = 5
if var imageFrame = self.imageView?.frame,
var labelFrame = self.titleLabel?.frame {
let cumulativeWidth = imageFrame.width + labelFrame.width + inset
let excessiveWidth = self.bounds.width - cumulativeWidth
labelFrame.origin.x = excessiveWidth / 2
imageFrame.origin.x = labelFrame.origin.x + labelFrame.width + inset
self.imageView?.frame = imageFrame
self.titleLabel?.frame = labelFrame
}
}
Ответ 9
Построение ответа на @split...
Ответ фантастический, но он игнорирует тот факт, что кнопка может иметь пользовательские вставки изображения и заголовка заголовка, которые установлены заранее (например, в раскадровке).
Например, вы можете захотеть, чтобы изображение имело некоторые отступы сверху и снизу контейнера, но все же перемещайте изображение в правую часть кнопки.
Я расширил концепцию с помощью этого метода: -
- (void) moveImageToRightSide {
[self sizeToFit];
CGFloat titleWidth = self.titleLabel.frame.size.width;
CGFloat imageWidth = self.imageView.frame.size.width;
CGFloat gapWidth = self.frame.size.width - titleWidth - imageWidth;
self.titleEdgeInsets = UIEdgeInsetsMake(self.titleEdgeInsets.top,
-imageWidth + self.titleEdgeInsets.left,
self.titleEdgeInsets.bottom,
imageWidth - self.titleEdgeInsets.right);
self.imageEdgeInsets = UIEdgeInsetsMake(self.imageEdgeInsets.top,
titleWidth + self.imageEdgeInsets.left + gapWidth,
self.imageEdgeInsets.bottom,
-titleWidth + self.imageEdgeInsets.right - gapWidth);
}
Ответ 10
// Get the size of the text and image
CGSize buttonLabelSize = [[self.button titleForState:UIControlStateNormal] sizeWithFont:self.button.titleLabel.font];
CGSize buttonImageSize = [[self.button imageForState:UIControlStateNormal] size];
// You can do this line in the xib too:
self.button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
// Adjust Edge Insets according to the above measurement. The +2 adds a little space
self.button.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, -(buttonLabelSize.width+2));
self.button.titleEdgeInsets = UIEdgeInsetsMake(0, 0, 0, buttonImageSize.width+2);
Это создает выровненную по правому краю кнопку:
[ button label (>)]
Кнопка не регулирует ширину в соответствии с контекстом, поэтому в левой части метки появится пробел. Вы можете решить это, вычислив ширину рамки кнопки с помощью кнопки buttonLabelSize.width и buttonImageSize.width.
Ответ 11
button.semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
Ответ 12
Это решение работает с iOS 7 и выше
Просто подкласс UIButton
@interface UIButton (Image)
- (void)swapTextWithImage;
@end
@implementation UIButton (Image)
- (void)swapTextWithImage {
const CGFloat kDefaultPadding = 6.0f;
CGSize buttonSize = [self.titleLabel.text sizeWithAttributes:@{
NSFontAttributeName:self.titleLabel.font
}];
self.titleEdgeInsets = UIEdgeInsetsMake(0, -self.imageView.frame.size.width, 0, self.imageView.frame.size.width);
self.imageEdgeInsets = UIEdgeInsetsMake(0, buttonSize.width + kDefaultPadding, 0, -buttonSize.width);
}
@end
Использование (где-то в вашем классе):
[self.myButton setTitle:@"Any text" forState:UIControlStateNormal];
[self.myButton swapTextWithImage];
Ответ 13
Основываясь на предыдущих ответах. Если вы хотите иметь разницу между значком и названием кнопки, код должен немного измениться, чтобы предотвратить перемещение метки и значка над границами кнопок с внутренним размером.
let margin = CGFloat(4.0)
button.titleEdgeInsets = UIEdgeInsetsMake(0, -button.imageView.frame.size.width, 0, button.imageView.frame.size.width);
button.imageEdgeInsets = UIEdgeInsetsMake(0, button.titleLabel.frame.size.width, 0, -button.titleLabel.frame.size.width)
button.contentEdgeInsets = UIEdgeInsetsMake(0, margin, 0, margin)
Последняя строка кода важна для вычисления размера встроенного контента для автоматического макета.