UITableView重新排序模式期间的滚动速度(与性能无关)

时间:2010-07-12 01:29:36

标签: iphone uitableview scroll performance

有没有办法提高在movable row mode UITableView的表{{1}}期间向上/向下拖动单元格的速度?例如,似乎有一个标准速度,当您移动单元格时,表格将允许您拖动单元格,如果将其保持在设备屏幕的顶部/底部边缘附近,则滚动速度似乎会增加。对于给定的单元格高度和一大堆单元格,如果我必须使用标准的慢速滚动,这可能需要一段时间才能重新排序。

所以基本上,当你拖动单元格时,我想提高它向上/向下滚动的速度,这样就不需要花费很长时间就可以到达你想要放置单元格的位置。

据我所知,您可以通过降低单元格高度来加速移动过程,从而在设备屏幕上放置更多单元格,但我宁愿只在无法提高滚动速度时才这样做。

过去有过这方面经验的建议或想法吗?非常感谢任何建议!

3 个答案:

答案 0 :(得分:2)

如果列表要长,那么您可能需要考虑其他重新排序机制。例如,我的Netflix队列在每个调用中包含一个数字,用于指定队列的顺序,1表示要发送的电影,2表示下一个,依此类推,最后添加到队列的数据为187左右。我可以在iPhone上拖动一个条目重新排序,但我也可以更改单元格中的订单号以重新排序条目,这比将#187拖到队列中的第10个点要容易得多。每个条目中都有一个按钮,可以将该条目放在最顶层。

在您的应用中,您可以在编辑视图中添加额外的控件以帮助重新排序,例如订单号或“向上/向下10”按钮。

如果您的用户想要订购条目有共同的原因,您可以使用一个处理该条目的按钮,例如“向上移动到下一个最近的蓝色条目。”

答案 1 :(得分:2)

你走了。 SDK 3.1移动单元格时滚动速度增强器的概念验证。它可能无法通过Apple的要求,因为重写_beginReorderingForCell和_endReorderingForCell看起来有点不合规格。还有其他方法可以确定一个单元格是否开始或结束重新排序(例如,继承UITableViewCell并找到一些度量),但这是我认为最简单的方法。

方法非常简单:对于Y像素的每次移动,我们只会在重新排序时向下移动2 * Y像素。

问题是当前拖动的单元格是表格视图的子视图,因此如果我们移动它,它会随表格视图移动。如果我们要在此setContentOffset内更正它,则它没有任何效果,因为将根据除当前contentOffset之外的值计算单元格的位置。因此,我们稍后使用performSelector更正。

为方便起见,我将调试线留在那里。您需要做的就是使用FastUITableView代替UITableView(尤其是您的NIB)

你当然可以添加一些计时功能,这样速度只会在1秒左右后上升。那将是微不足道的。

@interface FastUITableView : UITableView
{
    UITableViewCell *draggingCell;
    CGFloat lastY;
}
@end


@implementation FastUITableView

-(void)_beginReorderingForCell:(UITableViewCell*)cell
{
    printf("begin reordering for cell %x\n",cell);
    draggingCell = cell;
    lastY = -1.0f;
    [super _beginReorderingForCell:cell];
}

-(void)_endReorderingForCell:(UITableViewCell*)cell wasCancelled:(BOOL)cancelled animated:(BOOL)animated
{
    printf("end reordering for cell %x\n",cell);
    draggingCell = nil;
    [super _endReorderingForCell:cell wasCancelled:cancelled animated:animated];
}

-(void)setContentOffset:(CGPoint)pt
{
    if ( !draggingCell )
    {
        [super setContentOffset:pt];
        return;
    }

    if ( lastY < 0 ) lastY = pt.y;
    CGPoint fast = pt;
    float diff = pt.y - lastY;
    //diff *= 0.5; /// <<--- control speed here
    fast.y = pt.y + diff;

    if ( fast.y > self.contentSize.height - self.superview.frame.size.height )
    {
        CGFloat corr = fast.y - self.contentSize.height + self.superview.frame.size.height;
        printf("Correction: %f\n",corr);
        fast.y -= corr;
        diff -= corr;
    } else if ( fast.y < 0.0f ) {
        CGFloat corr = -fast.y;
        printf("Correction: %f\n",corr);
        diff += corr;
        fast.y += corr;
    }

    [self performSelector:@selector(moveCell:) withObject:[NSNumber numberWithFloat:diff] afterDelay:0.01];

    lastY = fast.y;

//  printf("setting content offset: %f -> %f of max %f\n",pt.y, fast.y, self.contentSize.height);
    [super setContentOffset:fast];
}

-(void)moveCell:(NSNumber*)diff
{
    CGRect frame = draggingCell.frame;
    frame.origin.y += [diff floatValue];
//  printf("shifting cell %x with %f\n",draggingCell,[diff floatValue]);
    draggingCell.frame = frame;
}

答案 2 :(得分:0)

根据我的经验,tableView滚动速度取决于拖动的单元格与内容原点/结束点之间的距离。

因此,为了提高滚动速度,您不需要继承UITableView。相反,您可以设置tableView的contentInset属性。

例如,在viewDidLoad中调用它:

tableView.contentInset = UIEdgeInsetsMake(64, 0, 64, 0)

值64假定tableView上面有statusBar和navBar,tableView和superView之间的top / bottom约束设置为0,edgesForExtendedLayout设置为.all。 tableView位于navBar和statusBar下,但由于contentInset,它看起来像是附加到navBar。