UIScrollView ScrollRectToVisible - не работает с animate = yes - PullRequest
5 голосов
/ 24 августа 2011

У меня есть UIScrollView, который содержит кнопку. Когда кнопка нажата, я бы хотел перейти к нижней части представления, используя scrollRectToVisible.

например:

CGRect r = CGRectMake(0, myUIScrollView.contentSize.height - 1, 1, 1);
[myUIScrollView scrollRectToVisible:r animated:YES];

Если я установил анимированный на NO, все работает как положено, но если установить значение YES, я вижу странное поведение:

  • в принципе, ничего не происходит.
  • если я несколько раз коснусь кнопки, она может прокрутить пару пикселей, или можете прокрутить полностью.
  • но если я прокручиваю вид вручную пальцем перед нажатием кнопки, у него есть шанс прокрутиться до конца, как и ожидалось, но это не совсем точно.

Я напечатал _geScroll_Settings.contentSize, и он, как и ожидалось.

Я также пытался отложить вызов scrollRectToVisible, запустив таймер, но результаты в значительной степени совпадают.

ScrollView довольно ванильный. Я создаю его в конструкторе интерфейсов. Я динамически добавляю контент scrollView при запуске и корректно настраиваю его contentSize, но все, что кажется, работает нормально.

Есть мысли?

Ответы [ 2 ]

6 голосов
/ 24 августа 2011

Моя ставка в том, что scrollRectToVisible выходит из строя, потому что видимая область недопустима (1x1) или y смещение находится за пределами границ, вы пытались установить его с размером видимой областивместо scrollView?

CGRect rectBottom = CGRectZero;
rectBottom.size = myUIScrollView.frame.size;
rectBottom.origin.y = myUIScrollView.contentSize.height - rectBottom.size.height;
rectBottom.origin.x = 0;

[myUIScrollView scrollRectToVisible:rectBottom animated:YES];

Извините, я не могу вам больше помочь, но сейчас я не на своем Mac, поэтому я не могу запустить тест.Приведенный выше код создаст CGRect точного размера того, что помещается внутри видимой части scrollView, а смещение будет последней видимой частью в нем.

0 голосов
/ 21 декабря 2013

Я столкнулся с аналогичной проблемой, в том числе с частью «Если я установил анимированный на 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
...