iosdevuk Building Custom Controls with UIView


#Building Custom Controls with UIView

_Rory Prior_

Buttons can be easily customised.
Some controls can have their colour tint changed (UIToolbar, UINavigationBar)

## UIView

- Defines a rectangular portion of the screen and handles drawing and touch events in that area.
- Acts as a container for other views and can manage their co-ordinates and size.
- Each UIView is backed by a CALayer which can be useful for animation and speeds up drawing performance by caching the view's appearance.

To start building your own controls, subclass UIView.

### Key methods to override

- initWithFrame for programmatically created views
- initWithCoder for views created from Xibx
- drawRect to handleDrawing
- touchesBegan... etc to handle touches

## Coordinates

Top left corner is the origin in UIKit
Bottom left corner is the origin in CoreGraphics
iOS takes care of scaling etc for Retina displays

CGPoint, CGSize, and CGRects are used to

A UIView has both a frame and a bounds

- Frame is with respect to parent view
- Bounds isn't.

## Drawing images

Two ways:

- Add a UIImageView as a subview - but this is 'heavy', less flexible. Less code.
- Draw a UIImage directly - less overhead, maybe faster. More code.

Two ways of drawing a UIImage: drawAtPoint:, drawInRect:. There are 'blend modes' available for artiness.

## Drawing text

- UILabel
- Draw an NSString directly

drawAtPoint:withFont, drawInRect:withFont

sizeWithFont: is useful for working out the size of the rectangle you need. Methods also available to specify text alignment and line break modes.

### Specifying a font

UIFont is used to specify font and size. systemFontOfSize is useful.

## Advanced drawing

Two ways:

- UIBezierPath
- CoreGraphics routines

### UIBezierPath

Draw a path, then stroke and fill. Can build a path piecemeal. Ends can be customised.

The colour of text and UIBezierPath can be set by calling UIColor's `set` method.
There are a bunch of convenience methods - e.g. [UIColor whiteColor]

Everything will be drawn in the `set` colour until you set another.

You can also use a pattern image as a 'colour', but gradient fills are not supported at this time.

### Interface builder

You can draw generic UIView objects onto the canvas and then simply set the class to your custom class.

## Handling user interaction

Three ways:

- Override UIResponder methods to detect touches
- Add UIGestureRecognizers to detect swipes, pinches, etc
- Cheat! Don't reinvent the wheel - if you need a button add a UIButton as a subview

### UIResponder

touchesBegan:withEvent:
touchesMoved:withEvent:
touchesEnded:withEvent:

Best used for simple things, not gestures.

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchedPoint = [touch locationInView:self];
...
}

### UIGestureRecognizer

- Single tap, double tap, rotation, swipe, pan, long presses.

## Interacting with your app

- Use target:action:
- Use the delegate pattern

Delegate acts as a bridge between your view and model while keeping the view as generic as possible.

## Making a delegate

- Define a protocol which defines the methods the delegate needs to implement
- Specify these as @required or @optional
- Make sure you check if [delegate respondsToSelector:]!

## Handling retina display

The OS automatically translates coordinates.

If you include double-sized images with the extension '@2x' in your app bundle, the OS will automatically use those. e.g. Icon@2x.png
Report abuse