仅允许 select 个具有 shouldSelectItemAt indexPath 函数的特定单元格
Let only select specific cells with shouldSelectItemAt indexPath function
我希望一次只能选择四个特定的单元格。按下按钮时,我希望可选单元格低 4 indexPath.row
。
例子:一开始,indexPath.row
44-47是可选的。如果我想要按下按钮,那么 indexPath.row
40-43 是可选的,依此类推。
我想过用 indexPath 创建一个数组,如果按下按钮,数组中的数字会低 4 个数字。
我不知道如何将它添加到 shouldSelectItemAt indexPath
函数中。
我如何实现这一点?
您可以使用 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
数组的优点:与集合一样,值的唯一性(无重复)。仅包含整数,您可以添加 "range" 这很有用(不是添加所有索引,而是添加一个范围)。
注释后,如果你只允许连续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)
让我们假设这些项目形成一个字符串数组,并且您将跟踪选定的索引作为一个范围。
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
}
注意:我建议您在尝试生产代码之前验证这是否涵盖所有极端情况。
我希望一次只能选择四个特定的单元格。按下按钮时,我希望可选单元格低 4 indexPath.row
。
例子:一开始,indexPath.row
44-47是可选的。如果我想要按下按钮,那么 indexPath.row
40-43 是可选的,依此类推。
我想过用 indexPath 创建一个数组,如果按下按钮,数组中的数字会低 4 个数字。
我不知道如何将它添加到 shouldSelectItemAt indexPath
函数中。
我如何实现这一点?
您可以使用 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
数组的优点:与集合一样,值的唯一性(无重复)。仅包含整数,您可以添加 "range" 这很有用(不是添加所有索引,而是添加一个范围)。
注释后,如果你只允许连续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)
让我们假设这些项目形成一个字符串数组,并且您将跟踪选定的索引作为一个范围。
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
}
注意:我建议您在尝试生产代码之前验证这是否涵盖所有极端情况。