UITextView
jest podklasą UIScrollView
, więc odpowiedź wiąże właściwość contentOffset
, czyli co się zmieniło, nie wypustki lub rozmiar zawartości. Jeśli pozycja przewijania jest poprawna, gdy najpierw pojawi się widok, możesz zapisać przesunięcie zawartości, aby móc później przywołać.
YourViewController.h snipped
@interface YourViewController : UIViewController <UITextViewDelegate, UIScrollViewDelegate>
@property(nonatomic, weak) IBOutlet UITextView *textView;
@end
YourViewController.m snippet
@implementation YourViewController {
@private
BOOL _freezeScrolling;
CGFloat _lastContentOffsetY;
}
// UITextViewDelegate
- (void)textViewDidBeginEditing:(UITextView *)textView {
// tell the view to hold the scrolling
_freezeScrolling = YES;
_lastContentOffsetY = self.textView.contentOffset.y;
}
// UITextViewDelegate
- (void)textViewDidEndEditing:(UITextView *)textView {
_freezeScrolling = NO;
}
// UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (_freezeScrolling) {
// prevent the scroll view from actually scrolling when we don't want it to
[self repositionScrollView:scrollView newOffset:CGPointMake(scrollView.contentOffset.x, _lastContentOffsetY)];
}
}
// UIScrollViewDelegate
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
// scroll prevention should only be a given scroll event and turned back off afterward
_freezeScrolling = NO;
}
// UIScrollViewDelegate
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
// when the layout is redrawn, scrolling animates. this ensures that we are freeing the view to scroll
_freezeScrolling = NO;
}
/**
This method allows for changing of the content offset for a UIScrollView without triggering the scrollViewDidScroll: delegate method.
*/
- (void)repositionScrollView:(UIScrollView *)scrollView newOffset:(CGPoint)offset {
CGRect scrollBounds = scrollView.bounds;
scrollBounds.origin = offset;
scrollView.bounds = scrollBounds;
}
Co również ważne, aby pamiętać w próbce kodu powyżej jest ostatnia metoda. Wywołanie jakiegokolwiek rodzaju setContentOffset:
spowoduje w rzeczywistości przewijanie, co spowoduje wywołanie scrollViewDidScroll:
. Dlatego wywołanie setContentOffset:
powoduje nieskończoną pętlę. Ustawienie ograniczenia przewijania to obejście tego problemu.
Mówiąc krótko, mówimy kontrolerowi widoku, aby uniemożliwić przewijanie UITextView
po wykryciu, że użytkownik wybrał tekst do edycji. Przechowujemy także bieżące przesunięcie treści (ponieważ wiemy, że pozycja jest tym, czego chcemy). Jeśli UITextView
spróbuje przewinąć, trzymamy przesunięcie zawartości w miejscu do momentu zatrzymania się scroll (które wyzwala albo scrollViewDidEndDecelerating:
lub scrollViewDidEndScrollingAnimation:
). Odmawiamy także przewijanie po zakończeniu edycji przez użytkownika.
Pamiętaj, że jest to podstawowy przykład, więc musisz dostosować kod w oparciu o dokładne zachowanie, które chcesz.
Jakiej wersji SDK używasz? 3.0? – hanleyp
Tak, używam SDK 3.0 – Gero