0
votes

I am writing a Custom UITextView, but using the delegate inside the UITextView itself, it no longer can be used else where (ex: in the UIViewController).

So, is there a way to detect when the user changes the range of the selected text in a textview or textfield because I need the caret position. I couldn't find any NSNotification to do something like this :

[[NSNotificationCenter defaultCenter] addObserver:self
     selector:@selector(selectionDidChange:) 
      name: ?? // someNotification
       object:textView];

Then do something with the selector

-(void)selectionDidChange:(NSNotification *)notification {
     //do something
}

I got a hint here, but don't know how to proceed.

Any help is appreciated. Thank you.

2

2 Answers

1
votes

I think you have to made our own protocol for your custom TextField. In your custom textfield, you implement the UItextfieldDelegate protocols and you made your own to prevent the UIVIewController.

in your .h

@protocol YourCustomTextFieldDelegate <NSObject>

  - (void) userDidChangeRange:(NSRange*) currentRange;

@end
@interface YourCustomTextField : UIView <UITextFieldDelegate> {
  UITextField *_customTextField;
} 

@property(nonatomic, weak) id<YourCustomTextFieldDelegate> delegate

in your .m

- (void)viewDidLoad{
   [super viewDidLoad];
  // Do any additional setup after loading the view.
 //Create your customTextField and add it to the view
 _customTextField.delegate = self;

 }

#pragma mark - UItextField Delegate

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:    (NSRange)range replacementString:(NSString *)string
{
  [self.delegate userDidChangeRange:range]; 
  return YES;
}

Edit :With notification post in your .h

  interface YourCustomTextField : UIView <UITextFieldDelegate> {
    UITextField *_customTextField;
  } 

in your .m

 - (void)viewDidLoad{
   [super viewDidLoad];
   // Do any additional setup after loading the view.
   //Create your customTextField and add it to the view
   _customTextField.delegate = self;
}

#pragma mark - UItextField Delegate

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:       (NSRange)range replacementString:(NSString *)string
{
   [[[NSNotificationCenter defaultCenter] postNotificationName:@"YourNotificationName" object:self userInfo:@{@"range": range, @"textFieldTag" : @"[NSNumber numberWithInt:self.tag]}]; 
  return YES;
} 

The user will listen to your notification with

 - (void) viewWillAppear:(BOOL)animated
 {
  [super viewWillAppear:animated];
   [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(rangeDiDChange) name:@"YourNotificationName" object:nil];
}

I suggest that in the notification you set the tag to recognise your textfield, if you have many custom textfield in your view controller, to recognise it.

Hope it will help.

0
votes

UITextViewDelegate has this

-(void)textViewDidChangeSelection:(UITextView *)textView {
    //textView.selectedRange
}

Important, dismissing keyboard (if you have a toolbar with done button for example) will not trigger the selection change method, even though selection has now changed (to 0) so I recommend also calling this method in the end editing method as well, while also manually setting the selected range to nil

-(void)textViewDidEndEditing:(UITextView *)textView {
    textView.selectedRange = NSMakeRange(0, 0);
    [self textViewDidChangeSelection:textView];
}