سؤال

I have several UITextViews in the lower portion of the screen which when tapped on, bring the keyboard up, however the text views hide under it. I know there is documentation about this in the Apple developer forum, and I have tried that, however that solution only seems to work for UITextFields, NOT UITextViews. I have added a test text field and that DOES scroll up fine using a method from UIScrollView called scrollRectToVisible. For some reason it does not work using textviews.

This is the method which works for UITextField, taken from the Apple guide

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);

    self.scrollView.contentInset = contentInsets;
    self.scrollView.scrollIndicatorInsets = contentInsets;

    // If active text field is hidden by keyboard, scroll it so it's visible
    // Your app might not need or want this behavior.
    CGRect aRect = self.view.frame;
    aRect.size.height -= kbSize.height;

    if (!CGRectContainsPoint(aRect, self.activeTextView.frame.origin) ) {
        [self.scrollView scrollRectToVisible:self.activeTextView.frame animated:YES];
    }
}

Is there a way to make it work the same for UITextView ?

هل كانت مفيدة؟

المحلول 2

After some serious debugging I finally found the culprit... There is actually no reason for scrollRectToVisible to not work with UITextViews, since it take as parameter a CGRect.

I actually had two problems:

  1. I used textView.bounds.origin.y to create the CGRect for the scrolling method, which is not correct. the bounds property returns coordinates relative to the object itself, not the parent view, so I was actually passing a 0 as height, hence no scrolling was done. To use the coordinate relative to the parent view, you must use textview.frame.origin.y.

  2. I had my text view inside a content view which was in turn inside the scrollview, not being the same height as the scrollview. This is a problem since the frame property will give you only values relative to the parent view, so this wasn't the real y for the whole main view. To fix this, use convertRect:toView: and that will make sure to pass the correct y value relative to the view specified to the CGRect in scrollRectToVisible.

After fixing these two issues, text views scrolled smoothly and neatly into place when the keyboard was shown on top of them.

I've seen many people asking about this and no real concise answer has been given. Entire classes and big solutions have been implemented, which are not even necessary.

Anyway, I hope this becomes useful for someone in the future...

نصائح أخرى

Add UITextViewDelegate in .h file

And add below method for push UITextview upside when keyboard will be displayed and set as it is when key board will be hidden.

-(void)textViewDidBeginEditing:(UITextView *)textView
{
    if(textView.tag==0)
    {
        self.view.frame=CGRectMake(0, -100,[UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
    }
    // IF you have multiple UITextview then set different tag for them and access here as per tag
}

-(void)textViewDidEndEditing:(UITextView *)textView
{
    if(textView.tag==0)
    {
        self.view.frame=CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
    }
    // IF you have multiple UITextview then set different tag for them and access here as per tag
}

-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    if([text isEqualToString:@"\n"])
    {
        [textView resignFirstResponder];
        return NO;
    }

    return YES;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top