ChatGPT解决这个技术问题 Extra ChatGPT

如何将图像放在 UIButton 中文本的右侧?

如果可以避免,我不想使用子视图。我想要一个包含背景图像、文本和图像的 UIButton。现在,当我这样做时,图像位于文本的左侧。背景图像、文本和图像都有不同的高亮状态。

要在此处向不断增长的列表添加另一个“hack”:您可以将按钮的属性标题设置为包含按钮标题 + 空格 + 图像的属性字符串(作为 NSTextAttachment)。您可能需要调整附件的边界以使其按需要对齐(请参阅 stackoverflow.com/questions/26105803/…)。

S
Sunil Targe

最简单的解决方案:

iOS 10 及更高版本,斯威夫特:

button.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
button.titleLabel?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
button.imageView?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)

在 iOS 10 之前,Swift/Obj-C:

button.transform = CGAffineTransformMakeScale(-1.0, 1.0);
button.titleLabel.transform = CGAffineTransformMakeScale(-1.0, 1.0);
button.imageView.transform = CGAffineTransformMakeScale(-1.0, 1.0);

iOS 9 及更高版本,Swift:(推荐)

button.semanticContentAttribute = .forceRightToLeft

我将它用于导航栏标题视图,但出现了故障。首次加载时很好,但是当您推送视图控制器并弹出它时,标题会翻转。
我发现如果这引起了关于运行时自动布局约束冲突的抱怨,可以通过在 layoutSubviews() 中添加它来修复
如何在文本和图像之间放置更多空间?
@rohinb @jose920405 尝试将 ImageEdgeInsets 和 ContentEdgeInsets 设置为填充(请记住它们已被反转)。例如 button.ImageEdgeInsets = new UIEdgeInsets(0, -leftPadding, 0, leftPadding); button.ContentEdgeInsets = new UIEdgeInsets(0, 0, 0, leftPadding);。那是在 Xamarin 中,但应该足够容易地转换为 Swift/Obj-C。
设置 semanticContentAttribute 的致命缺陷是它破坏画外音导航。画外音导航使用语义内容属性来确定在元素中导航的方向并强制翻转语义意味着用户将到达按钮,然后他们的 VO 导航被翻转并返回到他们刚刚访问的元素而不是下一个一。
m
manmal

尽管一些建议的答案非常有创意且非常聪明,但最简单的解决方案如下:

button.semanticContentAttribute = UIApplication.shared
    .userInterfaceLayoutDirection == .rightToLeft ? .forceLeftToRight : .forceRightToLeft

就如此容易。作为奖励,图像将位于从右到左语言环境的左侧。

编辑:由于这个问题已经被问过几次,这是 iOS 9 +。


我不敢相信这个答案是被接受的。没有人为他们的应用程序进行本地化?
@pallzoltan:这回答了问题(即“如何将图像放在 UIButton 中文本的右侧?”)。本地化与此有什么关系?
不希望布局在 RTL 语言中“翻转”的情况并不多。直接设置 semanticContentAttribute 只是一种技巧/解决方法,而不是真正的解决方案。
我的方法是,您不知道提出问题的人正在构建什么,因此最好考虑布局的灵活性。
这是如何被接受的答案?它不是最简单的,甚至不是远程接近正确的分析器。 UIUserInterfaceLayoutDirection.rightToLeft 的 Apple 文档指出:“布局方向从右到左。当使用本地化(如阿拉伯语或希伯来语)运行时,该值是合适的,用户界面布局原点应位于坐标系的右边缘。” UIButton 有一个可以在代码或 IB 中设置的 imageEdgeInsets 属性。为此专门指定。这是重新定位按钮图像的正确方法。
Z
Zaporozhchenko Oleksandr

为 XCODE 9 更新(通过 Interface Builder)

Interface Builder 提供了一种更简单的方法。

选择 UIButton 并在 View Utilities > Semantic 中选择此选项:

https://i.stack.imgur.com/YMacE.png

可选 - 第二步:

如果要调整图像和标题之间的间距,可以在此处更改 Image Inset:

https://i.stack.imgur.com/Cqap0.png

希望有帮助!


在 Xcode 9.0 beta 5 (9M202q) 中,不幸的是,您只能在运行时看到结果——在故事板中,它仍然显示左侧的图像。另请注意,因此需要一些试验和错误来设置正确的插图。
请不要这样做 - 这会破坏从右到左语言的本地化。
B
Ben Baron

子类化 UIButton 是完全没有必要的。相反,您可以简单地为图像插入设置一个高左插入值,并为标题设置一个小的右插入值。像这样的东西:

button.imageEdgeInsets = UIEdgeInsetsMake(0., button.frame.size.width - (image.size.width + 15.), 0., 0.);
button.titleEdgeInsets = UIEdgeInsetsMake(0., 0., 0., image.size.width);

它有效,但请记住,今天使用自动布局,您必须在 viewDidAppear 而不是 viewDidLoad 上进行
C
Community

我将此归功于 Inspire48。根据他的建议并查看其他问题,我想出了这个。子类 UIButton 并覆盖这些方法。

@implementation UIButtonSubclass

- (CGRect)imageRectForContentRect:(CGRect)contentRect
{
    CGRect frame = [super imageRectForContentRect:contentRect];
    frame.origin.x = CGRectGetMaxX(contentRect) - CGRectGetWidth(frame) -  self.imageEdgeInsets.right + self.imageEdgeInsets.left;
    return frame;
}

- (CGRect)titleRectForContentRect:(CGRect)contentRect
{
    CGRect frame = [super titleRectForContentRect:contentRect];
    frame.origin.x = CGRectGetMinX(frame) - CGRectGetWidth([self imageRectForContentRect:contentRect]);
    return frame;
}

@end

UIButton 是一个类簇,不应该被子类化。
这不是真的,文档明确提到了子类化并提供了您应该为自定义布局行为覆盖的方法。
developer.apple.com/library/ios/documentation/uikit/reference/… buttonWithType If you subclass UIButton, this method does not return an instance of your subclass. If you want to create an instance of a specific subclass, you must alloc/init the button directlybackgroundRectForBounds 提供自定义背景装饰的子类可以覆盖此方法并返回修改后的边界矩形以防止按钮绘制任何自定义内容。他们不介意子类。
看起来这个公式更适合镜像图像帧:frame.origin.x = CGRectGetMaxX(contentRect) - CGRectGetWidth(frame) - self.imageEdgeInsets.right + self.imageEdgeInsets.left - frame.origin.x; 它更适用于 UIControlContentHorizontalAlignmentCenter 和其他...
@GwendalRoué 仅仅因为它更短并不意味着它更好。这是一种更骇人听闻的方式,它使按钮忽略实际的插入,并且可能会中断从右到左的语言。有了这个答案,您就可以完全控制布局
P
Piotr Tomasik

更改标题时只需更新插图。您需要在另一侧使用相等且相反的插图来补偿插图。

[thebutton setTitle:title forState:UIControlStateNormal];
thebutton.titleEdgeInsets = UIEdgeInsetsMake(0, -thebutton.imageView.frame.size.width, 0, thebutton.imageView.frame.size.width);
thebutton.imageEdgeInsets = UIEdgeInsetsMake(0, thebutton.titleLabel.frame.size.width, 0, -thebutton.titleLabel.frame.size.width);

您可能希望在之前添加 [thebutton.titleLabel sizeToFit];。如果您没有触发布局,宽度可能为零。图像大小也是如此(只需使用 UIImage.size 而不是 imageView 大小)
@delrox 好点。可以使用 titleWidth = [self.titleLabel sizeThatFits:CGSizeMake(CGFLOAT_MAX, self.bounds.size.height)].width;(或者如果您担心尚未建立按钮框架,也可以使用 CGFLOAT_MAX 作为高度)和 imageWidth = self.currentImage.size.width;
在 viewDidLayoutSubviews 上完美运行
我不得不把它放在我的 UITableViewCell 子类的 layoutSubviews 中,但它工作得很好。谢谢!
A
Alexander Vasenin

截至 2016 年 1 月,所有这些答案都是不必要的。在 Interface Builder 中,将 View Semantic 设置为 Force Right-to-Left,或者如果您更喜欢编程方式,semanticContentAttribute = .forceRightToLeft 这将导致图像出现在文本的右侧。


可悲的是,它不支持 9 岁以上的 ios。还是不错的答案。
我很遗憾地报告,在用于 UIBarButtonItem 的 UIButton 上设置它并没有导致任何变化。
正如@Amelia 提到的,如果您调用 UIBarButtonItem(customView: button),它不起作用,但如果您将按钮包装在某个空视图中,它将起作用
@tt.Kilew ,使用 XCode 8.1 就可以了。我设置了 uiButton.semanticContentAttribute = .forceRightToLeft 并提供 let nextButton = UIBarButtonItem(customView: uiButton)
如果您支持辅助功能,请不要使用此选项,因为这会破坏 VoiceOver 在屏幕上说出的元素的顺序。
G
Gennadiy Ryabkin

在界面生成器中,您可以为 UIButton 配置选项 Edge Insets,分别为三个部分:内容、图像、标题

https://i.stack.imgur.com/KdBVa.png

Xcode 8:

https://i.stack.imgur.com/FQzaB.png


在我看来这实际上是最佳答案stackoverflow.com/a/39013315/1470374))
J
Jean-Baptiste

更新:斯威夫特 3

class ButtonIconRight: UIButton {
    override func imageRect(forContentRect contentRect:CGRect) -> CGRect {
        var imageFrame = super.imageRect(forContentRect: contentRect)
        imageFrame.origin.x = super.titleRect(forContentRect: contentRect).maxX - imageFrame.width
        return imageFrame
    }

    override func titleRect(forContentRect contentRect:CGRect) -> CGRect {
        var titleFrame = super.titleRect(forContentRect: contentRect)
        if (self.currentImage != nil) {
            titleFrame.origin.x = super.imageRect(forContentRect: contentRect).minX
        }
        return titleFrame
    }
}

Swift 2 的原始答案:

处理所有水平对齐的解决方案,带有 Swift 实现示例。如果需要,只需转换为 Objective-C。

class ButtonIconRight: UIButton {
    override func imageRectForContentRect(contentRect:CGRect) -> CGRect {
        var imageFrame = super.imageRectForContentRect(contentRect)
        imageFrame.origin.x = CGRectGetMaxX(super.titleRectForContentRect(contentRect)) - CGRectGetWidth(imageFrame)
        return imageFrame
    }

    override func titleRectForContentRect(contentRect:CGRect) -> CGRect {
        var titleFrame = super.titleRectForContentRect(contentRect)
        if (self.currentImage != nil) {
            titleFrame.origin.x = CGRectGetMinX(super.imageRectForContentRect(contentRect))
        }
        return titleFrame
    }
}

另外值得注意的是,它可以很好地处理图像和标题插图。

灵感来自 jasongregori 的回答 ;)


这个解决方案对我有用,但是我的图像周围需要一些空间,所以我添加了以下代码: self.contentEdgeInsets = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0)
我喜欢这种方式,因为您可以将 @IBDesignable 添加到类并在设计时看到它翻转。
我更喜欢这个解决方案,因为它甚至在放入导航栏中时也可以工作。
M
Mark Hennings

我决定不使用标准按钮图像视图,因为提出的移动它的解决方案感觉很笨拙。这给了我想要的美感,通过改变约束来重新定位按钮是很直观的:

extension UIButton {
    func addRightIcon(image: UIImage) {
        let imageView = UIImageView(image: image)
        imageView.translatesAutoresizingMaskIntoConstraints = false

        addSubview(imageView)

        let length = CGFloat(15)
        titleEdgeInsets.right += length

        NSLayoutConstraint.activate([
            imageView.leadingAnchor.constraint(equalTo: self.titleLabel!.trailingAnchor, constant: 10),
            imageView.centerYAnchor.constraint(equalTo: self.titleLabel!.centerYAnchor, constant: 0),
            imageView.widthAnchor.constraint(equalToConstant: length),
            imageView.heightAnchor.constraint(equalToConstant: length)
        ])
    }
}

https://i.stack.imgur.com/abObc.png


这不会响应点击,文本变暗但图像没有
还要检查您在小型设备上的扩展。
t
tt.Kilew

如果这需要在 UIBarButtonItem 中完成,则应在视图中使用额外的包装 这将起作用

let view = UIView()
let button = UIButton()
button.setTitle("Skip", for: .normal)
button.setImage(#imageLiteral(resourceName:"forward_button"), for: .normal)
button.semanticContentAttribute = .forceRightToLeft
button.sizeToFit()
view.addSubview(button)
view.frame = button.bounds
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: view)

这行不通

let button = UIButton()
button.setTitle("Skip", for: .normal)
button.setImage(#imageLiteral(resourceName:"forward_button"), for: .normal)
button.semanticContentAttribute = .forceRightToLeft
button.sizeToFit()
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button)

UIBarButtonItem 的问题确实让我发疯了几个小时,直到我找到了这个答案。向你致敬。
N
Nazmul Hasan

自己做。 Xcode10、swift4、

用于以编程方式进行 UI 设计

https://i.stack.imgur.com/d7k3y.png

 lazy var buttonFilter : ButtonRightImageLeftTitle = {
    var button = ButtonRightImageLeftTitle()
    button.setTitle("Playfir", for: UIControl.State.normal)
    button.setImage(UIImage(named: "filter"), for: UIControl.State.normal)
    button.backgroundColor = UIColor.red
    button.contentHorizontalAlignment = .left
    button.titleLabel?.font = UIFont.systemFont(ofSize: 16)
    return button
}()

边缘插入值应用于矩形以缩小或扩展该矩形表示的区域。通常,在视图布局期间使用边缘插入来修改视图的框架。正值会导致帧被插入(或缩小)指定的量。负值导致框架以指定的量开始(或扩展)。

class ButtonRightImageLeftTitle: UIButton {

    override func layoutSubviews() {
        super.layoutSubviews()

        guard imageView != nil else { return }

        imageEdgeInsets = UIEdgeInsets(top: 5, left: (bounds.width - 35), bottom: 5, right: 5)
        titleEdgeInsets = UIEdgeInsets(top: 0, left: -((imageView?.bounds.width)! + 10), bottom: 0, right: 0 )

    }
}

用于 StoryBoard UI 设计

https://i.stack.imgur.com/q0Y1D.png


有没有办法让它更优雅?
你知道如何消除标题前的间隙吗?
V
Vitalii Gozhenko

这是具有居中对齐内容的 UIButton 的解决方案。此代码使图像右对齐并允许使用 imageEdgeInsetstitleEdgeInsets 进行宝贵的定位。

https://i.stack.imgur.com/lEAm4.png

使用您的自定义类子类 UIButton 并添加:

- (CGRect)imageRectForContentRect:(CGRect)contentRect {
    CGRect frame = [super imageRectForContentRect:contentRect];
    CGFloat imageWidth = frame.size.width;
    CGRect titleRect = CGRectZero;
    titleRect.size = [[self titleForState:self.state] sizeWithAttributes:@{NSFontAttributeName: self.titleLabel.font}];
    titleRect.origin.x = (self.frame.size.width - (titleRect.size.width + imageWidth)) / 2.0 + self.titleEdgeInsets.left - self.titleEdgeInsets.right;
    frame.origin.x = titleRect.origin.x + titleRect.size.width - self.imageEdgeInsets.right + self.imageEdgeInsets.left;
    return frame;
}

- (CGRect)titleRectForContentRect:(CGRect)contentRect {
    CGFloat imageWidth = [self imageForState:self.state].size.width;
    CGRect frame = [super titleRectForContentRect:contentRect];
    frame.origin.x = (self.frame.size.width - (frame.size.width + imageWidth)) / 2.0 + self.titleEdgeInsets.left - self.titleEdgeInsets.right;
    return frame;
}

您也可以将 IBDESIGNABLE 添加到类标题中以在故事板 yadi.sk/i/fd6Si-BJqzCFD 中观看它
a
akashlal.com

iOS 15 带来了一个更新,您现在可以以更简单的非混乱方式处理按钮中的图像放置,即。没有插图。

https://i.stack.imgur.com/HE8YT.png

https://i.stack.imgur.com/h7wzd.png

这不是向后兼容的功能,仅适用于 iOS15+,如 WWDC '21 - https://developer.apple.com/videos/play/wwdc2021/10064/?time=236

开发者文档:https://developer.apple.com/documentation/uikit/uibutton/configuration?changes=_4


这是现代项目中任何人的最佳答案。
c
cnotethegr8

由于转换解决方案在 iOS 11 中不起作用,我决定编写一种新方法。

调整按钮 semanticContentAttribute 使我们的图像很好地向右移动,而无需在文本更改时重新布局。因此,它是理想的解决方案。但是我仍然需要 RTL 支持。应用程序无法在同一会话中更改其布局方向这一事实很容易解决此问题。

话虽如此,这很简单。

extension UIButton {
    func alignImageRight() {
        if UIApplication.shared.userInterfaceLayoutDirection == .leftToRight {
            semanticContentAttribute = .forceRightToLeft
        }
        else {
            semanticContentAttribute = .forceLeftToRight
        }
    }
}

M
Musa almatri

延伸方式

使用扩展在右侧使用自定义偏移设置图像

   extension UIButton {
    func addRightImage(image: UIImage, offset: CGFloat) {
        self.setImage(image, for: .normal)
        self.imageView?.translatesAutoresizingMaskIntoConstraints = false
        self.imageView?.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: 0.0).isActive = true
        self.imageView?.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -offset).isActive = true
    }
}

F
Freeubi

Swift - 扩展 UiButton 并放置这些行

    if let imageWidth = self.imageView?.frame.width {
        self.titleEdgeInsets = UIEdgeInsetsMake(0, -imageWidth, 0, imageWidth);
    }

    if let titleWidth = self.titleLabel?.frame.width {
        let spacing = titleWidth + 20
        self.imageEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, -spacing);
    }

E
Erik van der Neut

建立在 Piotr Tomasik 的优雅解决方案之上:如果您还想在按钮标签和图像之间留出一点间距,则将其包含在边缘插图中,如下所示(在此处复制我的代码,这对我来说非常有效):

    CGFloat spacing          = 3;
    CGFloat insetAmount      = 0.5 * spacing;

    // First set overall size of the button:
    button.contentEdgeInsets = UIEdgeInsetsMake(0, insetAmount, 0, insetAmount);
    [button sizeToFit];

    // Then adjust title and image insets so image is flipped to the right and there is spacing between title and image:
    button.titleEdgeInsets   = UIEdgeInsetsMake(0, -button.imageView.frame.size.width - insetAmount, 0,  button.imageView.frame.size.width  + insetAmount);
    button.imageEdgeInsets   = UIEdgeInsetsMake(0, button.titleLabel.frame.size.width + insetAmount, 0, -button.titleLabel.frame.size.width - insetAmount);

感谢 Piotr 的解决方案!

埃里克


@lulian:我最近一直在使用Liau Jian Jie 的解决方案(这里接受的答案),效果很好,是一个非常优雅的解决方案。
这对我也不起作用,因为它改变了文本的对齐方式。
A
Ashutosh Mishra

接受@Piotr 的回答并将其制成 Swift 扩展。确保在调用它之前设置图像和标题,以便按钮大小正确。

 extension UIButton {
    
    /// Makes the ``imageView`` appear just to the right of the ``titleLabel``.
    func alignImageRight() {
        if let titleLabel = self.titleLabel, imageView = self.imageView {
            // Force the label and image to resize.
            titleLabel.sizeToFit()
            imageView.sizeToFit()
            imageView.contentMode = .ScaleAspectFit
            
            // Set the insets so that the title appears to the left and the image appears to the right. 
            // Make the image appear slightly off the top/bottom edges of the button.
            self.titleEdgeInsets = UIEdgeInsets(top: 0, left: -1 * imageView.frame.size.width,
                bottom: 0, right: imageView.frame.size.width)
            self.imageEdgeInsets = UIEdgeInsets(top: 4, left: titleLabel.frame.size.width,
                bottom: 4, right: -1 * titleLabel.frame.size.width)
          }
        }
     }

C
Community

子类化和覆盖 layoutSubviews 可能是您最好的方法。

引用自:iPhone UIButton - image position


继承 UIButton 绝对没有问题。
C
Chris

一个快速的选项,可以在不使用任何插图的情况下完成您想要的操作:

class RightImageButton: UIButton {

    override func layoutSubviews() {
        super.layoutSubviews()

        if let  textSize = titleLabel?.intrinsicContentSize(),
                imageSize = imageView?.intrinsicContentSize() {
            let wholeWidth = textSize.width + K.textImageGap + imageSize.width
            titleLabel?.frame = CGRect(
                x: round(bounds.width/2 - wholeWidth/2),
                y: 0,
                width: ceil(textSize.width),
                height: bounds.height)
            imageView?.frame = CGRect(
                x: round(bounds.width/2 + wholeWidth/2 - imageSize.width),
                y: RoundRetina(bounds.height/2 - imageSize.height/2),
                width: imageSize.width,
                height: imageSize.height)
        }
    }

    struct K {
        static let textImageGap: CGFloat = 5
    }

}

L
Lukasz

一旦我启用了自动布局,这里提到的解决方案就会停止工作。我不得不想出我自己的:

子类 UIButton 并覆盖 layoutSubviews 方法:

//
//  MIThemeButtonImageAtRight.m
//  Created by Lukasz Margielewski on 7/9/13.
//

#import "MIThemeButtonImageAtRight.h"

static CGRect CGRectByApplyingUIEdgeInsets(CGRect frame, UIEdgeInsets insets);

@implementation MIThemeButtonImageAtRight

- (void)layoutSubviews
{
    [super layoutSubviews];

    CGRect contentFrame = CGRectByApplyingUIEdgeInsets(self.bounds, self.contentEdgeInsets);

    CGRect frameIcon = self.imageView.frame;
    CGRect frameText = self.titleLabel.frame;

    frameText.origin.x = CGRectGetMinX(contentFrame) + self.titleEdgeInsets.left;
    frameIcon.origin.x = CGRectGetMaxX(contentFrame) - CGRectGetWidth(frameIcon);

    self.imageView.frame = frameIcon;
    self.titleLabel.frame = frameText;
}

@end

static CGRect CGRectByApplyingUIEdgeInsets(CGRect frame, UIEdgeInsets insets){

    CGRect f = frame;

    f.origin.x += insets.left;
    f.size.width -= (insets.left + insets.right);
    f.origin.y += (insets.top);
    f.size.height -= (insets.top + insets.bottom);

    return f;

}

结果:

https://i.stack.imgur.com/IH6V4.png


S
Sourabh Sharma

jasongregori 给出的 swift 3.0 迁移解决方案

class ButtonIconRight: UIButton {
        override func imageRect(forContentRect contentRect: CGRect) -> CGRect {
            var imageFrame = super.imageRect(forContentRect: contentRect)
           imageFrame.origin.x = super.titleRect(forContentRect: contentRect).maxX - imageFrame.width
        return imageFrame
        }

        override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
            var titleFrame = super.titleRect(forContentRect: contentRect)
            if (self.currentImage != nil) {
                titleFrame.origin.x = super.imageRect(forContentRect: contentRect).minX
            }
            return titleFrame
        }

r
rbaldwin

Xcode 11.4 斯威夫特 5.2

对于任何试图用 V 形像这样反映后退按钮样式的人:

https://i.stack.imgur.com/90vDn.jpg

import UIKit

class NextBarButton: UIBarButtonItem {

    convenience init(target: Any, selector: Selector) {

        // Create UIButton
        let button = UIButton(frame: .zero)

        // Set Title
        button.setTitle("Next", for: .normal)
        button.setTitleColor(.systemBlue, for: .normal)
        button.titleLabel?.font = UIFont.systemFont(ofSize: 17)

        // Configure Symbol
        let config = UIImage.SymbolConfiguration(pointSize: 19.0, weight: .semibold, scale: .large)
        let image = UIImage(systemName: "chevron.right", withConfiguration: config)
        button.setImage(image, for: .normal)

        // Add Target
        button.addTarget(target, action: selector, for: .touchUpInside)

        // Put the Image on the right hand side of the button
        // Credit to liau-jian-jie for this part
        button.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
        button.titleLabel?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
        button.imageView?.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)

        // Customise spacing to match system Back button
        button.imageEdgeInsets = UIEdgeInsets(top: 0.0, left: -18.0, bottom: 0.0, right: 0.0)
        button.titleEdgeInsets = UIEdgeInsets(top: 0.0, left: -12.0, bottom: 0.0, right: 0.0)

        self.init(customView: button)
    }
}

执行:

override func viewDidLoad() {
    super.viewDidLoad()
    let nextButton = NextBarButton(target: self, selector: #selector(nextTapped))
    navigationItem.rightBarButtonItem = nextButton
}

@objc func nextTapped() {
    // your code
}

P
Phil Dukhov

使用 Xcode 13.3,我通过以下几个步骤解决了问题,并为图像添加了填充。

创建按钮后,请执行以下操作:

首先定义图像: let symbol = UIImage(named: "put name of your symbol here") 然后在创建按钮的 viewDidLoad 中,在 1 中初始化上面定义的图像,将图像添加到按钮并设置属性: button.setImage(symbol, for: .normal) button.semanticContentAttribute = .forceRightToLeft button.configuration?.imagePadding = 2

并且不要忘记将您的按钮添加到视图中。


A
Alexander Volkov

斯威夫特 3:

open override func imageRect(forContentRect contentRect: CGRect) -> CGRect {
    var frame = super.imageRect(forContentRect: contentRect)
    let  imageWidth = frame.size.width
    var titleRect = CGRect.zero
    titleRect.size = self.title(for: self.state)!.size(attributes: [NSFontAttributeName: self.titleLabel!.font])
    titleRect.origin.x = (self.frame.size.width - (titleRect.size.width + imageWidth)) / 2.0 + self.titleEdgeInsets.left - self.titleEdgeInsets.right;
    frame.origin.x = titleRect.origin.x + titleRect.size.width - self.imageEdgeInsets.right + self.imageEdgeInsets.left;
    return frame
}

open override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
    var frame = super.titleRect(forContentRect: contentRect)
    if let imageWidth = self.image(for: self.state)?.size.width {
        frame.origin.x = (self.frame.size.width - (frame.size.width + imageWidth)) / 2.0 + self.titleEdgeInsets.left - self.titleEdgeInsets.right;
    }
    return frame
}

r
rock workinghouse

约束条件如何?与语义内容属性不同,它们不会改变语义。可能是这样的:

 button.rightAnchorconstraint(equalTo: button.rightAnchor).isActive = true

或在 Objective-C 中:

[button.imageView.rightAnchor constraintEqualToAnchor:button.rightAnchor].isActive = YES;

注意事项:未经测试,iOS 9+


j
jeet.chanchawat

在尝试了互联网上的多种解决方案后,我没有达到确切的要求。所以我最终编写了自定义实用程序代码。发布以帮助将来的人。在 swift 4.2 上测试

// This function should be called in/after viewDidAppear to let view render
    func addArrowImageToButton(button: UIButton, arrowImage:UIImage = #imageLiteral(resourceName: "my_image_name") ) {
        let btnSize:CGFloat = 32
        let imageView = UIImageView(image: arrowImage)
        let btnFrame = button.frame
        imageView.frame = CGRect(x: btnFrame.width-btnSize-8, y: btnFrame.height/2 - btnSize/2, width: btnSize, height: btnSize)
        button.addSubview(imageView)
        //Imageview on Top of View
        button.bringSubviewToFront(imageView)
    }

S
Sushil Vyas

对于这个问题,您可以在“带有 UIImage 视图的标签”中创建 UIView 并将 UIView 类设置为 UIControl 并将 IBAction 创建为侧边

https://i.stack.imgur.com/CDSht.png


R
Rashid Latif

斯威夫特 4 & 5

改变 UIButton 图像的方向(RTL 和 LTR)

extension UIButton {
    func changeDirection(){
       isArabic ? (self.contentHorizontalAlignment = .right) : (self.contentHorizontalAlignment = .left)
        // left-right margin 
        self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
        self.titleEdgeInsets = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
    }
}

Utility 是什么?
我只是删除了实用程序,它是我代码中的一个类,我可以在其中检查所选语言是阿拉伯语还是英语