Here you go. A proof of concept of a speed enhancer of the scroll when you move a cell, SDK 3.1. It may not pass Apple's requirements since overriding _beginReorderingForCell and _endReorderingForCell looks a little off-spec. There are other ways to determine if a cell starts or ends reordering (e.g. subclassing UITableViewCell
and finding some measure) but this is the easiest I think.
The approach is quite simple: for every movement of Y pixels down, we move 2*Y pixels down, only when reordering.
The problem is that the currently dragged cell is a subview of the table view, so it shifts with the table view if we move it. If we are to correct for that within this setContentOffset
, it has no effect since the position of the cell will be set based on values calculated apart from the current contentOffset
. Therefore we correct an instant later using performSelector
.
I left the debugging lines in there for convenience. All you need to do is to use FastUITableView
instead of UITableView
(esp. in you NIB)
You may of course want to add some timing things, so that the speed only goes up after 1 second or so. That will be trivial.
@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;
}