在按钮点击上仅将子视图添加到一个UICollectionViewCell

时间:2015-02-21 23:14:48

标签: ios swift uicollectionview uicollectionviewcell subview

每个UICollectionViewCell都有自己的按钮,连接到以下操作:

@IBAction func dropDown(sender:UIButton){

    var pt = sender.bounds.origin
    var ptCoords : CGPoint = sender.convertPoint(pt, toView:sender.superview);
    var ptCoords2 : CGPoint = sender.convertPoint( ptCoords, toView: collectionView!);
    var cellIndex: NSIndexPath = self.collectionView!.indexPathForItemAtPoint(ptCoords2)!
    //var i : NSInteger = cellIndex.row;
    //var i2 : NSInteger  = cellIndex.section;
    var selectedCell = collectionView?.cellForItemAtIndexPath(cellIndex) as CollectionViewCell!
    selectedCell.button.backgroundColor = UIColor.blackColor()

    for (var i = 0; i < 3; i++){
        var textView : UITextView! = UITextView(frame: CGRectMake(self.view.frame.size.width - self.view.frame.size.width/1.3, CGFloat(50 + (30*(i+1))), CGRectGetWidth(self.view.frame), CGFloat(25)))
            textView.backgroundColor = UIColor.whiteColor()
            selectedCell.contentView.addSubview(textView)
    }
}

我想要做的是只将3个子视图添加到已被点击的单元格中。子视图已成功添加,但只要我滚动,进入视图的单元格&amp;对应于先前设置的indexPath加载了3个子视图。我认为这是由于dequeueReusableCellWithReuseIdentifier方法,但我无法找到解决方法。我考虑删除scrollViewDidScroll上的子视图,但理想情况下我希望将视图保留在其父级单元格中,直到再次点击该按钮。

修改 好吧,我放弃了整个convertPoint方法,现在根据按钮标记获取单元格索引:

    var selectedCellIndex : NSIndexPath = NSIndexPath(forRow: cell.button.tag, inSection: 0)
    var selectedCell = collectionView?.cellForItemAtIndexPath(selectedCellIndex) as CollectionViewCell!

无论如何,当我尝试仅将子视图添加到所选索引处的单元格时,子视图会重复。

修改: 我创建了一个带有键值的字典来跟踪每个单元格的状态,如下所示:

var cellStates = [NSIndexPath: Bool]()
for(var i = 0; i < cellImages.count; i++){
    cellStates[NSIndexPath(forRow: i, inSection: 0)] = false
}

cellStates[selectedCellIndex] = true函数中的dropDown设置。然后在cellForItemAtIndexPath函数中,我执行以下检查:

if(selectedIndex == indexPath && cellStates[indexPath] == true){

    for (var i = 0; i < 3; i++){
         var textView : UITextView! = UITextView(frame: CGRectMake(cell.frame.size.width - cell.frame.size.width/1.3, CGFloat(50 + (30 * (i+1))), CGRectGetWidth(cell.frame), CGFloat(25)))
         textView.backgroundColor = UIColor.whiteColor()
         cell.contentView.addSubview(textView)
         println("display subviews")
         println(indexPath)
    }
 } else {
     println("do not display subviews")
     println(indexPath)
 }

return cell

其中selectedIndex,通过NSIndexPath函数设置的活动单元格的dropDown与正在创建的单元格的indexPath进行比较。 cellState已检查true

仍然没有运气 - 子视图仍显示在回收的单元格上。我应该提一下&#34;显示子视图&#34;和&#34;不显示子视图&#34;正在滚动时正确记录,因此正在成功评估条件语句。

我(......哈哈......)解决方案! 可能会破坏一堆最佳编码实践,但我为所有创建的子视图分配了标记,在cellForItemAtIndexPath方法的开头删除它们,如果cellState条件返回{{1},则再次创建它们}。

2 个答案:

答案 0 :(得分:1)

没问题。基本上,您需要将程序状态存储在您的UI组件中,通常称为“模型”。不知道你的应用程序是什么,所以我打算做一个例子。假设您要显示一个网格,其中每个单元格最初为绿色,并在用户点击它时切换为红色。您需要在某个二维数组中存储状态(即,是否已经敲过单元格),这将包含所有单元格的布尔值,而不仅仅是当前显示的布尔值(假设您已经足够单元格使网格滚动)。当用户点击一个单元格时,您可以在相应的数组元素中设置该标志。然后,当iOS回调提供一个单元格(在dequeue方法中)时,检查数组中的状态,将适当的颜色应用于单元格的UIView,然后返回它。这样,iOS可以重用单元格视图对象以提高效率,同时您可以动态地将模型状态应用于相应的单元格。如果这清楚,请告诉我。

答案 1 :(得分:0)

两件事之一: - 禁止合并细胞。 - 在您的模式下保持足够的信息,以便能够根据模型而不是在屏幕上的位置绘制单元格。也就是说,在您的模型中存储一点,确定是否为每个&#34;逻辑&#34;显示三个视图。细胞。然后,当要求将单元格出列时,检查其模型并动态添加/删除背景。