ioscocoa-touchuitextinput

Extra call to setMarkedText:selectedRange in iOS7?


In my app I have UITextInput implemented so I can handle multi stage key input (Japanese, Chinese keyboards) for my custom text view. I'm noticing in iOS7, when you have some text that is marked, and you tap one of the suggestions above the keyboard to replace it, that setMarkedText:selectedRange is called twice: once where it replaces the marked text with the string selected from the panel above the keyboard (as you'd expect), and once where an empty string is sent as the parameter. In iOS6, it's only called once.

My questions are, is there a reason it's doing this? And how should I adjust my setMarkedText:selectedRange to account for this (listed below):

- (void)setMarkedText:(NSString *)markedText selectedRange:(NSRange)selectedRange
{
    NSRange selectedNSRange = self.textView.selectedTextRange;
    NSRange markedTextRange = self.textView.markedTextRange;

    if (markedTextRange.location != NSNotFound)
    {
        if (!markedText)
            markedText = @"";
        [self.text replaceCharactersInRange:markedTextRange withString:markedText];
        markedTextRange.length = markedText.length;
    }
    else if (selectedNSRange.length > 0)
    {
        [self.text replaceCharactersInRange:selectedNSRange withString:markedText];
        markedTextRange.location = selectedNSRange.location;
        markedTextRange.length = markedText.length;
    }
    else
    {
        [self.text insertString:markedText atIndex:selectedNSRange.location];
        markedTextRange.location = selectedNSRange.location;
        markedTextRange.length = markedText.length;
    }

    selectedNSRange = NSMakeRange(selectedRange.location + markedTextRange.location, selectedRange.length);

    self.textView.contentText = self.text;
    self.textView.markedTextRange = markedTextRange;
    self.textView.selectedTextRange = selectedNSRange;
}

My first instinct is to put an if statement around the contents saying

if markedText != @""

but I'm not sure if I'd be messing up some other cases. Does anyone have any suggestions on how to account for this change??


Solution

  • The guy from DTS recommended this solution:

    - (void)setMarkedText:(NSString *)markedText selectedRange:(NSRange)selectedRange 
    {
        ...
    
        if (markedText == nil || markedText.length == 0 ) 
        {
            [self unmarkText];
        }
    }
    

    And it seems to work fine.