Programmatically set image and text on UIButton

后端 未结 6 1751
孤街浪徒
孤街浪徒 2020-12-28 13:46

I need to create button programatically with an image for normal and highlighted state as well text. I cannot build it using Interface Builder, because I need to create butt

相关标签:
6条回答
  • 2020-12-28 13:54

    You've made a mistake there, you're doing

    [btn setBackgroundImage:buttonImage forState:UIControlStateNormal]; 
    

    instead of

    [btn setImage:buttonImage forState:UIControlStateNormal]; 
    

    This will work fine.

    0 讨论(0)
  • 2020-12-28 13:54

    Have you tried

    [btn setBackgroundImage:buttonImage forState:UIControlStateHighlighted];
    

    It might solve your problem.

    0 讨论(0)
  • 2020-12-28 13:56

    Swift 4

    • You can set the image and text together as a attribute text and you can do this by implementing below code:
    • here i have customised function in which you can pass the title string and button image it will returned you an attributed text and you can set on UIButton/UILabel title as a attributed title/text.

    - if you want to display an image prefix with title

    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
    }
    

    this is how you can use this :

    self.btnprefix.setAttributedTitle(AttributedTextwithImagePrefix(AttributeImage: #imageLiteral(resourceName: "avtar"), AttributedText: " prefix avtar", buttonBound: self.prefix), for: .normal)
    

    - if you want to display an image suffix with title

    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
    }
    

    this is how you can use this :

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

    OUTPUT WILL BE

    0 讨论(0)
  • 2020-12-28 14:03

    I think Azharhussain Shaikh's answer is not working with larger images so I've twisted it a little and converted to a Swift 4 extension to UIButton. There you go:

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

    and a extension to 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);
    }
    }
    
    0 讨论(0)
  • 2020-12-28 14:11

    UIButtons setImage sets the image above the title so you will not be able to see the text below it. So try to set image to your button with setBackgroundImage.

    Objective-C:

    [btn setBackgroundImage:buttonImage forState:UIControlStateNormal]; 
    

    Swift:

    myButton.setBackgroundImage(buttonImage, forState: .normal)
    
    0 讨论(0)
  • 2020-12-28 14:15
           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)
    
        }
    
    0 讨论(0)
提交回复
热议问题