Ios uiscrollview scrollRectToVisible方法不起做用

iOS 码拜 5年前 (2015-04-30) 438次浏览 0个评论

[size=13px][size=12px]我有一个需求,做一个类似网易新闻客户端的标签 让标签rect滚动到可以显示的范围里
则调用了 – (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated; 这个方法 但是没有作用代码如下

– (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    self.view.backgroundColor = [UIColor yellowColor];
    self.automaticallyAdjustsScrollViewInsets = NO;

    scroll = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 80, 320, 44)];
    scroll.contentSize = CGSizeMake(60*10, 0);
    for(int i=0; i<10; i++)
    {
        UIButton *bt = [[UIButton alloc]initWithFrame:CGRectMake(60*i, 0, 60, 44)];
        [bt setTitle:[NSString stringWithFormat:@”第%i块”,i] forState:UIControlStateNormal];
        bt.backgroundColor = [UIColor redColor];
        bt.tag = 1000+i;
        [scroll addSubview:bt];
        [bt addTarget:self action:@selector(pressBt:) forControlEvents:UIControlEventTouchUpInside];
    }
    scroll.delegate = self;
    scroll.backgroundColor = [UIColor clearColor];
    [self.view addSubview:scroll];
}
– (void)pressBt:(UIButton *)bt
{
    [scroll scrollRectToVisible:bt.frame animated:YES];
}[/size][/size]

求大神赐教

Ios uiscrollview  scrollRectToVisible方法不起做用
button是作为scrollview 的子控件来添加的,所以button 的坐标系是相对于它的父视图scrollview来说的。但在uiscrollview 的 scrollRectToVisible:animated:要求的坐标系是相对于self.view来说的,所以你需要将button转换坐标系得到相对self.view的坐标位置,再使用scrollRectToVisible:animated: 来定位uiscrollview. 转换代码:

CGRect  rect = [scroll  convertRect: btn.frame toView:self.view];

完整代码如下:

- (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [scroll  convertRect: btn.frame toView:self.view];
    [scroll scrollRectToVisible:rect animated:YES];
}
Ios uiscrollview  scrollRectToVisible方法不起做用
版主大人,好像不是这么回事 我又调整了代码 有用代理做了测试 也不行

- (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    [scroll scrollRectToVisible:rect animated:YES];
    NSLog(@"点击了事件");
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [scroll scrollRectToVisible:CGRectMake(0, 80, 60, 44) animated:YES];
    NSLog(@"代理");
}
Ios uiscrollview  scrollRectToVisible方法不起做用
引用 2 楼 u013030988 的回复:

版主大人,好像不是这么回事 我又调整了代码 有用代理做了测试 也不行

- (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    [scroll scrollRectToVisible:rect animated:YES];
    NSLog(@"点击了事件");
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [scroll scrollRectToVisible:CGRectMake(0, 80, 60, 44) animated:YES];
    NSLog(@"代理");
}

应该是没问题的。把convert出来后的rect 打印到控制台输出,看下是多少

NSLog(@"converted rect is :%@",NSStringFromCGRect(rect))
Ios uiscrollview  scrollRectToVisible方法不起做用
引用 3 楼 zhanglei5415 的回复:
Quote: 引用 2 楼 u013030988 的回复:

版主大人,好像不是这么回事 我又调整了代码 有用代理做了测试 也不行

- (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    [scroll scrollRectToVisible:rect animated:YES];
    NSLog(@"点击了事件");
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [scroll scrollRectToVisible:CGRectMake(0, 80, 60, 44) animated:YES];
    NSLog(@"代理");
}

应该是没问题的。把convert出来后的rect 打印到控制台输出,看下是多少

NSLog(@"converted rect is :%@",NSStringFromCGRect(rect))

Ios uiscrollview  scrollRectToVisible方法不起做用

Ios uiscrollview  scrollRectToVisible方法不起做用
引用 4 楼 u013030988 的回复:
Quote: 引用 3 楼 zhanglei5415 的回复:
Quote: 引用 2 楼 u013030988 的回复:

版主大人,好像不是这么回事 我又调整了代码 有用代理做了测试 也不行

- (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    [scroll scrollRectToVisible:rect animated:YES];
    NSLog(@"点击了事件");
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [scroll scrollRectToVisible:CGRectMake(0, 80, 60, 44) animated:YES];
    NSLog(@"代理");
}

应该是没问题的。把convert出来后的rect 打印到控制台输出,看下是多少

NSLog(@"converted rect is :%@",NSStringFromCGRect(rect))

Ios uiscrollview  scrollRectToVisible方法不起做用

这就是button当前相对于self.view的位置,它的位置就在这里,scrollRectToVisible 又定位在了这个位置,所以看不出变化。你是不是应该根据当前button 的位置做下判断,比如当button的x 坐标大于某个值时,让x的位置滚动到某个位置。如大于270时让它定位在200的位置,可以这样

 - (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    if (rect.origin.x > 270) {
             rect.origin.x -= 70;
             [scroll scrollRectToVisible:rect animated:YES];
   }
}
Ios uiscrollview  scrollRectToVisible方法不起做用
- (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    rect.origin.x = 0;
    [scroll scrollRectToVisible:rect animated:YES];
    NSLog(@"点击了事件");
}

我把这个rect.origin.x 写死了0,如果scroll向右滚动过了,点击了bt就应该滚动到最左面
但是确实没有这么显示 非常奇怪

Ios uiscrollview  scrollRectToVisible方法不起做用
引用 6 楼 u013030988 的回复:
- (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    rect.origin.x = 0;
    [scroll scrollRectToVisible:rect animated:YES];
    NSLog(@"点击了事件");
}

我把这个rect.origin.x 写死了0,如果scroll向右滚动过了,点击了bt就应该滚动到最左面
但是确实没有这么显示 非常奇怪

你有没有实现 scrollView 的 Delegate 方法,比如 didScroll?

Ios uiscrollview  scrollRectToVisible方法不起做用
有实现 我实现了一个 完成滚动时的代理

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [scroll scrollRectToVisible:CGRectMake(0, 80, 60, 44) animated:YES];
}

点击按钮时并不会调用他。滚动后调用这个代理, scrollRectToVisible方法似乎也没有起到作用

Ios uiscrollview  scrollRectToVisible方法不起做用
引用 5 楼 zhanglei5415 的回复:
Quote: 引用 4 楼 u013030988 的回复:
Quote: 引用 3 楼 zhanglei5415 的回复:
Quote: 引用 2 楼 u013030988 的回复:

版主大人,好像不是这么回事 我又调整了代码 有用代理做了测试 也不行

- (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    [scroll scrollRectToVisible:rect animated:YES];
    NSLog(@"点击了事件");
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [scroll scrollRectToVisible:CGRectMake(0, 80, 60, 44) animated:YES];
    NSLog(@"代理");
}

应该是没问题的。把convert出来后的rect 打印到控制台输出,看下是多少

NSLog(@"converted rect is :%@",NSStringFromCGRect(rect))

Ios uiscrollview  scrollRectToVisible方法不起做用

这就是button当前相对于self.view的位置,它的位置就在这里,scrollRectToVisible 又定位在了这个位置,所以看不出变化。你是不是应该根据当前button 的位置做下判断,比如当button的x 坐标大于某个值时,让x的位置滚动到某个位置。如大于270时让它定位在200的位置,可以这样

 - (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    if (rect.origin.x > 270) {
             rect.origin.x -= 70;
             [scroll scrollRectToVisible:rect animated:YES];
   }
}
CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    rect.origin.x = 0;
    [scroll scrollRectToVisible:rect animated:YES];
    NSLog(@"点击了事件");

我把这个rect.origin.x 写死了0,如果scroll向右滚动过了,点击了bt就应该滚动到最左面
但是确实没有这么显示 非常奇怪

Ios uiscrollview  scrollRectToVisible方法不起做用
引用 9 楼 u013030988 的回复:
Quote: 引用 5 楼 zhanglei5415 的回复:
Quote: 引用 4 楼 u013030988 的回复:
Quote: 引用 3 楼 zhanglei5415 的回复:
Quote: 引用 2 楼 u013030988 的回复:

版主大人,好像不是这么回事 我又调整了代码 有用代理做了测试 也不行

- (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    [scroll scrollRectToVisible:rect animated:YES];
    NSLog(@"点击了事件");
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [scroll scrollRectToVisible:CGRectMake(0, 80, 60, 44) animated:YES];
    NSLog(@"代理");
}

应该是没问题的。把convert出来后的rect 打印到控制台输出,看下是多少

NSLog(@"converted rect is :%@",NSStringFromCGRect(rect))

Ios uiscrollview  scrollRectToVisible方法不起做用

这就是button当前相对于self.view的位置,它的位置就在这里,scrollRectToVisible 又定位在了这个位置,所以看不出变化。你是不是应该根据当前button 的位置做下判断,比如当button的x 坐标大于某个值时,让x的位置滚动到某个位置。如大于270时让它定位在200的位置,可以这样

 - (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    if (rect.origin.x > 270) {
             rect.origin.x -= 70;
             [scroll scrollRectToVisible:rect animated:YES];
   }
}
CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    rect.origin.x = 0;
    [scroll scrollRectToVisible:rect animated:YES];
    NSLog(@"点击了事件");

我把这个rect.origin.x 写死了0,如果scroll向右滚动过了,点击了bt就应该滚动到最左面
但是确实没有这么显示 非常奇怪

这也真是太奇葩了。不行,你打包发上来,帮你看看。

Ios uiscrollview  scrollRectToVisible方法不起做用
引用 10 楼 zhanglei5415 的回复:
Quote: 引用 9 楼 u013030988 的回复:
Quote: 引用 5 楼 zhanglei5415 的回复:
Quote: 引用 4 楼 u013030988 的回复:
Quote: 引用 3 楼 zhanglei5415 的回复:
Quote: 引用 2 楼 u013030988 的回复:

版主大人,好像不是这么回事 我又调整了代码 有用代理做了测试 也不行

- (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    [scroll scrollRectToVisible:rect animated:YES];
    NSLog(@"点击了事件");
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [scroll scrollRectToVisible:CGRectMake(0, 80, 60, 44) animated:YES];
    NSLog(@"代理");
}

应该是没问题的。把convert出来后的rect 打印到控制台输出,看下是多少

NSLog(@"converted rect is :%@",NSStringFromCGRect(rect))

Ios uiscrollview  scrollRectToVisible方法不起做用

这就是button当前相对于self.view的位置,它的位置就在这里,scrollRectToVisible 又定位在了这个位置,所以看不出变化。你是不是应该根据当前button 的位置做下判断,比如当button的x 坐标大于某个值时,让x的位置滚动到某个位置。如大于270时让它定位在200的位置,可以这样

 - (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    if (rect.origin.x > 270) {
             rect.origin.x -= 70;
             [scroll scrollRectToVisible:rect animated:YES];
   }
}
CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    rect.origin.x = 0;
    [scroll scrollRectToVisible:rect animated:YES];
    NSLog(@"点击了事件");

我把这个rect.origin.x 写死了0,如果scroll向右滚动过了,点击了bt就应该滚动到最左面
但是确实没有这么显示 非常奇怪

这也真是太奇葩了。不行,你打包发上来,帮你看看。

这不会传,我传百度网盘了 http://pan.baidu.com/s/1qWwo45e

Ios uiscrollview  scrollRectToVisible方法不起做用
引用 11 楼 u013030988 的回复:
Quote: 引用 10 楼 zhanglei5415 的回复:
Quote: 引用 9 楼 u013030988 的回复:
Quote: 引用 5 楼 zhanglei5415 的回复:
Quote: 引用 4 楼 u013030988 的回复:
Quote: 引用 3 楼 zhanglei5415 的回复:
Quote: 引用 2 楼 u013030988 的回复:

版主大人,好像不是这么回事 我又调整了代码 有用代理做了测试 也不行

- (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    [scroll scrollRectToVisible:rect animated:YES];
    NSLog(@"点击了事件");
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [scroll scrollRectToVisible:CGRectMake(0, 80, 60, 44) animated:YES];
    NSLog(@"代理");
}

应该是没问题的。把convert出来后的rect 打印到控制台输出,看下是多少

NSLog(@"converted rect is :%@",NSStringFromCGRect(rect))

Ios uiscrollview  scrollRectToVisible方法不起做用

这就是button当前相对于self.view的位置,它的位置就在这里,scrollRectToVisible 又定位在了这个位置,所以看不出变化。你是不是应该根据当前button 的位置做下判断,比如当button的x 坐标大于某个值时,让x的位置滚动到某个位置。如大于270时让它定位在200的位置,可以这样

 - (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    if (rect.origin.x > 270) {
             rect.origin.x -= 70;
             [scroll scrollRectToVisible:rect animated:YES];
   }
}
CGRect  rect = [scroll  convertRect: bt.frame toView:self.view];
    rect.origin.x = 0;
    [scroll scrollRectToVisible:rect animated:YES];
    NSLog(@"点击了事件");

我把这个rect.origin.x 写死了0,如果scroll向右滚动过了,点击了bt就应该滚动到最左面
但是确实没有这么显示 非常奇怪

这也真是太奇葩了。不行,你打包发上来,帮你看看。

这不会传,我传百度网盘了 http://pan.baidu.com/s/1qWwo45e

看了你的代码,你这个 pressBt 实现不对,不应该用convertRect,直接用 button 的 frame 就行了。

- (void)pressBt:(UIButton *)bt {
    CGRect  rect = bt.frame;//[scroll  convertRect: bt.frame toView:self.view];
    rect.origin.x = 0;
    [scroll scrollRectToVisible:rect animated:YES];
    NSLog(@"点击了事件");
}

再来看convertRect方法,convertRect 是把 Rect 坐标映射到指定的 view 上的坐标,你的 button 又不是添加到 self.view 上的,映射成的坐标当然就不对了,比如你的 button 的 y 是0, 你映射成 self.view 的 y 就成了80(scroll 的 y),如果你一定要用convertRect方法的话有两种方案:
1. 让 self.view 自身就是一个 scrollView,然后把 button 添加到 scrollView 上;
2. 用这句CGRect rect = [scroll convertRect: bt.frame toView:scroll]代替。

Ios uiscrollview  scrollRectToVisible方法不起做用
20分
看了下,你是后来才改成用convertRect转换的,你是想点击5的时候让5全部显示吧:
Ios uiscrollview  scrollRectToVisible方法不起做用
如果是那样的话,你的问题是出在 contentSize 上:

contentSize = CGSizeMake(60*10, 0);

你要让 scrollView 按 Rect 来滚动的前提是 contentSize 的 x、y 都不能为0,改在这样就ok 了:

contentSize = CGSizeMake(60*10, 1);
Ios uiscrollview  scrollRectToVisible方法不起做用
20分
看你的代码了,可以用convert后的位置来判断是向左向右,再根据bt的frame来计算滚动的位置。我下面的代码是这样处理的,如果点击的位置超过了屏幕的一半,这样scroll就向左滑动,让被点击的按钮处在屏幕中间。如果计算得到的posX 小于 0 说明滚动到了头部。还是看代码吧:

- (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [self.scroll  convertRect: bt.frame toView:self.view];
    NSLog(@"rect is %@",NSStringFromCGRect(rect));
    CGFloat posX = 0;
    CGFloat halfWidth = 60/2;
    posX = bt.frame.origin.x-self.scroll.frame.size.width/2+halfWidth; /////让点击的按钮位置居中
    
    if (rect.origin.x >=self.scroll.frame.size.width/2 + halfWidth) {
        if(posX >= self.scroll.contentSize.width/2-halfWidth)
            posX = self.scroll.contentSize.width - self.scroll.frame.size.width; /////滚动到尾
    }else { //////向前滚动,判断是否到头了。
        if (posX <= 0)
            posX = 0;  /////滚动到头
    }
    
    [UIView animateWithDuration:0.3f animations:^{
        [self.scroll setContentOffset:CGPointMake(posX, 0)];
    }];
    
    NSLog(@"点击了事件");
}
Ios uiscrollview  scrollRectToVisible方法不起做用
引用 14 楼 zhangao0086 的回复:

看了下,你是后来才改成用convertRect转换的,你是想点击5的时候让5全部显示吧:
Ios uiscrollview  scrollRectToVisible方法不起做用
如果是那样的话,你的问题是出在 contentSize 上:

contentSize = CGSizeMake(60*10, 0);

你要让 scrollView 按 Rect 来滚动的前提是 contentSize 的 x、y 都不能为0,改在这样就ok 了:

contentSize = CGSizeMake(60*10, 1);

恩,改了 contentSize 确实好用了,谢谢版主了。问题解决。

Ios uiscrollview  scrollRectToVisible方法不起做用
引用 15 楼 zhanglei5415 的回复:

看你的代码了,可以用convert后的位置来判断是向左向右,再根据bt的frame来计算滚动的位置。我下面的代码是这样处理的,如果点击的位置超过了屏幕的一半,这样scroll就向左滑动,让被点击的按钮处在屏幕中间。如果计算得到的posX 小于 0 说明滚动到了头部。还是看代码吧:

- (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [self.scroll  convertRect: bt.frame toView:self.view];
    NSLog(@"rect is %@",NSStringFromCGRect(rect));
    CGFloat posX = 0;
    CGFloat halfWidth = 60/2;
    posX = bt.frame.origin.x-self.scroll.frame.size.width/2+halfWidth; /////让点击的按钮位置居中
    
    if (rect.origin.x >=self.scroll.frame.size.width/2 + halfWidth) {
        if(posX >= self.scroll.contentSize.width/2-halfWidth)
            posX = self.scroll.contentSize.width - self.scroll.frame.size.width; /////滚动到尾
    }else { //////向前滚动,判断是否到头了。
        if (posX <= 0)
            posX = 0;  /////滚动到头
    }
    
    [UIView animateWithDuration:0.3f animations:^{
        [self.scroll setContentOffset:CGPointMake(posX, 0)];
    }];
    
    NSLog(@"点击了事件");
}

问题解决了。 是由于 contentSize?=?CGSizeMake(60*10,?0); 的问题
改为 contentSize?=?CGSizeMake(60*10,?1)变解决了 多谢版主耐心指导

Ios uiscrollview  scrollRectToVisible方法不起做用
引用 15 楼 zhanglei5415 的回复:

看你的代码了,可以用convert后的位置来判断是向左向右,再根据bt的frame来计算滚动的位置。我下面的代码是这样处理的,如果点击的位置超过了屏幕的一半,这样scroll就向左滑动,让被点击的按钮处在屏幕中间。如果计算得到的posX 小于 0 说明滚动到了头部。还是看代码吧:

- (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [self.scroll  convertRect: bt.frame toView:self.view];
    NSLog(@"rect is %@",NSStringFromCGRect(rect));
    CGFloat posX = 0;
    CGFloat halfWidth = 60/2;
    posX = bt.frame.origin.x-self.scroll.frame.size.width/2+halfWidth; /////让点击的按钮位置居中
    
    if (rect.origin.x >=self.scroll.frame.size.width/2 + halfWidth) {
        if(posX >= self.scroll.contentSize.width/2-halfWidth)
            posX = self.scroll.contentSize.width - self.scroll.frame.size.width; /////滚动到尾
    }else { //////向前滚动,判断是否到头了。
        if (posX <= 0)
            posX = 0;  /////滚动到头
    }
    
    [UIView animateWithDuration:0.3f animations:^{
        [self.scroll setContentOffset:CGPointMake(posX, 0)];
    }];
    
    NSLog(@"点击了事件");
}

不需要这样,直接用scrollRectToVisible就行了

Ios uiscrollview  scrollRectToVisible方法不起做用
引用 18 楼 zhangao0086 的回复:
Quote: 引用 15 楼 zhanglei5415 的回复:

看你的代码了,可以用convert后的位置来判断是向左向右,再根据bt的frame来计算滚动的位置。我下面的代码是这样处理的,如果点击的位置超过了屏幕的一半,这样scroll就向左滑动,让被点击的按钮处在屏幕中间。如果计算得到的posX 小于 0 说明滚动到了头部。还是看代码吧:

- (void)pressBt:(UIButton *)bt
{
    CGRect  rect = [self.scroll  convertRect: bt.frame toView:self.view];
    NSLog(@"rect is %@",NSStringFromCGRect(rect));
    CGFloat posX = 0;
    CGFloat halfWidth = 60/2;
    posX = bt.frame.origin.x-self.scroll.frame.size.width/2+halfWidth; /////让点击的按钮位置居中
    
    if (rect.origin.x >=self.scroll.frame.size.width/2 + halfWidth) {
        if(posX >= self.scroll.contentSize.width/2-halfWidth)
            posX = self.scroll.contentSize.width - self.scroll.frame.size.width; /////滚动到尾
    }else { //////向前滚动,判断是否到头了。
        if (posX <= 0)
            posX = 0;  /////滚动到头
    }
    
    [UIView animateWithDuration:0.3f animations:^{
        [self.scroll setContentOffset:CGPointMake(posX, 0)];
    }];
    
    NSLog(@"点击了事件");
}

不需要这样,直接用scrollRectToVisible就行了

我的方式不可以?可能复杂了点,呵呵。


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明Ios uiscrollview scrollRectToVisible方法不起做用
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!