I have a UITextView
and I want have two buttons. When the user taps the back button I want the cursor to move back 1 character. When they tap to forward button the cursor should move forward 1 character. How could I do this?
2 Answers
I wrote it out for you, referencing the answer linked below. You can drop the code I wrote into a basic project and try it out.
The solution idea:
You can programmatically select a block of text by specifying the range of text to select (see reference). What's a range, you ask? It's basically a starting position and a length. Since you only care about the cursor position, you can ignore the length (i.e. keep it at zero) and adjust the starting position of the "selection" by +1 or -1.
Reference:
Can I select a specific block of text in a UITextField?
Code Explanation:
In the code below, there are two buttons (Forward and Back) and a target method for each of them that changes the cursor position in the UITextView. Note that tv
is the class variable/property for your UITextView (and needs to be declared as such).
The Code:
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *forward = [UIButton buttonWithType:UIButtonTypeRoundedRect];
forward.frame = CGRectMake(20, 20, 100, 50);
[forward setTitle:@"Forward" forState:UIControlStateNormal];
[forward addTarget:self action:@selector(moveForward:) forControlEvents:UIControlEventTouchUpInside];
UIButton *back = [UIButton buttonWithType:UIButtonTypeRoundedRect];
back.frame = CGRectMake(130, 20, 100, 50);
[back setTitle:@"Back" forState:UIControlStateNormal];
[back addTarget:self action:@selector(moveBack:) forControlEvents:UIControlEventTouchUpInside];
tv = [[UITextView alloc] initWithFrame:CGRectMake(20, 120, 280, 100)];
[self.view addSubview:forward];
[self.view addSubview:back];
[self.view addSubview:tv];
}
-(void)moveForward:(id)sender {
UITextRange *selectedRange = [tv selectedTextRange];
// Calculate the new position, - for left and + for right
if (tv.selectedRange.location < tv.text.length) {
UITextPosition *newPosition = [tv positionFromPosition:selectedRange.start offset:1];
UITextRange *newRange = [tv textRangeFromPosition:newPosition toPosition:newPosition];
// Set new range
[tv setSelectedTextRange:newRange];
}
}
-(void)moveBack:(id)sender {
UITextRange *selectedRange = [tv selectedTextRange];
// Calculate the new position, - for left and + for right
if (tv.selectedRange.location > 0) {
UITextPosition *newPosition = [tv positionFromPosition:selectedRange.start offset:-1];
UITextRange *newRange = [tv textRangeFromPosition:newPosition toPosition:newPosition];
// Set new range
[tv setSelectedTextRange:newRange];
}
}
-
1Eitan, nice comprehensive answer! (+1) – Anne Jun 30 '12 at 19:12
Determine theSelectedRange
range by [theTextView selectedRange];
.
Update the location
property of theSelectedRange
by subtracting or adding the offset.
The length
property is zero in case no selection has been made (an insertion point).
Position the cursor using theTextView.selectedRange = theSelectedRange;
.
Make sure the new range is not out of range for the theTextView
content.

- 26,765
- 9
- 65
- 71