【问题标题】:Adding subviews to only one UICollectionViewCell on button tap在按钮点击时仅将子视图添加到一个 UICollectionViewCell
【发布时间】:2015-02-21 23:14:48
【问题描述】:

每个 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 个子视图。子视图已成功添加,但一旦我滚动,进入视图并对应于先前设置的 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] = truedropDown 函数中设置。然后在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,通过dropDown 函数设置的活动单元格的NSIndexPath 与正在创建的单元格的indexPath 进行比较,并检查cellState 中的true

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

我的(...hack of a...)解决方案! 可能破坏了一堆最佳编码实践,但我为所有创建的子视图分配了标签,在 cellForItemAtIndexPath 方法的开头删除它们,如果cellState 条件返回true,则重新创建它们。

【问题讨论】:

    标签: ios swift uicollectionview uicollectionviewcell subview


    【解决方案1】:

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

    【讨论】:

    • 你能看看我的编辑,如果我做了你想做的事,请告诉我?它仍然不起作用,但我不知道为什么。
    • 感谢您的启发。不确定我所做的是否是您的想法,但现在可以了,非常感谢!
    【解决方案2】:

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

    【讨论】:

    • 啊,我希望我能更好地理解你的意思——我对这些东西真的很陌生。你有没有机会对此进行扩展和简化?您的意思是为每个单元格创建标志并根据标志是真/假来显示视图吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多