indexPathForItemAtPoint偶尔返回nil

时间:2015-03-29 18:36:43

标签: ios objective-c uibutton uicollectionview nsindexpath

在我的应用中,我有一个UICollectionView,可以在我的应用中充当滚动颜色选择器。我有一个非常罕见的错误,一旦在蓝色的月亮,按钮按下时颜色将被设置为滚动条中的第一个值,而不是与用户实际触摸的按钮相关联的颜色。

我将此信息隔离到indexPathForItemAtPoint返回nil按钮按下。

现在我只是在返回的索引路径为nil时返回来解决问题,但是,我担心这种行为仍然不正确有几个原因;

  1. 首先,我查看了调试器中的触摸位置,它在集合视图的范围内有效。
  2. 其次,当集合中的某个按钮发生事件UIControlEventTouchUpInside时,会发生获取与按钮关联的颜色的触发器。因此,对我来说没有意义的是,代码将被调用而不是按钮内的触摸。在这种情况下,我已经交换了我当前的错误颜色,因为一个按钮几乎不会响应的错误。
  3. 我做了一些搜索,除非我错过了,我在这个网站上看到的只是代码有一个实现错误并且总是接收nil的情况,但没有什么比这更好。

    我希望有人能够帮助我找出原因,以便我可以解决它或至少理解问题发生的原因。

    相关功能如下:

    - (IBAction)myClickEvent:(id)sender event:(id)event
    {
        NSSet *touches = [event allTouches];
    
        UITouch *touch = [touches anyObject];
    
        CGPoint currentTouchPosition = [touch locationInView: self.collectionViewColors];
    
        NSIndexPath *indexPath = [self.collectionViewColors indexPathForItemAtPoint: currentTouchPosition];
    
        if(!indexPath)return;
    
        appState.currentColor = appState.colors[indexPath.row];
    
        const CGFloat *components = CGColorGetComponents(appState.currentColor.CGColor);
    
        self.redSlider.value = components[0];
        self.greenSlider.value = components[1];
        self.blueSlider.value = components[2];
    
        appState.setBackgroundImagePreview(nil);
    }
    

    设置按钮事件的初始化函数:

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *identifier = @"Cell";
    
        UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
    
        UIButton *myButton = (UIButton *)[cell viewWithTag:100];
    
        [myButton  addTarget:self action:@selector(myClickEvent:event:) forControlEvents:UIControlEventTouchUpInside];
    
        /// abridged 
    
        [myButton setBackgroundImage:colorSquare forState:UIControlStateNormal];
    
        return cell;
    }
    

    谢谢!

    编辑:我尝试了下面的操作,认为Apple可能会出于某种原因在按钮外发送多点触控/触摸。没有骰子。它有时仍返回nil索引路径。

     NSSet *touches = [event touchesForView:sender];
    

1 个答案:

答案 0 :(得分:3)

如果" no item was found at the specified point"

indexPathForItemAtPoint:会返回nil当点落在单元格之间的间距时,最常见的情况。有3个流布局属性通常用于影响单元格的间距:

  • minimumLineSpacing
  • minimumInteritemSpacing
  • sectionInset

获得nil索引路径然后询问其行时,它始终为0,因此appState.colors[indexPath.row]为您提供阵列中的第一种颜色。

解决此问题的一种方法是循环遍历indexPathsForVisibleItems中的所有单元格,并确定哪一个包含中心点(如果有)或最接近它。最简单的方法是使用 - layoutAttributesForItemAtIndexPath:CGRectContainsPoint()和一些简单的数学运算。

如果您获得return路径并且不采取任何措施,那么您的应用只需nil就可以了。