Tuesday, May 3, 2011

Objective C UITextView, select all tweak

Anybody who have used a UITextView in Objective C will know the select all option. For those who didn't understand, I'm talking about the select all option you get when you tap on a UITextView. Today I'm going to show you how to change its behaviour.

First things first :) Did you know that you can programmatically select a range of text? This is how you can do it.

[textView setSelectedRange:NSMakeRange(2, length];

textView - your UITextView object
2 - start position. In this example I have started from the second row
length - length of the text. This should be and integer value

So the above code will select a string of length specified starting from row 2. If you call this method when ever the user taps select all you can specify what select all actually selects. When the user taps on select all the following delegate function of UITextView get called. So the next step would be to implement it in your UITextView delegate class.

- (void)textViewDidChangeSelection:(UITextView *)textView{
[textView setSelectedRange:NSMakeRange(2, length];

But now the problem is when the user taps on select the same function will get called. So how do we know that he tapped select all. We can check this by checking whether his action (select/select all) has indeed selected an area which we don't want to be selectable. The following check whether the user's selection include the first two rows and makes a custom selection.

- (void)textViewDidChangeSelection:(OLTextView *)textView{
if ([textView selectedRange].location < 3) {
[textView setSelectedRange:NSMakeRange(2, length)];

Since we want the custom selection for the select all only we have to make the first two rows non-selectable via the select option. Since select option works only for editable text area we can make the first two rows non editable. The following code will make the first two rows non-editable.

- (BOOL)textView:(OLTextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
if (range.location < 3) {
return FALSE;
return YES;

No comments: