You can use insets to arrange the contents of system or custom button
. With inset, you can add or remove spaces to button titleEdgeInsets
( titleEdgeInsets
), images ( imageEdgeInsets
), and both titles and images together ( contentEdgeInsets
).
To see how these three properties work, create a button (UIButton) via the xib file or write in code. It only provides a center
vertically and horizontally in the constraint
of view father. Give contentView
the background color in blue, the imageView
in red background and titleLabel
in yellow. On top of that, you can also give the border of the green button.
1 2 3 4 5 6 | button.backgroundColor = .blue button.imageView?.backgroundColor = .red button.titleLabel?.backgroundColor = .yellow button.layer.borderColor = UIColor.green.cgColor button.layer.borderWidth = 2 |
contentEdgeInsets
is working as you expect. You can add space around both imageView
and titleLabel
using values.
1 2 3 | let spacing: CGFloat = 8.0 button.contentEdgeInsets = UIEdgeInsets(top: 0, left: spacing, bottom: 0, right: spacing) |
The rule when it comes to titleEdgeInsets
or imageEdgeInsets
is adding equal offset to the insets of both left and right. So if you add 8 points
to the inset of the title on the left, you need to add -8 points
to the right. In this way, you only use insets
to offset headlines or images and not resize them in any way. If you do not do this, the calculated layout may become too small and the title may be cut off and the distance will show some strange behavior.
1 2 | button.titleEdgeInsets = UIEdgeInsets(top: 0, left: spacing, bottom: 0, right: 0) |
To change the title and image position, we can use imageEdgeInsets
and titleEdgeInsets
to move imageView
behind titleLabel
. First we move the imageView
with the same number of button widths to the right and then we subtract the width of the image so that the imageView
will be in the content view. It should look like this:
We set the opposite value of the inset
on the left for the inset
on the right:
1 2 3 4 | let buttonWidth = button.frame.width let imageWidth = button.imageView!.frame.width button.imageEdgeInsets = UIEdgeInsets(top: 0, left: buttonWidth-imageWidth, bottom: 0, right: -(buttonWidth-imageWidth)) |
We can then move the titleLabel
to the same width of the imageView
to the left:
1 2 | button.titleEdgeInsets = UIEdgeInsets(top: 0, left: -imageWidth, bottom: 0, right: imageWidth) |
If you want some distance between imageView
and titleLabel
, you need to add half the space to titleLabel
and half the space for imageView
as follows:
1 2 3 4 5 6 | let buttonWidth = button.frame.width let imageWidth = button.imageView!.frame.width let spacing: CGFloat = 8.0 / 2 button.imageEdgeInsets = UIEdgeInsets(top: 0, left: buttonWidth-imageWidth + spacing, bottom: 0, right: -(buttonWidth-imageWidth) - spacing) button.titleEdgeInsets = UIEdgeInsets(top: 0, left: -imageWidth - spacing, bottom: 0, right: imageWidth + spacing) |
But currently titleLabel
and imageView
beyond content view. We can compensate for that with contentEdgeInsets
:
1 2 | button.contentEdgeInsets = UIEdgeInsets(top: 0, left: spacing, bottom: 0, right: spacing) |
But what if we wanted an imageView
with a certain margin from the edge and titleLabel
centered?
We can make the node bigger by giving it a larger distance, for example 128 points. Then we need to move the imageView
the width of the node plus the distance to the right minus one margin that we want the imageView
be on the right edge (16 points in our case). Then we have to compensate for the same distance but the opposite on the right side to keep the imageView
imageView the same size.
When adding an image, the title is pushed to the right with the amount of width of the image. In the example above, the imageView
with the titleLabel
is centered, but for now we just need to center the titleLabel
. To do so, we set the title to the left and right of titleEdgeInset
by half the width of the imageView
. We do it on both sides to keep the title the same size, otherwise you get a truncated title.
1 2 3 4 | button.imageEdgeInsets = UIEdgeInsets(top: 0, left: buttonWidth + spacing — imageWidth — 16, bottom: 0, right: -spacing) button.titleEdgeInsets = UIEdgeInsets(top: 0, left: -imageWidth/2, bottom: 0, right: imageWidth/2) button.contentEdgeInsets = UIEdgeInsets(top: 0, left: spacing, bottom: 0, right: spacing) |
When you set the width limit button, you can set the margin to 0 or remove all margins. The width constraint will expand the content view.
Link: https://medium.com/short-swift-stories/using-uiedgeinsets-to-layout-a-uibutton-44ba04dd085c