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:
- Il y a une légère saccades que le texte se déplace vers le haut si l'utilisateur tape particulièrement rapide.
- 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.
- 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
Vous devez vous connecter pour publier un commentaire.
Cool que vous avez trouvé mon post à ce sujet, content que cela a été utile!
Je crois que vous risquez de ne pas voir le bas de ligne à cause de cette ligne:
Vous êtes en train de créer une 1x1 point fort. Une seule ligne de texte peut être quelque chose comme 20 ou 30 points de hauteur (selon la taille de police). Donc, si vous êtes de défilement de ce point de visible, il ne peut être montrant le très haut pixel de la ligne de fond de prise de la ligne de fond effectivement invisible! Si vous faites finalRect un peu plus grandes de sorte qu'il couvre l'ensemble de la ligne, il pourrait fonctionner mieux:
Aussi, vous pouvez appeler votre scrollRectToVisible code plusieurs fois, à la fois, ce qui peut provoquer des "judders". Dans mon code, je n'exécutez scrollRectToVisible de textViewDidChangeSelection, et de redimensionner la UITextView (si nécessaire) dans textViewDidChange. UIScrollView (et, par héritage, UITableView) a un support intégré pour faire défiler les activement élément sélectionné afin d'être visibles, ce qui dans mon test a bien fonctionné lorsque qu'un redimensionnement de la UITextView en cours de frappe (mais pas lors de la sélection d'un point spécifique à l'intérieur avec une touche).
textViewDidBeginEditing
est appelée, pour la scrollToCursor méthode ne fonctionne pas.Toute chance vous pourriez vous poster un exemple de projet avec code de travail? Aussi, si vous voulez continuer à essayer de le corriger vous-même, j'avais envisager de mettre NSLog états dans chaque fonction et de regarder de quel ordre d'incendie, il peut donner un aperçu. Certaines fonctions peuvent ou peuvent ne pas être de tir en fonction de comment vous montrant & cacher le clavier.
Grâce Manesh - comme il arrive j'ai trouvé une solution beaucoup plus simple pour l'ensemble de la chose. Depuis UITextView est une sous-classe de UIScrollView, je peux juste mettre le code dans le
scrollViewDidScroll:
délégué méthode pour déplacer l'image de fond. Je viens donc de mon UITextView défilement normal, et dans l'arrière-plan de déplacement de la vue en réponse à elle. De cette façon, le comportement défilement est parfait, parce que c'est de l'intégré dans le comportement de UITextView. Merci pour toute l'aide!OriginalL'auteur Manesh
Il n'est pas facile de trouver les coordonnées sur l'écran pour n'importe quel texte ou d'un curseur dans un
UITextView
.Ce que vous devez faire est de l'inscription pour
UIKeyboardWillShowNotification
etUIKeyboardWillShowNotification
. Et dans les rappels que vous réglez lasize
oucontentInsets
de laUIScrollView
pour ajuster la taille du clavier.La taille du clavier, et même de l'animation de la durée est prévue dans les notifications
userInfo
, de sorte que vous pouvez le faire dans une belle animation de la mode.Vous trouverez plus d'informations et des exemples de code ici: http://developer.apple.com/library/ios/#documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html
OriginalL'auteur PeyloW
Pas strictement une réponse à votre question, mais ici, c'est une approche différente pour les notes de fond doublé astuce: http://www.cocoanetics.com/2010/03/stuff-you-learn-from-reverse-engineering-notes-app/
Je l'ai déjà utilisé et ça marche bien.
OriginalL'auteur Art Gillespie