Button with Image and Text vertically aligned using autolayout constraints

14,580

Solution 1

Few days ago, I solved similar problem,try this

 private func adjustImageAndTitleOffsetsForButton (button: UIButton) {

    let spacing: CGFloat = 6.0

    let imageSize = button.imageView!.frame.size

    button.titleEdgeInsets = UIEdgeInsetsMake(0, -imageSize.width, -(imageSize.height + spacing), 0)

    let titleSize = button.titleLabel!.frame.size

    button.imageEdgeInsets = UIEdgeInsetsMake(-(titleSize.height + spacing), 0, 0, -titleSize.width)
}

call this method for each button, like

self.adjustImageAndTitleOffsetsForButton(yourButton)

Solution 2

I've modified Ajay's answer because my images weren't centered:

func centerButtonImageAndTitle(button: UIButton) {
  let spacing: CGFloat = 5
  let titleSize = button.titleLabel!.frame.size
  let imageSize = button.imageView!.frame.size

  button.titleEdgeInsets = UIEdgeInsets(top: 0, left: -imageSize.width, bottom: -(imageSize.height + spacing), right: 0)
  button.imageEdgeInsets = UIEdgeInsets(top: -(titleSize.height + spacing), left: -imageSize.width/2, bottom: 0, right: -titleSize.width)
}

Solution 3

This is a solution that worked for me. Just set the button class to HorizontallyCenteredButton in storyboard and set the title and image top and bottom insets according to your needs (to place the image higher than title) and the button will adjust horizontal insets automatically so that the image is centered above title.

class HorizontallyCenteredButton: LocalizedButton {
    override func awakeFromNib() {
        super.awakeFromNib()
        self.contentHorizontalAlignment = .left
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        self.centerButtonImageAndTitle()
    }

    func centerButtonImageAndTitle() {
        let size = self.bounds.size
        let titleSize = self.titleLabel!.frame.size
        let imageSize = self.imageView!.frame.size

        self.imageEdgeInsets = UIEdgeInsets(top: self.imageEdgeInsets.top, left: size.width/2 - imageSize.width/2, bottom: self.imageEdgeInsets.bottom, right: 0)
        self.titleEdgeInsets = UIEdgeInsets(top: self.titleEdgeInsets.top, left: -imageSize.width + size.width/2 - titleSize.width/2, bottom: self.titleEdgeInsets.bottom, right: 0)
    }
}

Solution 4

Combining Ajay's and Matej's answer:

UIButton with vertically aligned image and text

import Foundation
import UIKit
class VerticalButton: UIButton {
override func awakeFromNib() {
    super.awakeFromNib()
    self.contentHorizontalAlignment = .left
}

override func layoutSubviews() {
    super.layoutSubviews()
    centerButtonImageAndTitle()
}

private func centerButtonImageAndTitle() {
    let titleSize = self.titleLabel?.frame.size ?? .zero
    let imageSize = self.imageView?.frame.size  ?? .zero
    let spacing: CGFloat = 6.0
    self.imageEdgeInsets = UIEdgeInsets(top: -(titleSize.height + spacing),left: 0, bottom: 0, right:  -titleSize.width)
    self.titleEdgeInsets = UIEdgeInsets(top: 0, left: -imageSize.width, bottom: -(imageSize.height + spacing), right: 0)
 }
}
Share:
14,580
user2695433
Author by

user2695433

Updated on August 05, 2022

Comments

  • user2695433
    user2695433 almost 2 years

    I m very new to IOS development and AutoLayout . I am facing issues to align the Image and Text inside UIbutton using Storyboard. I had tried to achieve it with TitleEdgeinset and ImageEdge insets accordingly to place the Title ( text ) vertically centered below the Image. But the issue is I have 3 similar buttons which are Vertically stacked ( StackView) and the Text is dynamically set since we have localized strings ( includes Arabic rtl ) . The image and text moves according to the text length. Is there any ways that I can achieve to make all the buttons with image and text vertically alligned.Also, different screen resolutions are not currently working if using edge insets. Appreciate your help . Thanks in advance.