3

Possible Duplicate:
How to get notified of UITableViewCell move start and end

I have implemented a UITableView with a custom design. This UITableView has to support edit mode. When entering the edit mode, UITableViewCell gets decorated with additional controls (EditControl, ReorderControl...). They don't fit well with my custom design and that's why I wanted to replace their images. For that purpose I subclassed UITableViewCell and overrode layoutSubview, where I replace the images for those controls.

Problem: When starting a drag & drop operation, the image for EditControl is replaced back to the original one somewhere in UITableViewCell. I can replace it again in

– tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:

when user moves the draggable cell to another indexPath, but that's too late.

So my question boils down to: How can I detect the moment the user actually starts dragging a UITableViewCell?

Community
  • 1
  • 1
Andy Friese
  • 6,349
  • 3
  • 20
  • 17
  • use PanGesture to detect the moment of dragging operation of the images – Bala Mar 19 '12 at 07:57
  • Thanks for your comment. Already tried that, without success. I can attach a GestureRecognizer to the contentview of the cell and my handler get's fired. But it doesn't get fired for touches of the ReorderControl. The same is true for overriding touchesBegan... – Andy Friese Mar 19 '12 at 15:51
  • Post your Code that might help to find a solution :) – Bala Mar 19 '12 at 15:56
  • I already found two solutions. First one: the images for EditControl won't be replaced by UITableViewCell, when the cell is in selected state. So i keep that state selected all the time and implemented my own tracking of selection in touchesBegan... Second and preferred solution: Dump that ugly hack, it's relying on too much internals which might change. If you are still interested I could post the hacky solution... – Andy Friese Mar 19 '12 at 16:26

1 Answers1

0

While Bala's comment went into the right direction, I initially had some problems with the right implementation. Now I found out how it can be done. In short: You have to create a custom subclass of UITableViewCell. Override layoutSubviews to attach a UILongPressGestureRecognizer to UITableViewCellReorderControl. Define a protocol and use a delegate to inform whoever you want to about the dragging state.

CustomTableViewCell.h:

#import <UIKit/UIKit.h>

@protocol CustomTableViewCellDelegate;

@interface CustomTableViewCell : UITableViewCell {
}

@property (nonatomic, assign) id <CustomTableViewCellDelegate> delegate;

@end

@protocol CustomTableViewCellDelegate
- (void)CustomTableViewCell:(CustomTableViewCell *)cell isDragging:(BOOL)value;
@end

CustomTableViewCell.m:

#import "CustomTableViewCell.h"

@implementation CustomTableViewCell

@synthesize delegate = _delegate;

- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer {
    if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
        [_delegate CustomTableViewCell:self isDragging:YES];    // Dragging started
    } else if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
        [_delegate CustomTableViewCell:self isDragging:NO];     // Dragging ended
    }
}

- (void)layoutSubviews {
    [super layoutSubviews];

    for (UIView *view in self.subviews) {
        if ([NSStringFromClass ([view class]) rangeOfString:@"ReorderControl"].location != NSNotFound) {    // UITableViewCellReorderControl
            if (view.gestureRecognizers.count == 0) {
                UILongPressGestureRecognizer *gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
                gesture.cancelsTouchesInView    = NO;
                gesture.minimumPressDuration    = 0.150;
                [view addGestureRecognizer:gesture];
            }
        }
    }
}

@end

Be aware that while this code doesn't use any private APIs it still might stop working if Apple changes its internal implementation (i.e. by changing the classname of UITableViewCellReorderControl).

Andy Friese
  • 6,349
  • 3
  • 20
  • 17