Search code examples
objective-cuitableviewuibuttontouchesmoved

Dragging a tableview cell that contains uibuttons


I'm trying to implement a uitableview that its rows can be dragged to right and left (and show something behind them). The code works fine, I've implemented it using the following methods:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;

My problem is that the rows also contain UIButtons that when clicking them- should be clicked but when dragging - should drag the entire cell. I've found this solution. Basically to bubble up the events when clicking on the UIButtons:

[super touchesBegan:touches withEvent:event];
[self.nextResponder touchesBegan:touches withEvent:event]; 

But, it seems taht the event touchesMoved only bubbles once.
I've seen all sort of questions in this area. Example. But I don't see any solution or responses.

Any help, suggestion or creative workaround would be appreciated!


Solution

  • Instead of implementing touchesBegan, etc. why not use a UIPanGestureRecognizer? I tested this with just a simple rectangular view which was mostly covered by a UIButton. The view was dragged, no matter where I touched, and the button method fired if I clicked over the button.

    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)];
        [self.theView addGestureRecognizer:panGesture]; //theView is IBOutlet for small view containing a button
    }
    
    -(void)viewDidAppear:(BOOL)animated {
        self.currentViewFrame = self.theView.frame;
    }
    
    - (IBAction)handlePanGesture:(UIPanGestureRecognizer *)sender {
        CGPoint translate = [sender translationInView:self.view];
    
        CGRect newFrame = self.currentViewFrame;
        newFrame.origin.x += translate.x;
        newFrame.origin.y += translate.y;
        sender.view.frame = newFrame;
    
        if (sender.state == UIGestureRecognizerStateEnded)
            self.currentViewFrame = newFrame;
    }
    
    -(IBAction)doClick:(id)sender {
        NSLog(@"click");
    }