2011-08-23 133 views
5

我有一个包含一个按钮的UIScrollView。 当按下按钮时,我想使用scrollRectToVisible滚动到视图的底部。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,但所有这些似乎工作正常。

有什么想法?

+0

还没有想通了这一点,但我必须把它完成,所以我刚开始一个计时器,并滚动它自己,直到它在正确的位置,使用setContentOffset W /动画:NO。作品,但:( –

回答

5

我敢打赌,scrollRectToVisible是crapping,因为可视面积为无效(1×1),或y偏移只是边界之外,你有没有试着用滚动视图的可见区域的大小设置它代替?

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现在,所以我不能运行测试。上面的代码会创建一个适合scrollView可见部分的精确大小的CGRect,并且偏移量将是其中最后一个可见部分。

+0

有趣的,我会给这个尝试,但我很可疑我没有使用更正常的大小矩形 - 例如scrollView的宽度和一些高度大于一但小于scrollview的高度,但它没有什么不同,在contentSize的中间也尝试过矩形,而不是在最后,我会让你知道的,在附注中,我不知道CGRectZero,谢谢! –

+0

刚刚回复你这个 - 我试过了,没有运气,我终于用“动画:NO”和一个计时器结束了自己的动画效果,不管怎么说,谢谢 –

+0

我刚刚遇到过这个,花了大概2个小时看着一切*但是* scrollRectToVisible调用。 –

0

我遇到过类似的问题,包括“如果我设置动画为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