仅使用 shouldSelectItemAt indexPath 函数选择特定单元格

Posted

技术标签:

【中文标题】仅使用 shouldSelectItemAt indexPath 函数选择特定单元格【英文标题】:Let only select specific cells with shouldSelectItemAt indexPath function 【发布时间】:2018-10-24 11:38:13 【问题描述】:

我希望一次只能选择四个特定单元格。当按下按钮时,我希望可选择的单元格是 4 indexPath.row 低。

示例:一开始,indexPath.row 44-47 是可选的。如果按下我想要的按钮,indexPath.row 40-43 是可选的,依此类推。

我想过用 indexPath 创建一个数组,如果按下按钮,数组中的数字会低 4 个数字。

我不知道,如何将它添加到shouldSelectItemAt indexPath 函数中。

我怎样才能意识到这一点?

【问题讨论】:

您是否将选定的索引(例如 44-47)保存在 Int 数组中? 这是我的想法 :) 如果您只使用一个部分,那么使用(NS)(Mutable)IndexSet 怎么样。将“允许”或“禁用”(我不知道你想要哪个)添加为可选择/不可选择。 @Larme 那是什么?我对这个主题很陌生,所以我不知道解决问题的许多不同方法 一个疑问:你提到了indexPath.rowshouldSelectItemAtrow 用于 UITableViewitem 用于 UICollectionView),shouldSelectItemAt 用于 UICollectionView。你用的是哪一个? 【参考方案1】:

您可以使用IndexSet。

var allowedSelectionRow: IndexSet
allowedSelectionRow.insert(integersIn: 44...47) //Initial allowed selection rows

collectionView(_:shouldSelectItemAt:)

return allowedSelectionRow.contains(indexPath.row) //or indexPath.item

随时随地:

allowedSelectionRow.remove(integersIn: 44...47) //Remove indices from 44 to 47
allowedSelectionRow.insert(integersIn: 40...43) //Add indices from 40 to 43

数组的优势:与集合一样,值具有唯一性(无重复)。仅包含整数,您可以添加有用的“范围”(不是添加所有索引,而是添加范围)。

在cmets之后,如果你只允许连续4行,你可以有那个方法:

func updateAllowedSectionSet(lowerBound: Int)  
    let newRange = lowerBound...(lowerBound+3)
    allowedSectionRow.removeAll() //Call remove(integersIn:) in case for instance that you want always the 1 row to be selectable for instance
    allowedSectionRow.insert(integersIn: newRange) 

对于第一个,您只需要执行以下操作: updateAllowedSectionSet(lowerBound: 44) 而不是 allowedSelectionRow.insert(integersIn: 44...47)

【讨论】:

谢谢你!只要我希望它起作用,它就起作用了。一个小问题:是否可以通过删除和插入来自动化该过程?例如。第一个数字总是小 4,最后一个数字也是如此?? 您可以为此创建一个函数:func update(withLowerBound: Int),当您只给出下限时:它会进行删除(请注意,您可以使用 removeAll() 而不是在特定索引处删除),它从下限创建范围,并在该范围内插入。 func updateAllowedSectionSet(lowerBound: Int) let newRange = lowerBound...(lowerBound+3); allowedSectionRow.removeAll(); allowedSectionRow.insert(integersIn: newRange) ,或类似的东西(没有检查边界)。所以你做self.updateAllowedSectionSet(lowerBound: 44)(第一个)。注意:您可以将整个allowedSelectionRow 完全替换为新的。我之前建议过remove(),因为您可能希望始终保持第一行可选(或类似的东西)。 完美 :D 世界需要更多像你这样的英雄 :D【参考方案2】:

让我们考虑项目形成一个字符串数组,并且您将选定的索引作为一个范围来跟踪。

var selectedRange: Range<Int>? 
    didSet 
        collectionView.reloadData()
    


var items: [String] = [] 
    didSet 
        // To make sure that the selected indices are reset everytime this array is modified,
        // so as to make sure that nothing else breaks
        if items.count >= 4 
            // Select the last 4 items by default
            selectedRange = (items.count - 4)..<items.count
         else if !items.isEmpty 
            selectedRange = 0..<items.count
         else 
            selectedRange = nil
        
    

然后,当你按下按钮来减少范围时,你可以使用这个逻辑来处理同样的事情:

func decrementRange() 
    if var startIndex = selectedRange?.startIndex,
        var endIndex = selectedRange?.endIndex 

        startIndex = max((startIndex - 4), 0)
        endIndex = min(max((startIndex + 4), (endIndex - 4)), items.count)

        selectedRange = startIndex..<endIndex
    

然后,您可以使用以下方法确定选择是否在活动范围内完成:

func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool 

    if let selectedRange = selectedRange 
        return selectedRange.contains(indexPath.item)
    
    return false

注意:我建议您在尝试生产代码之前验证这是否涵盖所有极端情况。

【讨论】:

以上是关于仅使用 shouldSelectItemAt indexPath 函数选择特定单元格的主要内容,如果未能解决你的问题,请参考以下文章

仅使用具有“in”子句中所有值的列加入查询

如何使用 FormatMessage c++ 获取仅英文消息

使用 Spark 执行“WHERE IN”子句,如何仅重新训练第一个数据集的列?

使用 put in for 循环以表格格式打印名称,但仅正确打印姓氏

inotify IN_CLOSE_WRITE 仅检测复制到目录的文件

对于手动编辑的文件,inotify IN_CLOSE_WRITE 仅触发一次