Question

I've added a horizontal UIPanGestureRecognizer to my tableviewcell to pan a subview of the cell, like the way the ios7 mail app does to reveal delete and more options and this works as expected

- (IBAction)slideCell:(UIPanGestureRecognizer *)sender
{

    CGPoint locationOfPan = [sender locationInView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:locationOfPan];
    TestCell *cell = (TestCell *)[self.tableView cellForRowAtIndexPath:indexPath];    

    if (sender.state == UIGestureRecognizerStateChanged) {
        CGPoint translation = [sender translationInView:self.tableView];
        [cell.view setCenter:CGPointMake(cell.view.center.x + translation.x, cell.view.center.y)];
        [sender setTranslation:CGPointMake(0, 0) inView:self.tableView];
    }
}

What I would also like to do is add a UIAttachmentBehavior with an anchor point to each of my UITableViewCells so that when I pan the cell.view horizontally I feel some resistance and then when I let go, the view in the cell that was panned springs back to it's original anchor position on the x axis, is this possible to do with UIDynamics?

Also can I set one side of the cell as a boundary which prevents a user from panning the contained view beyond it?

Was it helpful?

Solution

So here is code to get this working, it still needs to be tweaks to get the right feel but it all works as expected

In the TestCell UITableViewCell subclass

-(void)layoutSubviews{

    [super layoutSubviews];

    self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self];

    self.attachmentBehavior = [[UIAttachmentBehavior alloc] initWithItem:self.topView attachedToAnchor:self.topView.center];
    [self.attachmentBehavior setFrequency:4.5];
    [self.attachmentBehavior setDamping:0.3];

    UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[self.topView]];

    //gravity direction: right
    [gravityBehavior setGravityDirection:CGVectorMake(1.0, 0.0)];

    UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[self.topView]];
    [collisionBehavior addBoundaryWithIdentifier:@"rightBoundary" fromPoint:CGPointMake(320.0f, 0.0f) toPoint:CGPointMake(320.0f, self.contentView.frame.size.height)];
    [self.animator addBehavior:gravityBehavior];
    [self.animator addBehavior:collisionBehavior];

}

In my tableViewController

-(BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer {
    CGPoint translation = [gestureRecognizer translationInView:self.view.superview];
    // Check for horizontal gesture
    if (fabsf(translation.x) > fabsf(translation.y)) {
        return YES;
    }else{
        return NO;
    }

}


- (IBAction)slideCell:(UIPanGestureRecognizer *)sender
{

    CGPoint locationOfPan = [sender locationInView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:locationOfPan];
    TestCell *cell = (TestCell *)[self.tableView cellForRowAtIndexPath:indexPath];

    if(sender.state == UIGestureRecognizerStateBegan){

        [cell.attachmentBehavior setAnchorPoint:cell.topView.center];
        [cell.animator addBehavior:cell.attachmentBehavior];

    }

    if (sender.state == UIGestureRecognizerStateChanged) {

        CGPoint translation = [sender translationInView:self.tableView];
        [cell.attachmentBehavior setAnchorPoint:CGPointMake(cell.topView.center.x + translation.x, cell.topView.center.y)];
        [sender setTranslation:CGPointMake(0, 0) inView:self.tableView];

    }

    if (sender.state == UIGestureRecognizerStateEnded) {
        //incase pan gesture has moved off the cell
        for(TestCell *cell in [self.tableView visibleCells]){
            [cell.animator removeBehavior:cell.attachmentBehavior];
        } 

    }

}

Hope this helps someone else trying to do the same thing, and if anyone knows the settings for UIAttachmentBehavior to get the same feel as a UIScrollview, could you let me know, thanks

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top