ios iPhone UIButton - 图像位置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2515998/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:03:34  来源:igfitidea点击:

iPhone UIButton - image position

iosiphonecocoa-touchuibuttonimageedgeinsets

提问by Pavel Yakimenko

I have a UIButtonwith text "Explore the app" and UIImage(>) In Interface Builderit looks like:

我有一个UIButton带有“探索应用程序”和UIImage(>) 的文本,Interface Builder它看起来像:

[ (>) Explore the app ]

But I need to place this UIImageAFTER the text:

但我需要把它放在UIImage文本之后:

[ Explore the app (>) ]

How can I move the UIImageto the right?

我怎样才能UIImage向右移动?

采纳答案by Pavel Yakimenko

Here is my own way to do the thing, (after about 10 years)

这是我自己做这件事的方式,(大约 10 年后)

  1. Subclass from UIButton (Button, as we're living in Swift era)
  2. Put an image and a label in a stack view.
  1. UIButton 的子类(按钮,因为我们生活在 Swift 时代)
  2. 将图像和标签放在堆栈视图中。
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
        }
    }
}

回答by Split

My solution to this is quite simple

我对此的解决方案非常简单

[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);

回答by Alvivi

On iOS 9onwards, seems that a simple way to achieve this is to force the semantic of the view.

iOS 9之后,似乎实现此目的的一种简单方法是强制视图的语义。

enter image description here

在此处输入图片说明

Or programmatically, using:

或以编程方式,使用:

button.semanticContentAttribute = .ForceRightToLeft

回答by Steven Canfield

Set the imageEdgeInsetand titleEdgeInsetto move the components around within your image. You could also create a button using those graphics that is full size, and use that as the background image for the button (then use titleEdgeInsetsto move the title around).

设置imageEdgeInsettitleEdgeInset以在图像内移动组件。您还可以使用这些全尺寸图形创建一个按钮,并将其用作按钮的背景图像(然后用于titleEdgeInsets移动标题)。

回答by Chris Miles

Raymond W's answer is best here. Subclass UIButton with custom layoutSubviews. Extremely simple to do, here's a layoutSubviews implementation that worked for me:

Raymond 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;
}

回答by Raymond W

What about subclassing UIButtonand overriding layoutSubviews?

子类化UIButton和覆盖layoutSubviews呢?

Then post-processing the locations of self.imageView& self.titleLabel

然后对self.imageView&的位置进行后处理self.titleLabel

回答by DrAL3X

Another simple way (that is NOT iOS 9 only) is to subclass UIButton to override these two methods

另一种简单的方法(不仅仅是 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
}

contentEdgeInsetsis already taken into account by using super.

contentEdgeInsets已经通过使用 super 考虑到了。

回答by Luisma

Forcing 'right-to-left' for the button is not an option if your app supports both 'left-to-right' and 'right-to-left'.

如果您的应用程序同时支持“从左到右”和“从右到左”,则不能强制按钮“从右到左”。

The solution that worked for me is a subclass that can be added to the button in the Storyboard and works well with constraints (tested in iOS 11):

对我有用的解决方案是一个子类,它可以添加到 Storyboard 中的按钮并且适用于约束(在 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)
        }

    }

}

Where 'padding' would be the space between the title and the image.

其中“填充”将是标题和图像之间的空间。

回答by ChikabuZ

In 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  
    }
}

回答by BFar

Building off the answer by @split...

通过@split 构建答案...

The answer is fantastic, but it ignores the fact that the button may have custom image and title edge insets that are set beforehand (e.g. in storyboard).

答案很棒,但它忽略了一个事实,即按钮可能具有预先设置的自定义图像和标题边缘插入(例如在故事板中)。

For instance, you may want the image have some padding from the top and bottom of the container, but still move the image to the right side of the button.

例如,您可能希望图像在容器的顶部和底部有一些填充,但仍将图像移动到按钮的右侧。

I extended the concept with this method:-

我用这种方法扩展了这个概念:-

- (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);
}

回答by caliss

// 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);

This creates a right-aligned button, like so:

这将创建一个右对齐按钮,如下所示:

[           button label (>)]

The button doesn't adjust it's width according to the context, so space will appear on the left of the label. You could solve this by calculating the button's frame width from the buttonLabelSize.width and the buttonImageSize.width.

该按钮不会根据上下文调整其宽度,因此标签左侧会出现空格。您可以通过从 buttonLabelSize.width 和 buttonImageSize.width 计算按钮的框架宽度来解决这个问题。