如何在所有单元格周围的空白区域中接收UICollectionView上的触摸

时间:2014-07-11 16:00:38

标签: ios objective-c swift uicollectionview uigesturerecognizer

我有UICollectionView,其中包含不同的项目。当我点击某个项目时,我会使用:

 -(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath

找出触摸的内容然后基本上将该视图的alpha设置为0以隐藏它。一切正常。现在我想要做的是当你点击所有UICollectionViewCell所有视图周围的空白区域时,然后再次出现。我无法找到一种方法,可以让我知道细胞周围的白色空间何时被触摸。有没有一个好方法呢?我尝试过设置手势识别器,但是当我这样做时,我的方法

 -(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath

未被调用。有没有办法实现手势识别器,并从那里确定是否轻敲了一个单元格,如果是这样隐藏该单元格,否则显示所有隐藏的单元格?感谢。

6 个答案:

答案 0 :(得分:19)

我已成功使用UITapGestureRecognizer UICollectionView上的backgroundView来解决此问题。它在Swift中,但这个想法很明确:

self.tapGestureRecognizer = UITapGestureRecognizer(target: self, action: "handleTap:")
self.tapGestureRecognizer.delegate = self

self.collectionView.backgroundView = UIView(frame:self.collectionView.bounds)
self.collectionView.backgroundView!.addGestureRecognizer(tapGestureRecognizer)

回调:

func handleTap(recognizer: UITapGestureRecognizer) {
    // Handle the tap gesture
}

答案 1 :(得分:5)

我在项目中遇到了类似的情况,并通过执行以下操作解决了这个问题:

let tapGestureRecogniser = UITapGestureRecognizer(target: self, action: #selector(handleTapEmptySpaceGesture))
tapGestureRecogniser.delegate = self
collectionView.addGestureRecognizer(tapGestureRecogniser)

实施UIGestureRecognizerDelegate协议

然后在协议中实现以下功能:

func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
    // only handle tapping empty space (i.e. not a cell)
    let point = gestureRecognizer.locationInView(collectionView)
    let indexPath = collectionView.indexPathForItemAtPoint(point)
    return indexPath == nil
}

基本上,如果点击是在单元格上,那么您的手势识别器就不会开始,允许正常选择/取消选择代表运行。否则,如果它在空白区域,则识别器会处理水龙头并运行其处理程序。

答案 2 :(得分:0)

仅当用户选择collectionViewCell时才会调用didSelectItem委托方法。单元格之间的空间可能因每个单元格大小而异,您只能指定最小间距。 要通过更改其zindex来接收touchView作为backgroundView,请为其添加触摸检测。希望这会帮助你。 :)

答案 3 :(得分:0)

这适用于Swift 2.3

步骤1:实施UIGestureRecognizerDelegate协议

第2步:在UICollectionView backgroundView上设置UITapGestureRecognizer

步骤3:处理tapTap函数内部的操作

  let flipAnimation = CABasicAnimation(keyPath: "transform")
        flipAnimation.fromValue = NSValue(caTransform3D: CATransform3DIdentity)
        flipAnimation.toValue = NSValue(caTransform3D: CATransform3DMakeRotation(.pi, 0,1,0))
        flipAnimation.fillMode = kCAFillModeBoth

        self.layer.add(flipAnimation, forKey: "flip")
        self.layer.zPosition = -1000

        CATransaction.commit()

答案 4 :(得分:0)

Swift 4.2的一些“化妆品” :(上述其他作者的致谢.. :))

#define LOOP(n, f)                                            \
    static_assert(n <= 8 && "static loop size should <= 8");  \
    do {                                                      \
        if constexpr (n >= 8)                                 \
            f(std::integral_constant<size_t, n - 8>());       \
        if constexpr (n >= 7)                                 \
            f(std::integral_constant<size_t, n - 7>());       \
        if constexpr (n >= 6)                                 \
            f(std::integral_constant<size_t, n - 6>());       \
        if constexpr (n >= 5)                                 \
            f(std::integral_constant<size_t, n - 5>());       \
        if constexpr (n >= 4)                                 \
            f(std::integral_constant<size_t, n - 4>());       \
        if constexpr (n >= 3)                                 \
            f(std::integral_constant<size_t, n - 3>());       \
        if constexpr (n >= 2)                                 \
            f(std::integral_constant<size_t, n - 2>());       \
        if constexpr (n >= 1)                                 \
            f(std::integral_constant<size_t, n - 1>());       \
    } while (0);

template <typename T> constexpr size_t tupleSize(T&) { return tuple_size_v<T>; }

int main() {
    auto t = std::make_tuple(1, "string", 0.2, 3, 1, 1, 1);
    LOOP(tupleSize(t), [&](auto i) { cout << std::get<i>(t) << endl; });
    return 0;
}

答案 5 :(得分:0)

基于Paul Popiel的回答,但基于目标C

要设置手势识别器,请执行以下操作:

//The setup code (in viewDidLoad in your view controller)
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
                                        action:@selector(handleSingleTap:)];
[self.collectionView addGestureRecognizer:singleFingerTap];

并处理水龙头并识别它是否正在触摸一个单元格或未被单元格覆盖的空间

- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
    CGPoint location = [recognizer locationInView:[recognizer.view superview]];
    NSIndexPath* indexPath = [self.collectionView indexPathForItemAtPoint:location];
    if (!indexPath)
    {
        //Handle your selection of the white space in the collection view here.  Your code may vary.
        [self setSelected:YES];
    } else {
        //Handle selection of individual cell here
        [self collectionView:self.collectionView didSelectItemAtIndexPath:indexPath];
    }
}