Comment puis-je faire un UIScrollView faites défiler jusqu'à un UITextView de la position du curseur?

J'ai un point de vue qui est similaire à l'application de notes - c'est à dire en tapant sur un doublé morceau de papier. Pour rendre le texte et le rouleau de papier simultanément, j'ai désactivé le UITextView de défilement, et au lieu placé mes deux UITextView et mon UIImageView à l'intérieur d'un UIScrollView.

Le seul problème avec ceci est que, lorsque l'utilisateur tape, le texte disparaît sous le clavier, parce que évidemment le UIScrollView ne sais pas pour défiler jusqu'à la position du curseur.

Est-il un simple moyen pour que je puisse récupérer la position du curseur et de dire la UIScrollView pour faire défiler?

---EDIT---

À partir de quelque chose de similaire ici (où quelqu'un essaie de faire quelque chose de similaire avec un UITableView), j'ai réussi à faire de plus en plus, modifiable UITextView avec un arrière-plan fixe qui presque défile à la perfection. Les seuls problèmes sont maintenant:

  1. Il y a une légère saccades que le texte se déplace vers le haut si l'utilisateur tape particulièrement rapide.
  2. Si l'utilisateur se cache le clavier, sélectionne le texte au bas de l'écran, puis affiche de nouveau le clavier, ils ont à taper quelques lettres avant que le texte ne devient visible encore une fois - il n'a pas faites défiler vers le haut immédiatement.
  3. Lorsque l'utilisateur se cache le clavier, l'animation comme le défilement de l'affichage de l'image remplit l'écran ne se sent pas tout à fait raison en quelque sorte.

Voici le code, je serais vraiment reconnaissant si quelqu'un peut affiner encore...

#import "NoteEditViewController.h"
#import "RLWideLabelTableCell.h"
@implementation NoteEditViewController
@synthesize keyboardSize;
@synthesize keyboardHideDuration;
@synthesize scrollView;
@synthesize noteTextView;
//
//Dealloc and all that stuff
//
- (void)loadView
{
[super loadView];
UIScrollView *aScrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
self.scrollView = aScrollView; [aScrollView release];
self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width, noteTextView.frame.size.height);
[self.view addSubview:scrollView];
}
- (void)viewDidLoad
{   
[super viewDidLoad];
//Get notified when keyboard is shown. Don't need notification when hidden because we are
//using textViewDidEndEditing so we can start animating before the keyboard disappears.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
//Add the Done button so we can test dismissal of the keyboard    
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone 
target:self
action:@selector(doneButton:)];
self.navigationItem.rightBarButtonItem = doneButton; [doneButton release];
//Add the background image that will scroll with the text
CGRect noteImageFrame = CGRectMake(self.view.bounds.origin.x, 
noteTitleImageFrame.size.height, 
self.view.bounds.size.width, 500);    
UIView *backgroundPattern = [[UIView alloc] initWithFrame:noteImageFrame];
backgroundPattern.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"Notepaper-iPhone-Line"]];
[self.scrollView addSubview:backgroundPattern];
[self.view sendSubviewToBack:backgroundPattern];
[backgroundPattern release];
//Add the textView
CGRect textViewFrame = CGRectMake(noteImageFrame.origin.x+27, 
noteImageFrame.origin.y-3, 
noteImageFrame.size.width-35,
noteImageFrame.size.height);
RLTextView *textView = [[RLTextView alloc] initWithFrame:textViewFrame];
self.noteTextView = textView; [textView release];
self.noteTextView.font = [UIFont fontWithName:@"Cochin" size:21];
self.noteTextView.backgroundColor = [UIColor clearColor];
self.noteTextView.delegate = self;
self.noteTextView.scrollEnabled = NO;
[self.scrollView addSubview:self.noteTextView];
}
- (void)doneButton:(id)sender
{
[self.view endEditing:TRUE];
}
//When the keyboard is shown, the UIScrollView's frame shrinks so that it fits in the
//remaining space
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
float kbHideDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
self.keyboardHideDuration = kbHideDuration;
self.keyboardSize = kbSize;
self.scrollView.frame = CGRectMake(self.view.bounds.origin.x, 
self.view.bounds.origin.y, 
self.view.bounds.size.width, 
self.view.bounds.size.height - kbSize.height);    
}
//When the user presses 'done' the UIScrollView expands to the size of its superview
//again, as the keyboard disappears.
- (void)textViewDidEndEditing:(UITextView *)textView
{
[UIScrollView animateWithDuration:keyboardHideDuration animations:^{self.scrollView.frame = self.view.bounds;}];
}
//This method needs to get called whenever there is a change of cursor position in the text box
//That means both textViewDidChange: and textViewDidChangeSelection:
- (void)scrollToCursor
{
//if there is a selection cursor…
if(noteTextView.selectedRange.location != NSNotFound) {
NSLog(@"selectedRange: %d %d", noteTextView.selectedRange.location, noteTextView.selectedRange.length);
//work out how big the text view would be if the text only went up to the cursor
NSRange range;
range.location = noteTextView.selectedRange.location;
range.length = noteTextView.text.length - range.location;
NSString *string = [noteTextView.text stringByReplacingCharactersInRange:range withString:@""];
CGSize size = [string sizeWithFont:noteTextView.font constrainedToSize:noteTextView.bounds.size lineBreakMode:UILineBreakModeWordWrap];
//work out where that position would be relative to the textView's frame
CGRect viewRect = noteTextView.frame;  
int scrollHeight = viewRect.origin.y + size.height;
CGRect finalRect = CGRectMake(1, scrollHeight, 1, 1);
//scroll to it
[self.scrollView scrollRectToVisible:finalRect animated:YES];
}
}
//Whenever the text changes, the textView's size is updated (so it grows as more text
//is added), and it also scrolls to the cursor.
- (void)textViewDidChange:(UITextView *)textView
{
noteTextView.frame = CGRectMake(noteTextView.frame.origin.x, 
noteTextView.frame.origin.y, 
noteTextView.frame.size.width, 
noteTextView.contentSize.height);
self.scrollView.contentSize = CGSizeMake(self.scrollView.contentSize.width, 
noteTextView.frame.size.height+200);
[self scrollToCursor];
}
//The textView scrolls to the cursor whenever the user changes the selection point.
- (void)textViewDidChangeSelection:(UITextView *)aTextView 
{
[self scrollToCursor];
}
//PROBLEM - the textView does not scroll until the user starts typing - just selecting
//it is not enough. 
- (void)textViewDidBeginEditing:(UITextView *)textView
{
[self scrollToCursor];
}

OriginalL'auteur Ric Levy | 2011-05-11