0

While trying to allow multi token deletions, as user holds the backspace key in VENTokenField to act the same as the native email app, or messages app, I have come across many problems...

First, I can only detect one tap on the backspace key from the initial code the VENToken's UITextField subclass offer (which is technically touching private API) - (BOOL)keyboardInputShouldDelete:(UITextField *)textField. That is fine, but not helpful for detecting long press on backspace button, which only works while you actually have characters in a certain UITextField, and not while the UITextField is empty such as in our case.

I have also came across this blogpost which suggest another approach of accessing more of the private API, however, does not offer solution to my problem. As it's not documented, I was wondering if there is a valid way to detect this event at all?

rcat24
  • 548
  • 2
  • 23

1 Answers1

0

I've resolved it by first, comment out anything that was in VENBackspaceTextField class'

keyboardInputShouldDelete:(UITextField *)textField 

Then, added 2 consts in VENTokenField header:

NSString * const kTextEmpty = @"\u200B"; // Zero-Width Space
NSString * const kTextHidden = @"\u200D"; // Zero-Width Joiner

Everytime the token becomes first responder, make sure the textField has the empty text:

- (void)inputTextFieldBecomeFirstResponder {    
   [self.inputTextField becomeFirstResponder];
   if (self.tokens.count) {
      [self.inputTextField setText:kTextEmpty];
   }
   ...
}

And set it to hidden when cursor is not visible:

- (void)setCursorVisibility {
   NSArray *highlightedTokens = [self.tokens filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(VENToken *evaluatedObject, NSDictionary *bindings) {
    return evaluatedObject.highlighted;
   }]];
   BOOL visible = [highlightedTokens count] == 0;
   if (visible) {
      [self inputTextFieldBecomeFirstResponder];
   } else {
      [self.invisibleTextField becomeFirstResponder];
      [self.invisibleTextField setText:kTextHidden];
   }
}

Then, modified the textField Delegate method:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (self.tokens.count && [string isEqualToString:@""] && [textField.text isEqualToString:kTextEmpty]){
    VENToken *lastToken = [self.tokens lastObject];
    lastToken.highlighted = YES;
    [_inputTextField setText:kTextHidden];
    _inputTextField.alpha = 0.0;
    return NO;
}

if ([textField.text isEqualToString:kTextHidden]){
    [self deleteHighlighted];
    [self unhighlightAllTokens];

    return (![string isEqualToString:@""]);
}

//If there are any highlighted tokens, delete
[self deleteHighlighted];
return YES;
}
rcat24
  • 548
  • 2
  • 23