3

im using customkeyboard in my controller. but how to get the cursor location in the uitextfiled. my requirement is to enter a charecter in a desired location of textfield. is it possible?

Allen
  • 59
  • 1
  • 2
  • 5
  • possible duplicate of http://stackoverflow.com/questions/1317929/insert-string-at-cursor-position-of-uitextfield – kennytm May 06 '10 at 05:49
  • no im not asking about decimal points. – Allen May 06 '10 at 06:07
  • You may not be asking about decimal points, but you are asking the same question "how to insert text at a specific point in the text field". The question KennyTM linked contains a very good and useful solution. Take a look. – Jasarien Aug 23 '10 at 12:14

3 Answers3

1

Let's assume that you code is in a method on an object where self.textField is the UITextField in question.

You can find the current position of the cursor/selection with:

NSRange range = self.textField.selectedTextRange;

If the user has not selected text the range.length will be 0, indicating that it is just a cursor. Unfortunately this property does not appear to be KVO compliant, so there is no efficient way to be informed when it changes, however this should not be a problem in your case because you probably really only care about it when you are responding to user interaction with your custom keyboard.

You can then use (assuming newText holds the input from your custom keyboard).

[self.textField replaceRange:range withText:newText];

If you need to subsequently adjust the cursor/selection you can use:

self.textField.selectedTextRange = newRange;

For example, you may want to position the cursor after the text you inserted.

UPDATE:

In my original answer I failed to notice that I was leveraging a category I had added to UITextView:

- (void)setSelectedRange:(NSRange)selectedRange
{
    UITextPosition* from = [self positionFromPosition:self.beginningOfDocument offset:selectedRange.location];
    UITextPosition* to = [self positionFromPosition:from offset:selectedRange.length];
    self.selectedTextRange = [self textRangeFromPosition:from toPosition:to];
}

- (NSRange)selectedRange
{
    UITextRange* range = self.selectedTextRange;
    NSInteger location = [self offsetFromPosition:self.beginningOfDocument toPosition:range.start];
    NSInteger length = [self offsetFromPosition:range.start toPosition:range.end];
    NSAssert(location >= 0, @"Location is valid.");
    NSAssert(length >= 0, @"Length is valid.");
    return NSMakeRange(location, length);
}

Then replace use self.textField.selectedRange instead of self.textField.selectedTextRange and proceed as I described.

Thanks to omz for pointing out my error.

Of course, you can work directly with UITextRange but, at least in my case, this proved to be rather ungainly.

idz
  • 12,825
  • 1
  • 29
  • 40
  • `selectedTextRange` is not an `NSRange`, it's a `UITextRange` (which is a class, not a struct). – omz May 06 '13 at 00:05
  • Good catch! I had overlooked a category I was using. I have updated my answer according. – idz May 06 '13 at 05:57
0

The answer is that you can't get the current cursor location for all types of editing that can be done with the textfield. You can insert characters at the cursor with [textField paste], but the user can move the cursor, select and modify text, without a way to get notified where the cursor ended up.

You can temporarily paste a special character and search its position in the string, remove it, and then add the character you want to have there.

Henrik Erlandsson
  • 3,797
  • 5
  • 43
  • 63
  • 1
    As of iOS 5, `UITextField` conforms to the `UITextInput` protocol, so using its `replaceRange:withText:` method in combination with getting the `selectedTextRange` would be a better solution. – omz Jan 30 '13 at 00:21
0

Swift

Get the cursor location:

if let selectedRange = textField.selectedTextRange {
    let cursorPosition = textField.offsetFromPosition(textField.beginningOfDocument, toPosition: selectedRange.start)
}

Enter text at some arbitrary location:

let arbitraryValue: Int = 5
if let newPosition = textField.positionFromPosition(textField.beginningOfDocument, inDirection: UITextLayoutDirection.Right, offset: arbitraryValue) {

    textField.selectedTextRange = textField.textRangeFromPosition(newPosition, toPosition: newPosition)
    textField.insertText("Hello")
}

My full answer is here.

Community
  • 1
  • 1
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393