代码之家  ›  专栏  ›  技术社区  ›  iwasrobbed

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

  •  0
  • iwasrobbed  · 技术社区  · 16 年前

    有没有一种方法可以提高在表格中向上/向下拖动单元格的速度? movable row mode A的 UITableView ?例如,似乎有一个标准速度,当您移动单元格时,表允许您拖动单元格,如果您将其保持在设备屏幕的上/下边缘附近,滚动速度似乎会增加。对于一个给定的单元格高度和一大堆单元格,如果必须使用它们的标准慢速滚动,可能需要一段时间来重新排序它们。

    所以基本上,我想提高它在拖动单元格时向上/向下滚动的速度,这样就不会花太长时间到达要将单元格放置到位的位置。

    我知道你可以通过降低单元高度来加速移动过程,从而在设备屏幕上放置更多的单元,但我宁愿这样做,除非我不能提高滚动速度。

    从过去的经验中有什么建议或想法吗?任何建议都非常感谢!

    3 回复  |  直到 9 年前
        1
  •  2
  •   mvds    16 年前

    干得好。当你移动一个单元格时,卷轴的速度提升器的概念证明,sdk 3.1。它可能无法满足苹果的要求,因为覆盖的beginreorderingforcell和endreorderingforcell看起来有点不规范。还有其他方法可以确定单元格是开始还是结束重新排序(例如子类化 UITableViewCell 但这是我认为最简单的方法。

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

    问题是当前拖动的单元格是表视图的子视图,因此如果我们移动它,它将随表视图移动。如果我们要在这个范围内纠正它 setContentOffset ,因为单元格的位置将根据除当前值之外计算的值设置,所以它没有效果。 contentOffset . 因此,我们稍后使用 performSelector .

    为了方便起见,我把调试线留在那里了。你所要做的就是使用 FastUITableView 而不是 UITableView (尤其是你的笔尖)

    当然,你可能想增加一些定时的东西,这样速度只会在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
  •  2
  •   John Franklin    16 年前

    如果列表要长那么长,您可能需要考虑其他重新排序机制。例如,我的Netflix队列在每个调用中都包含一个数字,指定队列的顺序,1个用于即将发布的电影,2个用于下一个,以此类推,大约187个用于队列中最近添加的内容。我可以像在iPhone上一样拖动一个条目来重新排序,但我也可以更改单元格中的订单号来重新排序条目,这比将187拖动到队列中的第10个位置要容易得多。每个条目中也有一个按钮,将该条目放在最上面。

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

    如果您的用户希望订购条目有一些常见的原因,您可以使用一个按钮来处理,例如“向上移动到下一个最近的蓝色条目”。

        3
  •  0
  •   Mijo    9 年前

    根据我的经验,TableView滚动速度取决于拖动单元格和内容起点/终点之间的距离。

    因此,为了提高滚动速度,您不需要子类UITableView。相反,您可以设置TableView的ContentInSet属性。

    例如,在viewdidload中调用此函数:

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

    值64假定TableView上方有状态栏和导航栏,TableView和SuperView之间的上/下约束设置为0,EdgesForExtendedLayout设置为.all。 该表视图位于导航栏和状态栏下,但由于内容插入,它看起来像是连接到了导航栏上。