2009-07-24 8 views
28

Mam UITextView zawarte w UITableViewCell. Układ jest poprawny gdy początkowo wyświetlane są widoki, ale gdy klikam w UITextView automatycznie przewija się trochę, a górna połowa znaków w pierwszej linii staje się niewidoczny.Jak zatrzymać UITextView od przewijanie w górę podczas wprowadzania go

Ten obraz jest gdy UITextView nie jest aktywna:
UITextView not active http://gerodt.homeip.net/uitextview-notactive.png

i ten jest po kliknięciu w UITextView aby ją uaktywnić:
UITextView active http://gerodt.homeip.net/uitextview-active.png

nie zrobić UITextView do przewijania w ogóle powinien być prosty. Jak mogę to osiągnąć? Próbowałem już kilku ustawień w Interface Builder, ale jak dotąd nie miałem szczęścia.

Wszelkie sugestie są mile widziane.

Gero

+0

Jakiej wersji SDK używasz? 3.0? – hanleyp

+0

Tak, używam SDK 3.0 – Gero

Odpowiedz

16

ten sposób UITextView zachowuje się według inżyniera Apple to ma UITextView i jest przeznaczona dla tekstu, który jest co najmniej kilka linii wysokości. Nie ma do tego żadnej pracy, zamiast tego użyj UITextField lub zwiększ UITextView do co najmniej 3 linii wysokości.

+1

Dzięki. Podniosłem wysokość do 55, a dzięki czcionkom o rozmiarze 12 teraz działa tak, jak chcę. – Gero

61

UITextView jest podklasą UIScrollView, a więc ma konfigurowalny własność contentInset. Niestety, jeśli spróbujesz zmienić contentInset na instancji UITextView, dolna krawędź zawsze zostanie zresetowana do 32. Zrobiłem to wcześniej z krótkimi ramkami UITextView i okazało się, że jest to problem. Podejrzewam, że to jest przyczyną problemu, ale powinieneś sprawdzić zawartość zestawu TextView w debugerze, aby mieć pewność.

Rozwiązaniem/rozwiązanie jest proste: podklasa UITextView i zastąpić metodę contentInset tak, że zawsze powraca UIEdgeInsetZero. Wypróbuj to:

// 
// BCTextView 
// 
// UITextView seems to automatically be resetting the contentInset 
// bottom margin to 32.0f, causing strange scroll behavior in our small 
// textView. Maybe there is a setting for this, but it seems like odd behavior. 
// override contentInset to always be zero. 
// 
@interface BCZeroEdgeTextView : UITextView 
@end 

@implementation BCZeroEdgeTextView 

- (UIEdgeInsets) contentInset { return UIEdgeInsetsZero; } 

@end 
+0

Dziękuję, działa doskonale dla mnie. – Ievgen

+1

A ja, właśnie tego szukałem. –

+0

jesteś D człowiekiem !!!! dzięki!!!!!!!!!! – SpaceDog

1

Wystąpił podobny problem z niepożądanym przewijaniem UITextView. I w końcu udało się go naprawić poprzez zresetowanie contentSize na końcu mojego keyboardDidShow:

- (void)keyboardDidShow:(NSNotification *)notification { 
    textView.contentSize = CGSizeZero; 
} 

też będą musiały zarejestrować się na powiadomienia klawiatury, tak jak poniżej:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; 

W moim przypadku nie zrobił” t ma żadnego przewijanie ponieważ został zerowania ramkę wysokości TextView w contentSize gdy textViewDidChange (coraz TextView wewnątrz UIScrollView).

6

Można też po prostu zrobić:

textView.contentInset=UIEdgeInsetsZero; 

w pliku delegata.

+1

Działa świetnie! –

0

spróbuj umieścić w przerysować na TextView zamiast skali do wypełnienia. Wciąż może być konieczne przechwycenie delegata i utrzymanie przesunięcia zawartości, ale powinno to przynajmniej zapobiec przeskokowi do punktu (0,0). Również Autoresizes Wywiad musi być wyłączony. Przeskakiwał on także do góry tekstu za każdym razem na mnie, co rozwiązało ten problem.

enter image description here

2

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.