UITableView:以编程方式滚动内容视图

Posted

技术标签:

【中文标题】UITableView:以编程方式滚动内容视图【英文标题】:UITableView: scrolling programmatically the content view 【发布时间】:2011-03-28 08:08:18 【问题描述】:

您好,我正在尝试转发从 UITableView 前面的 UIView 收到的触摸。但是这样做我不能再让表格滚动了(see here)。

所以现在我正在尝试以编程方式使 tableview 滚动,我正在查看 setContentOffset:animated:scrollRectToVisible:animated: 并且只有第一个成功。 这是我在子类 UITableView 的类中的代码:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    NSLog(@"BEGTB");
    //previousXPan = 0.0;

    UITouch * touch = [touches anyObject];
    CGPoint tPoint = [touch locationInView:self]; 
    previousYPan = tPoint.y;

    [super touchesBegan:touches withEvent:event];
    //
    //[super touchesShouldBegin:touches withEvent:event inContentView:self];
    //[[self nextResponder] touchesBegan:touches withEvent:event];


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    UITouch * touch = [touches anyObject];
    CGPoint tPoint = [touch locationInView:self]; 


    NSLog(@"MOVTB");
    NSLog(@"BOUNDZ %f, %f, %f, %f", self.bounds.origin.x, self.bounds.origin.y, self.bounds.size.height, self.bounds.size.width);
    NSLog(@"CONTENT SIZE  %f, %f",  self.contentSize.height, self.contentSize.width);

    CGRect rc = [self bounds];
    NSLog(@"%f %f", rc.size.height, rc.size.width);
    CGRect newRect = CGRectMake(rc.origin.x, rc.origin.y + self.contentSize.height, self.contentSize.width, fabs(tPoint.y - previousYPan));
    NSLog(@"BOND RECT %f, %f, %f, %f", rc.origin.x, rc.origin.y, rc.size.height, rc.size.width);
    NSLog(@"NEW RECT %f, %f, %f, %f", newRect.origin.x, newRect.origin.y, newRect.size.height, newRect.size.width);
    //[self scrollRectToVisible:newRect animated:YES];
    NSLog(@"Content OFFSET %f",tPoint.y - previousYPan);
    [self setContentOffset:CGPointMake(rc.origin.x,(tPoint.y - previousYPan) *2.0 )animated:YES];
    previousYPan = tPoint.y;
    //[super touchesMoved:touches withEvent:event];
    //[[self nextResponder] touchesMoved:touches withEvent:event];

但结果确实很慢而且有问题。有更好的主意吗?

【问题讨论】:

您的 UIView 是否在 uitableviewcell 中,只需查看特定单元格内部并向前触摸即可更轻松? @vodkhang:我的 UIView 是 tableview 的视图 op 顶部,它将触摸转发到 uitableviewcell 触摸,然后转发到 uitable 视图(代码在消息中的链接上)。我正在放置这个 UIView 而不是直接使用 UITableViewCell,因为我想创建一个 ImageView 以在所有内容区域中拖动。 这听起来可能很愚蠢,但 NSLOG 确实会消耗大量性能(尤其是在诸如 cellForRowAtIndexPath 之类的常用方法中使用时)。尝试删除所有日志调用,看看是否更好,然后再深入研究。 @samsam:甚至都没有评论。性能不是这样的问题,但都是越野车和怪异,它上下弹跳,有时似乎不动,有时它像火箭一样上升 hmmm,那么看看 touchesMoved 被触发的频率可能会有所帮助,并且可能会限制对 setContentOffset 的调用,或者至少找到一种方法让 setContentOffset 在再次调用 setcontentOffset 之前一直进行动画处理(或者也许用动画尝试一下:NO)这是我目前能想到的。干杯! 【参考方案1】:

我几乎找到了一个合适的解决方案(它不像普通的滚动但是......)。

首先,我确定 Y 轴上表格视图的内容区域中的最小像素数量(视图完全加载时的 contentSize 高度)。

我检查了增量完成的运动,但没有参考表格视图中的触摸位置!我必须在覆盖它的顶层 UIView 上对其进行检查,因为当您更改表格的内容偏移量时,您会动态更改其尺寸,并且您最终会获得 加速效果

这是一些代码:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    UITouch * touch = [touches anyObject];

    CGPoint tPoint = [touch locationInView:[viewController draggableAreaView]];



    CGRect rc = [self bounds];


    float totalOS = tPoint.y - previousYPan;
    if ((contentOffSetY >= minY && contentOffSetY <= maxY) ||
        (contentOffSetY < minY - 5 && totalOS < 0) ||
        (contentOffSetY > maxY + 5 && totalOS > 0))
    

        if (totalOS > 0)
            totalOS += OFFSET;
        else if (totalOS < 0)
            totalOS -= OFFSET;
        [self setContentOffset:CGPointMake(rc.origin.x,self.contentOffset.y + totalOS)animated:NO];

    
    else /*if (contentOffSetY < minY - 5 && totalOS < 0) */
    
        [self resetOffset];
    
    previousYPan = tPoint.y; 



- (void)resetOffset

    CGRect rc = [self bounds];
    if(contentOffSetY < minY)
    
        [self setContentOffset:CGPointMake(rc.origin.x, minY + 50)animated:YES];
    
    else if (contentOffSetY > maxY)
    
        [self setContentOffset:CGPointMake(rc.origin.x, maxY - 50)animated:YES];
    

更多提示:

这里的 draggableAreaView 是顶部 UIView,我从中获得“绝对”位置 OFFSET 是一个常量,定义为线性增加滚动速度(没有它,touchesMoved: 被多次调用,每次只产生一个像素的相对移动) 、minYmaxY 是预先计算的极限值(为了计算它们,我计算了表格中所有单元格的高度为最大值,可见内容视图的高度为最小值) 我为minYmaxY 添加了一些位移,以使动画更明显

【讨论】:

你能告诉我什么是minY、maxY和contentOffSetY吗?我认为我的问题类似于这个问题

以上是关于UITableView:以编程方式滚动内容视图的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 以编程方式滚动到不存在的单元格

拖动滚动 UITableView 本身而不是其内容

以编程方式添加 UIControl

为啥我的 UITableView 单元格在滚动时重叠?

以编程方式将 UIButton 添加到 UITableView 但按钮不显示

以编程方式滚动底部的滚动视图 - iphone