Как остановить прокрутку UITextView при входе в нее
У меня есть UITextView
, включенный в UITableViewCell
. Макет правилен, когда представления изначально отображаются, но как только я нажимаю кнопку UITextView
, он автоматически прокручивается немного, а верхняя половина символов на первой строке становится невидимой.
Это изображение, когда UITextView
неактивно:
UITextView неактивен http://gerodt.homeip.net/uitextview-notactive.png
И это когда я нажал кнопку UITextView
, чтобы сделать его активным:
UITextView active http://gerodt.homeip.net/uitextview-active.png
Я не UITextView для прокрутки вообще, он должен оставаться неподвижным. Как я могу это достичь? Я уже пробовал несколько настроек в Interface Builder
, но пока не повезло.
Любые предложения приветствуются.
Геро
Ответы
Ответ 1
Вот как UITextView ведет себя в соответствии с инженером Apple, это предназначено, а UITextView предназначен для текста, который имеет по крайней мере несколько строк в высоту. Для этого нет никакой работы, используйте UITextField или увеличивайте UITextView до высоты не менее 3 строк.
Ответ 2
UITextView является подклассом UIScrollView, поэтому он имеет настраиваемое свойство contentInset. К сожалению, если вы попытаетесь изменить contentInset в экземпляре UITextView, то в нижней части вставки всегда будет reset до 32. Я столкнулся с этим раньше с короткими кадрами UITextView и обнаружил, что это проблема. Я подозреваю, что это то, что вызывает вашу проблему, но вы должны убедиться в правильности содержимого вашего текста в отладчике.
Обходной путь/решение прост: подкласс UITextView и переопределить метод contentInset, чтобы он всегда возвращал UIEdgeInsetZero. Попробуйте следующее:
//
// 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
Ответ 3
Вы также можете просто сделать:
textView.contentInset=UIEdgeInsetsZero;
в файле делегата.
Ответ 4
UITextView
является подклассом UIScrollView
, поэтому ответ включает свойство contentOffset
, которое является тем, что изменяется, а не вставки или размер содержимого. Если позиция прокрутки верна, когда сначала открывается представление, вы можете сохранить смещение содержимого для последующего вызова.
YourViewController.h отключен
@interface YourViewController : UIViewController <UITextViewDelegate, UIScrollViewDelegate>
@property(nonatomic, weak) IBOutlet UITextView *textView;
@end
Снимок тэга ViewViewController.m
@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;
}
Что также важно отметить в примере кода выше, это последний метод. Вызов любого типа setContentOffset:
фактически вызовет прокрутку, что приведет к вызову scrollViewDidScroll:
. Поэтому вызов setContentOffset:
приводит к бесконечному циклу. Установка границ прокрутки является обходным способом для этого.
Вкратце, мы говорим контроллеру вида, чтобы предотвратить прокрутку UITextView
, когда мы обнаруживаем, что пользователь выбрал текст для редактирования. Мы также сохраняем текущее смещение содержимого (поскольку мы знаем, что позиция - это то, что мы хотим). Если UITextView
пытается выполнить прокрутку, мы удерживаем смещение содержимого на месте до тех пор, пока прокрутка не остановится (что вызывает либо scrollViewDidEndDecelerating:
, либо scrollViewDidEndScrollingAnimation:
). Мы также размораживаем прокрутку, когда пользователь редактирует.
Помните, что это базовый пример, поэтому вам нужно настроить код на основе точного поведения, которое вы хотите.
Ответ 5
У меня возникла аналогичная проблема с нежелательной прокруткой UITextView
. Я, наконец, сумел исправить это, сбросив содержимое contentize в конце моего keyboardDidShow:
- (void)keyboardDidShow:(NSNotification *)notification {
textView.contentSize = CGSizeZero;
}
Вам также потребуется зарегистрироваться для уведомления клавиатуры, например:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
В моем случае мне не нужна прокрутка, так как я сбросил фрейм на высоту textView contentSize
, когда textViewDidChange
(растущий текст внутри UIScrollView
).
Ответ 6
Попробуйте помещать Redraw в текстовое окно вместо Scale to Fill. Возможно, вам придется захватить делегат и сохранить смещение содержимого, но он должен по крайней мере предотвратить прыжок в точку (0,0). Также Autoresizes subview должен быть отключен. Он тоже каждый раз перескакивал на верх над текстом, и это решило эту проблему.
![enter image description here]()