2

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?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Allison
  • 2,213
  • 4
  • 32
  • 56

2 Answers2

5

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];
    }
}
Community
  • 1
  • 1
Eitan
  • 1,308
  • 3
  • 15
  • 32
1

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.

Anne
  • 26,765
  • 9
  • 65
  • 71