Ios UICollectionView在UILongpress手势中滚动

Ios UICollectionView在UILongpress手势中滚动,ios,uicollectionview,Ios,Uicollectionview,更新问题。当视图滚动时,我很难在集合视图中重新排序项目。原因是用于重新排序项目的代码位于UILongpress手势的UIgestureRecognitizerStateChanged内。因此,当视图滚动且用户的手指静止在屏幕边缘时,不会调用UILongpress手势中的重新排序代码。如果我只是简单地插入重新排序代码: // Is destination valid and is it different from source? if (indexPath &&a

更新问题。当视图滚动时,我很难在集合视图中重新排序项目。原因是用于重新排序项目的代码位于UILongpress手势的UIgestureRecognitizerStateChanged内。因此,当视图滚动且用户的手指静止在屏幕边缘时,不会调用UILongpress手势中的重新排序代码。如果我只是简单地插入重新排序代码:

// Is destination valid and is it different from source?
            if (indexPath && ![indexPath isEqual:sourceIndexPath]) {

                // ... update data source.
                [self.imageArray exchangeObjectAtIndex:indexPath.row withObjectAtIndex:sourceIndexPath.row];

                // ... move the rows.
                [self.collectionView  moveItemAtIndexPath:sourceIndexPath toIndexPath:indexPath];

                // ... and update source so it is in sync with UI changes.
                sourceIndexPath = indexPath;
在autoscrollTimerFired方法中,项的indexpath将不再正确,因为集合视图已滚动到用户静态手指下的新位置

完整代码如下。有什么建议吗

- (void)longPressGestureRecognized:(id)sender {

    UILongPressGestureRecognizer *longPress = (UILongPressGestureRecognizer *)sender;
    UIGestureRecognizerState state = longPress.state;

    CGPoint location = [longPress locationInView:self.collectionView];
    NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:location];

    static UIView       *snapshot = nil;        ///< A snapshot of the row user is moving.
    static NSIndexPath  *sourceIndexPath = nil; ///< Initial index path, where gesture begins.

    switch (state) {
        case UIGestureRecognizerStateBegan: {
            if (indexPath) {

                [self.deleteButton removeFromSuperview];
                self.isDeleteActive = NO;

                sourceIndexPath = indexPath;

                UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];

                // Take a snapshot of the selected row using helper method.
                snapshot = [self customSnapshoFromView:cell];

                // Add the snapshot as subview, centered at cell's center...
                __block CGPoint center = cell.center;
                snapshot.center = center;
                snapshot.alpha = 0.0;
                [self.collectionView addSubview:snapshot];
                [UIView animateWithDuration:0.25 animations:^{

                    // Offset for gesture location.
                    center.x = location.x;
                    snapshot.center = center;
                    snapshot.transform = CGAffineTransformMakeScale(1.05, 1.05);
                    snapshot.alpha = 0.98;
                    cell.alpha = 0.0;

                } completion:^(BOOL finished) {

                cell.hidden = YES;

                }];
            }
            break;
        }

        case UIGestureRecognizerStateChanged: {

            CGPoint center = snapshot.center;
            center.x = location.x;
            snapshot.center = center;

            [self maybeAutoscrollForSnapshot:snapshot];

            // Is destination valid and is it different from source?
            if (indexPath && ![indexPath isEqual:sourceIndexPath]) {

                // ... update data source.
                [self.imageArray exchangeObjectAtIndex:indexPath.row withObjectAtIndex:sourceIndexPath.row];

                // ... move the rows.
                [self.collectionView  moveItemAtIndexPath:sourceIndexPath toIndexPath:indexPath];

                // ... and update source so it is in sync with UI changes.
                sourceIndexPath = indexPath;
            }
            break;
        }

        default: {
            // Clean up.

            if(_autoscrollTimer)
            {
                [_autoscrollTimer invalidate]; _autoscrollTimer = nil;
            }

            UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:sourceIndexPath];
            cell.hidden = NO;
            cell.alpha = 0.0;

            [UIView animateWithDuration:0.25 animations:^{

                snapshot.center = cell.center;
                snapshot.transform = CGAffineTransformIdentity;
                snapshot.alpha = 0.0;
                cell.alpha = 1.0;

            } completion:^(BOOL finished) {

                sourceIndexPath = nil;
                [snapshot removeFromSuperview];
                snapshot = nil;

            }];

            break;
        }
    }
}

- (void)maybeAutoscrollForSnapshot:(UIImageView *)snapshot
{
    _autoscrollDistance = 0;

    if (CGRectGetMaxX(snapshot.frame) < self.collectionView.collectionViewLayout.collectionViewContentSize.width)
    {
        // only autoscroll if the content is larger than the view
        if (self.collectionView.collectionViewLayout.collectionViewContentSize.width > self.view.frame.size.width)
        {
            float distanceFromTop = snapshot.center.x - CGRectGetMinX(self.collectionView.bounds);
            float distanceFromBottom = CGRectGetMaxX(self.collectionView.bounds) - snapshot.center.x;

            //NSLog(@"dist from left %f", distanceFromTop);

            if (distanceFromTop < kAutoScrollingThreshold) {
                _autoscrollDistance = [self autoscrollDistanceForProximityToEdge:distanceFromTop] * -1; // if scrolling up distance is negative
                //NSLog(@"left dist %f", _autoscrollDistance);
            } else if (distanceFromBottom < kAutoScrollingThreshold) {
                _autoscrollDistance = [self autoscrollDistanceForProximityToEdge:distanceFromBottom];
                //NSLog(@"right dist %f", _autoscrollDistance);
            }
        }
    }

    // if no autoscrolling, stop and clear timer
    if (_autoscrollDistance == 0) {
        [_autoscrollTimer invalidate];
        _autoscrollTimer = nil;
    }
    // otherwise create and start timer (if we don't already have a timer going)
    else if (_autoscrollTimer == nil) {
        _autoscrollTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / 60.0)
                                                            target:self
                                                          selector:@selector(autoscrollTimerFired:)
                                                          userInfo:snapshot
                                                           repeats:YES];
    }
}

- (float)autoscrollDistanceForProximityToEdge:(float)proximity {
    // the scroll distance grows as the proximity to the edge decreases, so that moving the thumb
    // further over results in faster scrolling.
    return ceilf((kAutoScrollingThreshold - proximity) / 5.0);
}

- (void)legalizeAutoscrollDistance {
    // makes sure the autoscroll distance won't result in scrolling past the content of the scroll view
    float minimumLegalDistance = (self.collectionView.contentOffset.x + self.collectionView.contentInset.left) * -1;

    float maximumLegalDistance = self.collectionView.collectionViewLayout.collectionViewContentSize.width - (self.view.frame.size.width + self.collectionView.contentOffset.x);

    //NSLog(@"min dist %f", minimumLegalDistance);
    //NSLog(@"max dist %f", maximumLegalDistance);


    _autoscrollDistance = MAX(_autoscrollDistance, minimumLegalDistance);
    _autoscrollDistance = MIN(_autoscrollDistance, maximumLegalDistance);

    //NSLog(@"autoscroll distance %f", _autoscrollDistance);
}

- (void)autoscrollTimerFired:(NSTimer*)timer {

    //    NSLog(@"autoscrolling: %.2f",_autoscrollDistance);
    [self legalizeAutoscrollDistance];
    // autoscroll by changing content offset
    CGPoint contentOffset = [self.collectionView contentOffset];
    contentOffset.x += _autoscrollDistance;

    //NSLog(@"%f",contentOffset.x);

    [self.collectionView setContentOffset:contentOffset];

    // adjust thumb position so it appears to stay still
    UIImageView *snapshot = (UIImageView *)[timer userInfo];
    snapshot.center = CGPointMake(snapshot.center.x + _autoscrollDistance, snapshot.center.y);

}
-(void)长按gesture已识别:(id)发件人{
UILongPressGestureRecognizer*longPress=(UILongPressGestureRecognizer*)发送方;
UIgestureRecognitzerState=longPress.state;
CGPoint位置=[longPress位置视图:self.collectionView];
NSIndexPath*indexPath=[self.collectionView indexPathForItemAtPoint:location];
静态UIView*snapshot=nil;//<行用户的快照正在移动。
静态nsindepath*sourceindepath=nil;//<初始索引路径,手势从这里开始。
开关(状态){
案例UIgestureRecognitzerStateStart:{
if(indexath){
[self.delete按钮从SuperView中移除];
self.isdeletictive=否;
sourceindepath=indepath;
UICollectionViewCell*cell=[self.collectionView cellForItemAtIndexPath:indexPath];
//使用helper方法拍摄所选行的快照。
快照=[self-customSnapshoFromView:cell];
//将快照添加为子视图,以单元格的中心为中心。。。
__块CGPoint center=cell.center;
snapshot.center=中心;
snapshot.alpha=0.0;
[self.collectionView addSubview:snapshot];
[UIView animateWithDuration:0.25动画:^{
//手势位置的偏移量。
中心.x=位置.x;
snapshot.center=中心;
snapshot.transform=CGAffineTransformMakeScale(1.05,1.05);
snapshot.alpha=0.98;
cell.alpha=0.0;
}完成:^(布尔完成){
cell.hidden=是;
}];
}
打破
}
案例UIgestureRecognitzerStateChanged:{
CGPoint center=snapshot.center;
中心.x=位置.x;
snapshot.center=中心;
[自拍照:快照];
//目的地有效吗?它与来源不同吗?
if(indepath&![indepath isEqual:sourceindepath]){
//…更新数据源。
[self.imageArray exchangeObjectAtIndex:indexPath.row with ObjectAtIndex:sourceIndexPath.row];
//…移动行。
[self.collectionView moveItemAtIndexPath:sourceIndexPath到indexPath:indexPath];
//…并更新源,使其与UI更改同步。
sourceindepath=indepath;
}
打破
}
默认值:{
//清理一下。
如果(_autoscrollTimer)
{
[_autoscrolltimerinvalidate];_autoscrollTimer=nil;
}
UICollectionViewCell*cell=[self.collectionView cellForItemAtIndexPath:sourceIndexPath];
cell.hidden=否;
cell.alpha=0.0;
[UIView animateWithDuration:0.25动画:^{
snapshot.center=cell.center;
snapshot.transform=CGAffineTransformity;
snapshot.alpha=0.0;
cell.alpha=1.0;
}完成:^(布尔完成){
sourceIndexPath=nil;
[snapshot removeFromSuperview];
快照=零;
}];
打破
}
}
}
-(无效)maybeAutoscrollForSnapshot:(UIImageView*)快照
{
_autoscrollDistance=0;
if(CGRectGetMaxX(snapshot.frame)self.view.frame.size.width)
{
float distance fromtop=snapshot.center.x-CGRectGetMinX(self.collectionView.bounds);
float distance frombottom=CGRectGetMaxX(self.collectionView.bounds)-snapshot.center.x;
//NSLog(@“距离左侧%f”,距离顶部);
if(距顶部的距离