Programmatically set image and text on UIButton

后端 未结 6 1752
孤街浪徒
孤街浪徒 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 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);
    }
    }
    

提交回复
热议问题