在collectionView上使用indexPathForItemAtPoint和转换后的单元格

时间:2014-05-21 13:53:03

标签: ios objective-c

在转换属性以将单元格旋转一定角度后,我遇到了抓取集合视图单元格的indexPaths的问题。我理解添加转换实际上并没有改变帧 - 这就是为什么我假设indexPathForItemAtPoint / cellForItemAtIndexPath返回错误的索引/单元格。

基本上我有一个UIView在屏幕的某些点悬停,我想选择它悬停的单元格。但由于变换不影响帧 - 计算结束。我正在寻找一种创造性的方法来解决这个问题。

使用CollectionViewDelegate的didSelectRowAtIndex效果出奇的好,但不幸的是它在同步这个在屏幕上盘旋的视图时不是很有用(会使运动起伏不定)。

我的布局代码非常类似于去年WWDC上的Apple的CircleLayout代码,并添加了该转换 -

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)path
{
    UICollectionViewLayoutAttributes* attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:path];
    attributes.size = CGSizeMake(ITEM_SIZE, ITEM_SIZE);

    attributes.center = CGPointMake(_center.x +_radius * cosf(2 * path.item * M_PI / _cellCount + M_PI / 2),
                                    _center.y + _radius * sinf(2 * path.item * M_PI/ _cellCount + M_PI / 2));

    //Rotate the item the correct amount
    attributes.transform = CGAffineTransformMakeRotation(SOME_RADIAN);
    return attributes;
}

1 个答案:

答案 0 :(得分:2)

假设每个单元格的旋转相同,那么您可以在正方形(矩形)之外进行思考,并将悬停的UIView视为处于备用坐标系中,然后在尝试之前将逆变换应用于其框架。 indexPathForItemAtPoint和cellForItemAtIndexPath:

CGAffineTransform inverseAffine = CGAffineTransformMakeRotation(-SOME_RADIAN);
//  use the inverse to move the hover UIView into the original coordinate space
CGRect hoverInOriginalSpace = CGRectApplyAffineTransform(hoverView.frame, inverseAffine);
CGPoint midpoint = CGPointMake(CGRectGetMidX(hoverInOriginalSpace), CGRectGetMidY(hoverInOriginalSpace));
NSIndexPath *path = [collectionView indexPathForItemAtPoint:midPoint];
...

<强>更新:

如果旋转不是常数(例如,如果它取决于单元格的索引),那么您需要进行扫描:

- (UICollectionViewCell *)findCellUnderHover:(UICollectionView *)collectionView hover:(UIView *)hoverView {
    NSArray *visibleCellIndexPaths = [collectionView indexPathsForVisibleItems];
    for (NSIndexPath *path in visibleCellIndexPaths) {
        UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:path];
        CGFloat rotationForCell = ...;
        CGAffineTransform inverseAffine = CGAffineTransformMakeRotation(-rotationForCell);
        //  use the inverse to move the hover UIView into the original coordinate space specific to this cell
        CGRect hoverInOriginalSpaceForCell = CGRectApplyAffineTransform(hoverView.frame, inverseAffine);
        CGPoint midpoint = CGPointMake(CGRectGetMidX(hoverInOriginalSpaceForCell), CGRectGetMidY(hoverInOriginalSpaceForCell));
        if (CGRectContainsPoint(cell.frame, midpoint))
            return cell;
    }
    return nil;
}
相关问题