Joris Kluivers

I like to build software.

Subclass UIAlertView to Customize the Look of an Alert

Update: I’ve posted about a better way to create custom alerts.

The iPhone SDK provides the class UIAlertView to display alerts to the user. These alerts are used by Apple for incoming text messages for example. Application developers can use the same notification style to display any custom notification. An alert appears in a special window level on top of all other content. User input to the underlying content is ignored until the alert is dismissed.

In one of my recent projects a view had to be displayed on top of all other content. While some features like the spotlight dim effect and blocking of user input could be reused, in this case the blue UIAlertView style did not fit my needs. Instead of creating my own view from scratch I decided to reuse what UIAlertView had to offer and strip out all unnecessary features.

This page will explain what is needed to create a custom alert like the blood spatter displayed below.

While we could transform the alert into anything we want, I’ve chosen to keep it simple. Our blood spatter alert consists of two main parts: a background image and a text label. As you can see in the comparison above we will ignore any buttons and the default text. A new initialization method will be used to provide our JKCustomAlert with the information needed.

1
- (id) initWithImage:(UIImage *)backgroundImage text:(NSString *)text;

By using our own initializer the default title and message are not set. If you show the alert at this point it will be empty and small but still using the default appearance.

To change the appearance from the default to our own background image drawRect: needs to be overridden. We do not call the super drawRect method to prevent UIAlertView from drawing the default appearance. All we do is draw our background image.

1
2
3
4
5
6
- (void) drawRect:(CGRect)rect {
    // do not call the super drawRect

    CGSize imageSize = self.backgroundImage.size;
    [self.backgroundImage drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
}

The last thing to do is to size our JKCustomAlert to fit our background image. The show method is responsible for resizing and animating the alert. We first call the super method to start the animation and override the view size right after that by setting the bounds to the size of the image.

1
2
3
4
5
6
7
8
- (void) show {
    // call the super show method to initiate the animation
    [super show];

    // resize the alert view to fit the image
    CGSize imageSize = self.backgroundImage.size;
    self.bounds = CGRectMake(0, 0, imageSize.width, imageSize.height);
}

The text label is added to our subview using addSubview: to be displayed. Positioning of the text label is done in the layoutSubviews selector. This is all normal procedure and shouldn’t be that hard.

Remember that because we do not provide the user with a button the application will have to dismiss the alert manually using the dismissWithClickedButtonIndex:animated: selector otherwise the app will be stuck while displaying our alert.

Of course a custom alert like shown above can also used to create an alternative to the private class UIProgressHUD (used by Apple).

Sample Project

Download CustomAlert.zip (23kb)