我有一个UIButton
文本“ Explore the app”,并且UIImage
(>)Interface Builder
看起来像:
[ (>) Explore the app ]
但是我需要UIImage
在文本之后放置:
[ Explore the app (>) ]
如何将其UIImage
移至右侧?
我有一个UIButton
文本“ Explore the app”,并且UIImage
(>)Interface Builder
看起来像:
[ (>) Explore the app ]
但是我需要UIImage
在文本之后放置:
[ Explore the app (>) ]
如何将其UIImage
移至右侧?
Answers:
我的解决方法很简单
[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);
semanticContentAttribute
在我们的布局逻辑中覆盖layoutSubviews和尊重,而不是更改semanticContentAttribute
自身。(更改语义方法,将不适用于国际化)
雷蒙德W的答案是最好的。具有自定义layoutSubviews的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;
}
另一种简单的方法(不仅限于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
通过使用super已被考虑在内。
如果您的应用程序同时支持“从左到右”和“从右到左”,则不可以将按钮强制为“从右到左”。
对我有用的解决方案是一个子类,可以将其添加到情节提要中的按钮,并且可以很好地与约束一起使用(在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)
}
}
}
其中“填充”是标题和图像之间的空间。
.forceRightToLeft
是一个选择!.forceLeftToRight
如果使用相反的值()UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft
。
在Swift中:
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
}
}
通过@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);
}
// 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计算按钮的框架宽度来解决此问题。
此解决方案适用于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];
以先前的答案为基础。如果要在图标和按钮标题之间留出一定的空白,则代码必须稍作更改,以防止标签和图标浮动在固有大小的按钮的边界上方。
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)
最后一行代码对于自动布局的固有内容大小计算很重要。
这是我做事的方式(大约10年后)
class CustomButton: Button {
var didLayout: Bool = false // The code must be called only once
override func layoutSubviews() {
super.layoutSubviews()
if !didLayout, let imageView = imageView, let titleLabel = titleLabel {
didLayout = true
let stack = UIStackView(arrangedSubviews: [titleLabel, imageView])
addSubview(stack)
stack.edgesToSuperview() // I use TinyConstraints library. You could handle the constraints directly
stack.axis = .horizontal
}
}
}