Я столкнулся с аналогичной проблемой, в том числе с частью «Если я установил анимированный на NO, все работает как положено».
Оказалось, что на iOS 6 UITextView автоматически прокручивает свой ближайший родительский UIScrollView, чтобы сделатькурсор становится видимым, когда он становится первым респондентом.На iOS 7 такого поведения нет.UIScrollView кажется сбитым с толку двумя вызовами scrollRectToVisible примерно в одно и то же время.
В iOS 6 мой явный вызов scrollRectToVisible игнорируется большую часть времени .Он будет прокручиваться только для того, чтобы сделать видимой первую строку UITextView (автоматическая прокрутка), а не для всей цели, как в iOS 7.
Чтобы проверить это, создайте новое приложение с одним представлением в Xcode 5установите его цель развертывания на 6.0 и используйте код ниже для ViewController.m.Запустите его в симуляторе iOS 6.1, прокрутите, чтобы скрыть UITextView, и коснитесь любого места на экране.Возможно, вам придется повторить попытку несколько раз, но в большинстве случаев будет видна только первая строка.Если вы снова включите WORKAROUD, определите, что UITextView будет встроен в его собственный UIScrollView, и вызов scrollRectToVisible будет работать как положено.
#import "ViewController.h"
//#define WORKAROUND
@interface ViewController ()
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UITextView *textView;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewTap)]];
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 240)];
self.scrollView.contentSize = CGSizeMake(320, 400);
self.scrollView.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:self.scrollView];
#ifdef WORKAROUND
UIScrollView* dummyScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(20, 280, 280, 100)];
self.textView = [[UITextView alloc] initWithFrame:dummyScrollView.bounds];
[dummyScrollView addSubview:self.textView];
[self.scrollView addSubview:dummyScrollView];
#else
self.textView = [[UITextView alloc] initWithFrame:CGRectMake(20, 280, 280, 100)];
[self.scrollView addSubview:self.textView];
#endif
self.textView.backgroundColor = [UIColor grayColor];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)viewTap
{
if (self.textView.isFirstResponder) {
[self.textView resignFirstResponder];
}
else {
[self.textView becomeFirstResponder];
}
}
- (void)keyboardWasShown:(NSNotification*)aNotification
{
#ifdef WORKAROUND
[self.scrollView scrollRectToVisible:CGRectInset(self.textView.superview.frame, 0, -10) animated:YES];
#else
[self.scrollView scrollRectToVisible:CGRectInset(self.textView.frame, 0, -10) animated:YES];
#endif
}
@end