以编程方式在UIButton上设置图像和文本

43

我需要以图像和文本形式创建按钮并且要包括正常和高亮状态。由于需要在UIScrollView上创建按钮,因此不能使用Interface Builder进行构建。这是我目前的代码:

- (void)loadView {
    CGRect fullScreenRect=[[UIScreen mainScreen] applicationFrame];
    scrollView=[[UIScrollView alloc] initWithFrame:fullScreenRect];
    scrollView.contentSize=CGSizeMake(320,960);

    UIImageView *tempImageView2 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image.jpeg"]];

    UIImage * buttonImage = [UIImage imageNamed:@"contentlist_active.png"];

    self.view=scrollView;
    [scrollView addSubview:tempImageView2];

    btn = [UIButton buttonWithType:UIButtonTypeCustom];
    btn.frame = CGRectMake(22, 100, 277, 32);

    [btn setImage:buttonImage forState:UIControlStateNormal]; 

    [btn setTitle:@"hello world" forState:UIControlStateNormal];
    [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

    [scrollView addSubview:btn];

}

但是按钮上的文本没有显示出来。如果我注释掉buttonsetImage,那么文本就完美地显示出来了,否则就不行。我能同时拥有文本和图像吗?


你能告诉我如何对齐文本吗?比如,如果我要放置阿拉伯文本,我该如何将其左对齐或右对齐。 - Haris Hussain
7个回答

80

UIButtons的setImage方法将图片设置在标题上方,这样你就无法看到其下方的文本。因此建议使用setBackgroundImage方法来为按钮设置图像。

Objective-C:

[btn setBackgroundImage:buttonImage forState:UIControlStateNormal]; 

Swift:

->

Swift:

myButton.setBackgroundImage(buttonImage, forState: .normal)

1
你能告诉我如何对齐文本,左对齐或右对齐,例如当我要放置阿拉伯文本时。 - Haris Hussain
1
[yourButton.titleLabel setTextAlignment:UITextAlignmentLeft];你的按钮.标题标签文本对齐 = UITextAlignmentLeft; - ipraba
我的图片在iPad air 2上运行应用程序时仍无法适应按钮,因为它们的分辨率较低。有什么建议可以拉伸它们以填充,并且图片未应用于背景。 - tryKuldeepTanwar
只是想指出,如果您想要稍微更快的语法,UIControlState是不必要的。 - H4Hugo

24

你犯了一个错误,你正在这样做

[btn setBackgroundImage:buttonImage forState:UIControlStateNormal]; 

取代

[btn setImage:buttonImage forState:UIControlStateNormal]; 
这将正常工作。

6

Swift 4

  • 您可以将图像和文本一起设置为属性文本,您可以通过实现以下代码来实现此操作:
  • 这里我有一个自定义函数,在其中您可以传递标题字符串按钮图像,它将返回一个带属性的文本,您可以将其设置为UIButton / UILabel标题或文本。

- 如果您想显示一个带有标题前缀的图像

func AttributedTextwithImagePrefix(AttributeImage : UIImage , AttributedText : String , buttonBound : UIButton) -> NSMutableAttributedString
{
    let fullString = NSMutableAttributedString(string: "   ")
    let image1Attachment = NSTextAttachment()
    image1Attachment.bounds = CGRect(x: 0, y: ((buttonBound.titleLabel?.font.capHeight)! - AttributeImage.size.height).rounded() / 2, width: AttributeImage.size.width, height: AttributeImage.size.height)
    image1Attachment.image = AttributeImage
    let image1String = NSAttributedString(attachment: image1Attachment)
    fullString.append(image1String)
    fullString.append(NSAttributedString(string: "  " + AttributedText))
    return fullString
}

这是你可以使用它的方法:
self.btnprefix.setAttributedTitle(AttributedTextwithImagePrefix(AttributeImage: #imageLiteral(resourceName: "avtar"), AttributedText: " prefix avtar", buttonBound: self.prefix), for: .normal)

- 如果您想显示带有标题后缀的图像

func AttributedTextwithImageSuffix(AttributeImage : UIImage , AttributedText : String , buttonBound : UIButton) -> NSMutableAttributedString
{
    let fullString = NSMutableAttributedString(string: AttributedText + "  ")
    let image1Attachment = NSTextAttachment()
    image1Attachment.bounds = CGRect(x: 0, y: ((buttonBound.titleLabel?.font.capHeight)! - AttributeImage.size.height).rounded() / 2, width: AttributeImage.size.width, height: AttributeImage.size.height)
    image1Attachment.image = AttributeImage
    let image1String = NSAttributedString(attachment: image1Attachment)
    fullString.append(image1String)
    fullString.append(NSAttributedString(string: ""))
    return fullString
}

这是如何使用它的方法:

self.btnsuffix.setAttributedTitle(AttributedTextwithImageSuffix(AttributeImage: #imageLiteral(resourceName: "avtar"), AttributedText: " suffix avtar", buttonBound: self.btnsuffix), for: .normal)

输出结果将是

输入图片描述


4
你尝试过吗?
[btn setBackgroundImage:buttonImage forState:UIControlStateHighlighted];

这可能会解决你的问题。

2

我认为Azharhussain Shaikh的答案在处理较大的图片时不起作用,所以我稍微改动了一下,并将其转换为Swift 4扩展程序到UIButton中。 以下是代码:

extension UIButton {
func setAttributedTextWithImagePrefix(image: UIImage, text: String, for state: UIControl.State) {
    let fullString = NSMutableAttributedString()

    if let imageString = getImageAttributedString(image: image) {
        fullString.append(imageString)
    }

    fullString.append(NSAttributedString(string: "  " + text))

    self.setAttributedTitle(fullString, for: state)
}

func setAttributedTextWithImageSuffix(image: UIImage, text: String, for state: UIControl.State) {
    let fullString = NSMutableAttributedString(string: text + "  ")

    if let imageString = getImageAttributedString(image: image) {
        fullString.append(imageString)
    }

    self.setAttributedTitle(fullString, for: state)
}

fileprivate func getImageAttributedString(image: UIImage) -> NSAttributedString? {
    let buttonHeight = self.frame.height

    if let resizedImage = image.getResizedWithAspect(maxHeight: buttonHeight - 10) {
        let imageAttachment = NSTextAttachment()
        imageAttachment.bounds = CGRect(x: 0, y: ((self.titleLabel?.font.capHeight)! - resizedImage.size.height).rounded() / 2, width: resizedImage.size.width, height: resizedImage.size.height)
        imageAttachment.image = resizedImage
        let image1String = NSAttributedString(attachment: imageAttachment)
        return image1String
    }

    return nil
}
}

还需要一个UIImage的扩展:

extension UIImage {

func getResized(size: CGSize) -> UIImage? {
    if UIScreen.main.responds(to: #selector(NSDecimalNumberBehaviors.scale)) {
        UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale);
    } else {
        UIGraphicsBeginImageContext(size);
    }

    self.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height));
    let newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

func getResizedWithAspect(scaledToMaxWidth width: CGFloat? = nil, maxHeight height: CGFloat? = nil) -> UIImage? {
    let oldWidth = self.size.width;
    let oldHeight = self.size.height;

    var scaleToWidth = oldWidth
    if let width = width {
        scaleToWidth = width
    }

    var scaleToHeight = oldHeight
    if let height = height {
        scaleToHeight = height
    }

    let scaleFactor = (oldWidth > oldHeight) ? scaleToWidth / oldWidth : scaleToHeight / oldHeight;

    let newHeight = oldHeight * scaleFactor;
    let newWidth = oldWidth * scaleFactor;
    let newSize = CGSize(width: newWidth, height: newHeight);

    return getResized(size: newSize);
}
}

1

枚举

 enum buttonImageDirection: Int {
                    case left = 0
                    case right
                    case top
                    case bottom
    }

扩展

extension UIButton{
     func setButtonWithTitleAndImage(fontSize : CGFloat = 15, fontType : String = "Poppins-Medium", textColor: UIColor, tintColor : UIColor, bgColor:UIColor = .clear, buttonImage: UIImage?, imagePosition:buttonImageDirection = .left, imageSizeHW: CGFloat = 30){
            if imageView != nil {
                let image = buttonImage?.withRenderingMode(.alwaysTemplate)
                self.setImage(image, for: .normal)
                self.titleLabel?.font = UIFont(name: fontType, size: fontSize)
                self.setTitleColor(textColor, for: .normal)
                self.tintColor = tintColor
                self.backgroundColor = bgColor
                
                switch imagePosition{
                case .left:
                    imageEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: (bounds.width - (imageSizeHW + 5)))
                    titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: (imageView?.frame.width)!)
                case .right:
                    imageEdgeInsets = UIEdgeInsets(top: 5, left: (bounds.width - (imageSizeHW + 5)), bottom: 5, right: 5)
                    titleEdgeInsets = UIEdgeInsets(top: 0, left: (imageView?.frame.width)!, bottom: 0, right: 0)
                case .top:
                    imageEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: (bounds.width - (imageSizeHW + 5)), right: 5)
                    titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: (imageView?.frame.height)!, right: 0)
                case .bottom:
                    imageEdgeInsets = UIEdgeInsets(top: (bounds.width - (imageSizeHW + 5)), left: 5, bottom: 5, right: 5)
                    titleEdgeInsets = UIEdgeInsets(top: (imageView?.frame.height)!, left: 0, bottom: 0, right: 0)
                }
            }
            self.layoutIfNeeded()
        }
}
  • 确保按钮的高度和宽度必须大于或等于图片

myButton. setButtonWithTitleAndImage(fontSize : 15, fontType : "Poppins-Medium", textColor: UIColor.red, tintColor : UIColor.red, bgColor: UIColor.white, buttonImage: UIImage(named: "Bell.png"), imagePosition: .left, imageSizeHW: 30)

0
       var menuButton:UIButton?

    override func viewWillAppear(animated: Bool) {
  menuButton =  UIButton(frame: CGRectMake(0,0,30,30))
        menuButton?.setBackgroundImage(UIImage(named: "menu.png"), forState: UIControlState.Normal)

    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接