77

I'm looking for a way to add a padding property to an UIView. Ideally, I would like to avoid subclassing and putting it in a category. The usage would be something like:

myview.padding = UIEdgeInsetsMake(10, 10, 10, 10);

And maybe have a paddingBox property as well which would return a CGRect describing the size and position of the inner padding box.

Now, how would one implement in a category something like that. I initially though of using bounds, but unfortunately the size of the bounds is linked to the size of the frame (always the same) only the coordinates can differ.

Daniyar
  • 2,975
  • 2
  • 26
  • 39
Meda
  • 2,776
  • 4
  • 20
  • 31
  • If you are thinking of `padding` in the Android sense – a space in which the view background is drawn but not its content – I think iOS just does not have that concept built in to its views. Strange, right? – androidguy Jun 04 '20 at 22:12

7 Answers7

58

This is generally done by setting the bounds within the view. So if you wanted an inset of 10 all round you could do:

view.bounds = CGRectInset(view.frame, 10.0f, 10.0f);

The bounds defines the drawable area of the view, relative to the frame. So this should give in effect a padding. You can then get the 'paddingBox' just from the bounds.

Hope this helps! :)

Update in Swift 5+, It's

view.bounds = view.frame.insetBy(dx: 10.0, dy: 10.0);
mahen3d
  • 7,047
  • 13
  • 51
  • 103
George Green
  • 4,807
  • 5
  • 31
  • 45
  • 6
    This changes the size of the view as well, unfortunately. As I mentioned in my question, the docs state that `The size of the bounds rectangle is coupled to the size of the frame rectangle, so that changes to one affect the other.`. In other terms, the code you posted should have a -10 not 10 and even so, it will add only top and left padding, but I'll test again, just to be sure I'm not missing something. – Meda Feb 13 '13 at 15:51
  • Do you have a link to the docs, as I'm pretty sure that the size of the bounds and frame can differ? – George Green Feb 13 '13 at 18:03
  • 1
    http://stackoverflow.com/questions/749558/why-is-there-an-frame-rectangle-and-an-bounds-rectangle-in-an-uiview and http://stackoverflow.com/questions/1071112/uiviews-frame-bounds-center-origin-when-to-use-what are good info on this. – George Green Feb 13 '13 at 18:03
  • Hmmm, just found it in the docs, am just doing an experiment to confirm. I would now like to apologise, as that is in fact the case. Looks like you may have to go for a simple subclass. – George Green Feb 13 '13 at 18:08
  • 3
    ```self.contentTextView.bounds = self.contentTextView.frame.insetBy(dx: 10, dy: 10)``` (***Swift 5+*** ) – eildiz Feb 07 '20 at 11:17
40

Update for Swift 3

view.bounds = view.frame.insetBy(dx: 10.0, dy: 10.0)

:)

Alien
  • 3,658
  • 1
  • 16
  • 33
40

Update: Since iOS11 you should use directionalLayoutMargins instead of layoutMargins.

Source: https://developer.apple.com/documentation/uikit/uiview/1622566-layoutmargins?language=objc

Since iOS 8, each view has now a layoutMargins property which corresponds to the padding.

myview.layoutMargins = UIEdgeInsetsMake(10, 10, 10, 10);

When you use AutoLayout, a format with |-[subview]-|, |- will refer to the edges defined with layoutMargins.

Source: https://developer.apple.com/reference/uikit/uiview/1622566-layoutmargins?language=objc

yageek
  • 4,115
  • 3
  • 30
  • 48
15

You can override the alignmentRectInsets property. Here is an example in Swift 4

class YourCustomView: UIView {

    override var alignmentRectInsets: UIEdgeInsets {
        return UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
    }
}
Omar Albeik
  • 1,332
  • 13
  • 17
11

What you really have to do is create a view and add a subview to it. Make one view the background and give it the frame you want. Then make the second subview the frame you want with the edge insets.

UIView backgroundView = new UIView(CGRect.FromLTRB(0, 0, 100, 100))
{
    BackgroundColor = backgroundGray,
};

//Will have a right edge inset of 10
UIView edgyView = new UIView(CGRect.FromLTRB(0, 0, 90, 100))
{
    BackgroundColor = backgroundGray,
}

backgroundView.AddSubview(edgyView);
Gandalf458
  • 2,139
  • 1
  • 21
  • 36
7

Update for Swift 4:

self.yourView.layoutMargins = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
Boomerange
  • 616
  • 1
  • 10
  • 18
2

You can inset the view's frame/bounds like this:

    yourView.frame = yourView.frame.inset(by: UIEdgeInsets(top: .zero, left: 5.0, bottom: 5.0, right: .zero)
Radu Ciobanu
  • 710
  • 8
  • 10