Providing a consistent UI experience between UITextField and UITextView

There are a few major differences between the two but the most glaring is that UITextView does not support styles so you cannot create them stylistically the same as a UITextField. You cannot readily apply background images depending on state and you cannot apply styles such as UITextBorderStyleRoundedRect. To get around this in the most simple fashion it appears to me that the best method, and one of the simplest, is to create your own UITextView subclass and use that. For this you need a few images in @2x and normal formats containing the background colours you want. In my case I use these, created from a simple PSD that lets me easily alter the background colour:

For the UITextField components I can then apply the setting like so:

	[name setBackground:textfieldEditBG];
	[name setDisabledBackground:textfieldPlainBG];

Having first loaded the images into those variables with methods like:

[[UIImage imageNamed:@"UITextFieldRoundedRectD"]  stretchableImageWithLeftCapWidth:12 topCapHeight:12];

This means that when I just want to view the text it appears unadorned and when I enable it for editing with:

[desc setEnabled:YES]

I get the rounded rect effect. For the UITextView subclass I use a simple hack as my Plain variants are the same as the background of the view in which they are present:

//
//  UIRoundedTextView.h
//  Cooking Companion
//
//  Created by Paul Downs on 10/12/2010.
//  Copyright 2010 The Lost Souls. All rights reserved.
//

#import 


@interface UIRoundedTextView : UITextView {
	UIImage *borderImage;
}

@property (nonatomic, retain) UIImage *borderImage;

- (void)setBorderImage:(UIImage *)background;

@end
//
//  UIRoundedTextView.m
//  Cooking Companion
//
//  Created by Paul Downs on 10/12/2010.
//  Copyright 2010 The Lost Souls. All rights reserved.
//

#import "UIRoundedTextView diovan hct.h"


@implementation UIRoundedTextView

@synthesize borderImage;

- (void)setBorderImage:(UIImage *)background {
	if (borderImage != background) {
		borderImage = nil;
		[borderImage release];
		borderImage = [[background stretchableImageWithLeftCapWidth:12 topCapHeight:12] retain];
		[self setClipsToBounds:NO];
	}
}

- (void)drawRect:(CGRect)rect {
	[super drawRect:rect];
	if (borderImage && [self isEditable]) {
		UIGraphicsGetCurrentContext();
		[borderImage drawInRect:rect];
		UIGraphicsEndImageContext();
	}
}

- (void)dealloc {
	[borderImage release];
	[super dealloc];
}

@end

I can then initialise such a view to display the adorned version in edit mode with:

	[desc setBorderImage:[UIImage imageNamed:@"UITextFieldRoundedRectD"]];
	[desc setClipsToBounds:NO];

Seeing as the drawRect mode has been overridden it does not interfere with the rendering of the text above the image. You could also use a transparent image here if you do not wish to change the background colour away from that of the main view behind it.

It’s important to note that any UITextView components in IB (xib/nib) files will need to have their class set to UIRoundedTextView. If anyone reads this, feel free to use the code above in your own projects.

This entry was posted in Programming and tagged , , , , . Bookmark the permalink.

One Response to Providing a consistent UI experience between UITextField and UITextView

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.