UITextView delegate methods

28,175

Solution 1

this method is missing from your Test2ViewController.m file:

- (void)viewDidLoad {
    [myTextView setDelegate:self];
}

or you can connect the delegate in the Interface Builder as well, if you prefer that way better.

UPDATE #1:

add this method to you class for controlling the return key.

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    if ([text isEqualToString:@"\n"]) {
        NSLog(@"Return pressed, do whatever you like here");
        return NO; // or true, whetever you's like
    }

    return YES;
}

Solution 2

Connect the delegate of the TextView in Interface Builder to the parent class. I like to use the connection in IB rather than code it. To me the less code to look at the better :). Also - don't compare strings that way. Use isEqualToString for string comparison:

if ([myTextView.text isEqualToString:@"TEXT"]) {
        [myTextView setText:@""];
}

Connection Pic

Here is the fixed project:

Solution 3

I think I have a good solution in principle:

Set the UITextView's delegate to self and then make your own delegate - re-using the same name. This allows you to intercept the delegate without anything looking different from the outside

@interface TTGTextView : UITextView<UITextViewDelegate>// UIPlaceHolderTextView
@property(nonatomic, assign) id<UITextViewDelegate> delegate;
@synthesize delegate = realDelegate;

Then go ahead and intercept the methods. Note that you need to cover all of them, otherwise they won't react the "real" delegate

-(void)textViewDidBeginEditing:(UITextView *)textView
{
  if ([realDelegate respondsToSelector:@selector(textViewDidBeginEditing:)])
    [realDelegate textViewDidBeginEditing:textView];
  /*YOUR CODE HERE*/
}
-(void)textViewDidChange:(UITextView *)textView
{
  if ([realDelegate respondsToSelector:@selector(textViewDidChange:)])
    [realDelegate textViewDidChange:textView];
  /*YOUR CODE HERE*/
}
-(void)textViewDidChangeSelection:(UITextView *)textView
{
  if ([realDelegate respondsToSelector:@selector(textViewDidChangeSelection:)])
    [realDelegate textViewDidChangeSelection:textView];
  /*YOUR CODE HERE*/
}
-(void)textViewDidEndEditing:(UITextView *)textView
{
  if ([realDelegate respondsToSelector:@selector(textViewDidEndEditing:)])
    [realDelegate textViewDidEndEditing:textView];
  /*YOUR CODE HERE*/
}

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
  if ([realDelegate respondsToSelector:@selector(textView:shouldChangeTextInRange:replacementText:)])
    return [realDelegate textView:self shouldChangeTextInRange:range replacementText:text];
  return YES;
}
-(BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange
{
  if ([realDelegate respondsToSelector:@selector(textView:shouldInteractWithTextAttachment:inRange:)])
    return [realDelegate textView:self shouldInteractWithURL:URL inRange:characterRange];
  return YES;
}
- (BOOL)textView:(UITextView *)textView shouldInteractWithTextAttachment:(NSTextAttachment *)textAttachment inRange:(NSRange)range
{
  if ([realDelegate respondsToSelector:@selector(textView:shouldInteractWithTextAttachment:inRange:)])
    return [realDelegate textView:textView shouldInteractWithTextAttachment:textAttachment inRange:range];
  return YES;
}

Some of the methods fire correctly, others don't fire for me at all but immediately appear for the "real" delegate. But this is a starting point. I guess a more solid and general way would be to make some kind of multiplexer - make it a UITableViewDelegate which holds an array of delegates to fire to.

Solution 4

Your UITextview needs to be told where its delegate methods lies...

If you add it via interface builder then simply connect the delegates

or if via code

[yourTextViewOutlet setDelegate:self];

Solution 5

Deponds on your View. if you use TextField, you should be used UITextFieldDelegate in .header file as a delegate just like show below.

@interface ExamPageViewController : UIViewController <UITextFieldDelegate>

and than we can be used UITextFieldDelegate methods. You can see;

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [self.questionAnswerTextField resignFirstResponder];
    return YES;
}

-(void)textFieldDidBeginEditing:(UITextField *)textField {

    if ([textField.text isEqualToString:@"Sorunun cevabını buraya yazınız!"]) {
        textField.text = @"";
    }
}


- (void)textFieldDidEndEditing:(UITextField *)textField {
    if ([textField.text isEqualToString:@""]) {
        textField.text = @"Sorunun cevabını buraya yazınız!";
    }
}

Otherwise you should be used UITextViewDelegate as a delegate like below code snippet.

@interface ExamPageViewController : UIViewController <UITextViewDelegate>

and than we can be used these delegate methods in .m file

- (BOOL)textViewShouldReturn:(UITextView *)textField {
    [self.questionAnswerTextField resignFirstResponder];
    return YES;
}

-(void)textViewDidBeginEditing:(UITextView *)textField {

    if ([textField.text isEqualToString:@"Sorunun cevabını buraya yazınız!"]) {
        textField.text = @"";
    }
}


- (void)textViewDidEndEditing:(UITextView *)textField {
    if ([textField.text isEqualToString:@""]) {
        textField.text = @"Sorunun cevabını buraya yazınız!";
    }
}
Share:
28,175
Mr Ordinary
Author by

Mr Ordinary

I am learning for pleasure and profit.

Updated on January 08, 2020

Comments

  • Mr Ordinary
    Mr Ordinary over 4 years

    I am trying to get delegate methods to work with UITextView, but it's not working for some reason.

    I have declared in my viewController.h that it is a UITextViewDelegate

    I am trying to get the following code to work to erase the default code "TEXT" when I tap on the textView.

    - (void)textViewDidBeginEditing:(UITextView *)textView {
    
        if (myTextView.text == @"TEXT") {
            [myTextView setText:@""];
        }
    
        NSLog(@"did begin editing");
    }
    

    I expected to the text to be cleared and to see the NSLog print when I tap on the textView and the keyboard appears. Nothing at all happens


    Using a text view by the way because I need to scale the view based on its content size and seems that the textView has a contentSize property, whit label and textField do not.

    UPDATE:

    I should have used:

    if ([myTextView.text isEqualToString:@"TEXT"]) {
        [myTextView setText:@""]; }
    

    here is the project if you want to take a look.

    • LJ Wilson
      LJ Wilson almost 12 years
      Also, I updated my answer to correct your string comparison and changed the project. Download the updated project.
  • Mr Ordinary
    Mr Ordinary almost 12 years
    Thanks that worked! One more question. Is it possible to have the return key make the textView resign first responder. There is no method as I can see.