Hi there! I hope to summarize here the key elements in creating custom designs on iOS as a quick reference that will be useful to you.
General Views and Layers
With UIView
being a thin wrapper over CALayer
, many of techniques applying to layers also work with views.
Rounded Corners
Set the properties cornerRadius
and masksToBounds
on CALayer
to get quick rounded corners.
view.layer.cornerRadius = 4
view.layer.masksToBounds = true
We need to set
masksToBounds
totrue
to allow clipping. Rounded corners also work with borders below.
Borders
Use the properties borderWidth
and borderColor
to create quick borders on a CALayer
. The borders are drawn inside the bounds.
view.layer.borderWidth = 2
view.layer.borderColor = UIColor.redColor().CGColor
We set a
CGColor
, notUIColor
, on theborderColor
property. Borders work with rounded corners above.
Shadows
The shadowRadius
property determines the amount of blur the shadow gets while the shadowOpacity
property affects how visible the shadow is. We're actually setting the properties on CALayer
so if you're working with layers they work too.
view.layer.shadowRadius = 4
view.layer.shadowOpacity = 0.5
Shadows do not work when clipping is enabled using
masksToBounds
and hence you can't use this with rounded corners. A good workaround is to wrap your view in a container view and apply the rounded corners to the subview and shadows to the parent.
You can also change the color of the shadow using the shadowColor
property.
view.layer.shadowColor = UIColor.redColor().CGColor
Shadows also have a slight inset by default that makes them appear higher than the view. You can tweak or remove that effect using shadowOffset
.
view.layer.shadowOffset = CGSizeZero
Background and Opacity
Use the backgroundColor
and alpha
properties on UIView
or the corresponding backgroundColor
and opacity
properties on CALayer
to set the background and transparency of a view.
view.backgroundColor = UIColor.redColor()
view.alpha = 0.5
The
alpha
oropacity
property takes a value from0
(invisible) to1
(fully visible). OnCALayer
,backgroundColor
takes aCGColor
.
Position
A view's position is specified in 3 properties, center
, bounds
and transform
. The frame
property is a shorthand for setting/retrieving all 3 at once.
center
- Determines the origin in the superview's coordinate space. You can use the anchorPoint
property on CALayer
to change how this is rendered (see below).
bounds
- Determines the visible region (and size) of a view in its own coordinate space. Typically, the bounds starts at an origin of CGPointZero
or (0,0) but some cases, like in UIScrollView
, it also determines the visible region of the view.
transform
- Determines the transformation of a view. This takes a value of type CGAffineTransform
, which you create using the Core Graphics functions prefixed with CGAffineTransform
. The default value is CGAffineTransformIdentity
which resets the transform of the view/layer.
- Scale; You can set the factor to scale (stretch) in both the horizontal and vertical directions. The value
1
is the default size.
view.transform = CGAffineTransformMakeScale(0.5, 0.5)
- Rotation; You specify the angle to rotate the view. Typically, you would pass in factor of the constant
M_PI
which is the value of mathematical constant Pi in radius (180 degrees.) You can also use the constantsM_PI_2
(Pi divided by 2, 90 degrees) andM_PI_4
(Pi over 4.)
view.transform = CGAffineTransformMakeRotation(CGFloat(30.0 / 180.0 * M_PI))
- Translation; You can specify a distance (both horizontally and veritically) to move your view without changing its
center
/frame
.
view.transform = CGAffineTransformMakeTranslation(100, 50)
What's interesting is that you can mix and match the order of the above transforms to create more complex effects. We used the functions prefixed with CGAffineTransformMake
above but you can use those without the Make
prefix to combine transformations.
let transform = CGAffineTransformMakeScale(0.5, 0.5)
view.transform = CGAffineTransformTranslate(transform, 100, 50)
The order you apply the transformations matter. The
Make
functions are simply applying transformations toCGAffineTransformIdentity
.
Anchor Point
The layer's anchor point, takes a value between 0
and 1
for both the horizontal and vertical direction in a CGPoint
. This determines how far into the layer we will consider the origin (or center
in a UIView
or position
in CALayer
) to be.
The following example puts the origin on the right of the view but vertically centered.
view.layer.anchorPoint = CGPoint(x: 1, y: 0.5)
The anchor point is critical when dealing with rotation transforms and decides where to rotate the view about.
Image Views
Positioning and Cropping
While contentMode
is a general UIView
property, the effect is most pronounced in UIImageView
. When your image view's size is different from the size of the UIImage
it is displaying, use this to get the right presentation.
imageView.contentMode = .ScaleAspectFill
Here's some of the more interesting options:
.ScaleToFill
- The default behavior; stretches your image to fit the image view (this may distort your image).ScaleAspectFit
- Resizes your image proportionally so the entire image fits within the bounds of the image view.ScaleAspectFill
- Resizes your image proportionally so the entire bounds of the image view is filled with your image..Center
,.Top
,.Bottom
,.Left
,.Right
, other combinations of directions - Positions your image so that the said edge/position of the image view and image are aligned.
Use this in conjugation with
clipsToBounds
set totrue
for a nice cropping effect.
Scroll Views
Scroll views are everywhere and the following techniques also apply to subclasses like UITableView
and UICollectionView
.
Padding
Use the contentInset
property to add space around the content. You also use this property to move content above the keyboard when typing.
tableView.contentInset = UIEdgeInsets(top: 100, left: 0, bottom: 0, right: 0)
You should also use the corresponding scrollIndicatorInsets
to inset the scroll bars.
Scroll Position
Set contentOffset
or setContentOffset(animated)
to change the visible region of your scroll view.
tableView.contentOffset = CGPoint(x: 0, y: 100)
If you're working with
UIScrollView
directly, you also need to setcontentSize
to tell the scroll view how wide and tall it should be before scrolling will work.
By default if the contentSize
is smaller than the scroll view's bounds
, scrolling is disabled. If you want the scroll view to scroll before bouncing back, set alwaysBounceVertical
and alwaysBounceHorizontal
to true
.