UIKit Dynamics: Attachment inside UITableViewCell

我的梦境 提交于 2019-12-03 09:11:30

I finally got it to work. The UITableView moves the coordinate system of every cell and of all views contained within that cell. Therefor I needed to manually move my view inside the UITableViewCell during scrolling while still referring to the initial anchor point.

The table view controller:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    BOOL scrollingUp = '\0';
    if (self.lastContentOffset > scrollView.contentOffset.y) {
        scrollingUp = YES;
    }
    else if (self.lastContentOffset < scrollView.contentOffset.y) {
        scrollingUp = NO;
    }

    NSInteger offset = 64; // To compensate for the navigation bar.

    if (scrollingUp) {
        offset = offset - scrollView.contentOffset.y;
    }
    else {
        offset = offset + scrollView.contentOffset.y;
    }

    // Limit the offset so the views will not disappear during fast scrolling.
    if (offset > 10) {
        offset = 10;
    }
    else if (offset < -10) {
        offset = -10;
    }

    // lastContentOffset is an instance variable.
    self.lastContentOffset = scrollView.contentOffset.y;

    for (UITableViewCell *cell in self.tableView.visibleCells) {  
        // Use CoreAnimation to prohibit flicker.          
        [UIView beginAnimations:@"Display notification" context:nil];
        [UIView setAnimationDuration:0.5f];
        [UIView setAnimationBeginsFromCurrentState:YES];

        cell.view.frame = CGRectMake(cell.view.frame.origin.x, offset, cell.view.frame.size.width, cell.view.frame.size.height);
        [UIView commitAnimations];
        [cell.dynamicAnimator updateItemUsingCurrentState:cell.view];
    }
}

The table view cell:

-(void)layoutSubviews {
    [super layoutSubviews];

    // _view is the animated UIView.
    UIDynamicItemBehavior *viewBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[_view]];
    viewBehavior.elasticity = 0.9f;

    UIAttachmentBehavior *attachmentBehaviorView = [[UIAttachmentBehavior alloc] initWithItem:_view attachedToAnchor:CGPointMake(_anchorView.frame.origin.x + _anchorView.frame.size.width / 2.0f, _anchorView.frame.origin.y + _anchorView.frame.size.height / 2.0f)];
    attachmentBehaviorView.damping = 8.0f;
    attachmentBehaviorView.frequency = 4.0f;
    attachmentBehaviorView.length = 0.0f;

    [_dynamicAnimator addBehavior:viewBehavior];
    [_dynamicAnimator addBehavior:attachmentBehaviorView];
}

You can change the anchorPoint of UIAttachmentBehavior during -[scrollViewDidScroll:]. You may refer to the following code snippet:

- (void)viewDidLoad
{
    UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

    UIAttachmentBehavior *behavior1 = [[UIAttachmentBehavior alloc] initWithItem:self.circleView
                                          attachedToAnchor:[self tableViewAnchor]];
    behavior1.length = 10.0;
    behavior1.damping = 0.3;
    behavior1.frequency = 2.5;

    [animator addBehavior:behavior1];
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    behavior1.anchorPoint = [self.tableView convertPoint:[self tableViewAnchor] toView:self.view];
}

- (CGPoint)tableViewAnchor
{
    return CGPointMake(160.0, 154.0);   // return your target coordination w.r.t. the table view
}

Preview:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!