Search code examples
iosswift3uibuttonautolayoutibdesignable

UIButton with image on left and right side using IBDesignable in Swift 3.0


How to show left and right image on left and right side with text in UIButton using IBDesignable?

I tried to google it to find any answer but did not find any smart answer. I want to do it through storyboard. Please Help

Required Output:

Output Image


Solution

  • You can build on this. After setting buttons in Attributes Inspector this unbutton subclass will reset the title and place images on sides (don't forget to check all edge cases):

    import UIKit
    
    class ViewController: UIViewController {
        @IBOutlet weak var button: DoubleImageButton!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            button.layer.borderWidth = 2.0
            button.layer.borderColor = UIColor.black.cgColor
            button.layer.cornerRadius = button.bounds.height*0.5
        }
    }
    
    
    @IBDesignable
    class DoubleImageButton: UIButton {
        /* Inspectable properties, once modified resets attributed title of the button */
        @IBInspectable var leftImg: UIImage? = nil {
            didSet {
                /* reset title */
                setAttributedTitle()
            }
        }
    
        @IBInspectable var rightImg: UIImage? = nil {
            didSet {
                /* reset title */
                setAttributedTitle()
            }
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            setAttributedTitle()
        }
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            setAttributedTitle()
        }
    
        private func setAttributedTitle() {
            var attributedTitle = NSMutableAttributedString()
    
            /* Attaching first image */
            if let leftImg = leftImg {
                let leftAttachment = NSTextAttachment(data: nil, ofType: nil)
                leftAttachment.image = leftImg
                let attributedString = NSAttributedString(attachment: leftAttachment)
                let mutableAttributedString = NSMutableAttributedString(attributedString: attributedString)
    
                if let title = self.currentTitle {
                    mutableAttributedString.append(NSAttributedString(string: title))
                }
                attributedTitle = mutableAttributedString
            }
    
            /* Attaching second image */
            if let rightImg = rightImg {
                let leftAttachment = NSTextAttachment(data: nil, ofType: nil)
                leftAttachment.image = rightImg
                let attributedString = NSAttributedString(attachment: leftAttachment)
                let mutableAttributedString = NSMutableAttributedString(attributedString: attributedString)
                attributedTitle.append(mutableAttributedString)
            }
    
            /* Finally, lets have that two-imaged button! */
            self.setAttributedTitle(attributedTitle, for: .normal)
        }
    }
    

    In attributes inspector: enter image description here

    Result (adjust my implementation to achieve the best result): enter image description here

    Be sure to check cases when you'll have only right image selected for example but no left image etc. It's a quick solution and not fully tested. Have fun and good luck! ;]