UICollectionViewselect并取消select问题
所以我有一个主要的对象,有许多图像相关联。 一个图像也是一个对象。
假设你有一个集合视图控制器,并且在你拥有的控制器中
cellForItemAtIndexPath
以及基于主要的对象,如果它有与之相关的当前图像,我想设置为true。 但是我希望用户能够在任何时候“取消”当前单元格以取消与主要对象的关联。
我发现如果你设置“select为真” – 如果主要对象和cellForItemAtIndexPath
图像之间有关系,取消select不再是一个选项。
在
didDeselectItemAtIndexPath
和
didSelectItemAtIndexPath
我testing一个日志,看看他们是否被称为。 如果一个单元格被设置为选中 – 下一个被调用,但如果我从来没有设置单元格在cellForItemAtIndexPath
中select我可以select和取消select所有我想要的。
这是集合视图应该工作的预期方式吗? 我阅读文档,似乎没有谈到这是如此。 我解释文档意味着它工作的表格视图单元格的方式。 有一些明显的变化
这也显示控制器设置正确,并使用适当的代表方法….嗯
我有同样的问题,即。 在[UICollectionView collectionView:cellForItemAtIndexPath:]
设置cell.selected = YES
,则不能通过点击取消select该单元格。
现在的解决scheme:我在[UICollectionView collectionView:cellForItemAtIndexPath:]
同时调用了 [UICollectionViewCell setSelected:]
和[UICollectionView selectItemAtIndexPath:animated:scrollPosition:]
[UICollectionView collectionView:cellForItemAtIndexPath:]
。
你的Cell类中有一个自定义的setSelected
方法吗? 你在那个方法中调用[super setSelected:selected]
?
我有一个神秘的问题,我正在使用多个select,一旦选中它,我就无法取消select单元格。 调用超级方法解决了这个问题。
我有一个UICollectionView
取消select问题,我发现我不允许在collectionView上的多个select。 所以当我testing的时候,我总是试着在同一个单元格上,如果单个select是ON,你就不能取消已经select的单元格。
我不得不补充:
myCollectionView.allowsMultipleSelection = YES;
这是有点老,但是,因为我遇到同样的问题,使用迅速我会加我的答案。 使用时:
collectionView.selectItemAtIndexPath(indexPath, animated: true, scrollPosition: [])
细胞根本没有被选中。 但是使用时:
cell.selected = true
它确实被选中,但我无法再select/取消select该单元格。
我的解决scheme(使用两种方法):
cell.selected = true collectionView.selectItemAtIndexPath(indexPath, animated: true, scrollPosition: .None)
当这两个方法被调用时:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
它完美的工作!
这是我对Swift 2.0的回答。
我能够在viewDidLoad()中设置以下内容
collectionView.allowsMultipleSelection = true;
然后我实现了这些方法
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { let cell = collectionView.cellForItemAtIndexPath(indexPath) as! MyCell cell.toggleSelected() } func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) { let cell = collectionView.cellForItemAtIndexPath(indexPath) as! MyCell cell.toggleSelected() }
最后
class MyCell : UICollectionViewCell { .... func toggleSelected () { if (selected){ backgroundColor = UIColor.orangeColor() }else { backgroundColor = UIColor.whiteColor() } } }
我不知道为什么UICollectionView
是如此混乱像UITableViewController
相比…我发现了一些事情。
setSelected:
被多次调用的原因是因为序列方法被调用。 该序列与UITextFieldDelegate
方法非常相似。
方法collectionView:shouldSelectItemAtIndexPath:
在collectionView
实际select单元之前被调用,因为它实际上是在询问“它应该被选中”吗?
collectionView:didSelectItemAtIndexPath:
实际上是在collectionView
select单元格之后调用的。 因此,名称“确实select”。
所以这就是你的情况(和我的情况),我不得不在这个问题上花费几个小时。
用户再次触摸所选单元格以取消select。 shouldSelectItemAtIndexPath:
调用shouldSelectItemAtIndexPath:
来检查是否应该select单元格。 collectionView
select单元格,然后调用didSelectItemAtIndexPath
。 无论你在这一点做什么是在单元格的selected
属性设置为YES
。 这就是为什么像cell.selected = !cell.selected
不会工作。
TL; DR – 让你的collectionView
取消select委托方法中的单元格collectionView:shouldSelectItemAtIndexPath:
通过调用deselectItemAtIndexPath:animated:
并返回NO
。
我做了一个简短的例子:
- (BOOL)collectionView:(OPTXListView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath { NSArray *selectedItemIndexPaths = [collectionView indexPathsForSelectedItems]; if ([selectedItemIndexPaths count]) { NSIndexPath *selectedIndexPath = selectedItemIndexPaths[0]; if ([selectedIndexPath isEqual:indexPath]) { [collectionView deselectItemAtIndexPath:indexPath animated:YES]; return NO; } else { [collectionView selectItemAtIndexPath:indexPath animated:YES scrollPosition:UICollectionViewScrollPositionCenteredHorizontally]; return YES; } } else { [collectionView selectItemAtIndexPath:indexPath animated:YES scrollPosition:UICollectionViewScrollPositionCenteredHorizontally]; return YES; } }
生活在iOS 9的时代,有很多事情要检查这里。
- 检查你有没有
collectionView.allowsSelection
设置为YES
- 检查你有没有
collectionView.allowsMultipleSelection
设置为YES
(如果你需要这种能力)
现在来粉丝部分。 如果你听苹果,并设置cell.contentView
而不是cell
本身,那么你已经隐藏其selectedBackgroundView
永远不可见。 因为:
(lldb) po cell.selectedBackgroundView <UIView: 0x7fd2dae26bb0; frame = (0 0; 64 49.5); autoresize = W+H; layer = <CALayer: 0x7fd2dae26d20>> (lldb) po cell.contentView <UIView: 0x7fd2dae22690; frame = (0 0; 64 49.5); gestureRecognizers = <NSArray: 0x7fd2dae26500>; layer = <CALayer: 0x7fd2dae1aca0>> (lldb) pviews cell <MyCell: 0x7fd2dae1aa70; baseClass = UICollectionViewCell; frame = (0 0; 64 49.5); clipsToBounds = YES; hidden = YES; opaque = NO; layer = <CALayer: 0x7fd2dae1ac80>> | <UIView: 0x7fd2dae26bb0; frame = (0 0; 64 49.5); autoresize = W+H; layer = <CALayer: 0x7fd2dae26d20>> | <UIView: 0x7fd2dae22690; frame = (0 0; 64 49.5); gestureRecognizers = <NSArray: 0x7fd2dae26500>; layer = <CALayer: 0x7fd2dae1aca0>> | | <UIView: 0x7fd2dae24a60; frame = (0 0; 64 49.5); clipsToBounds = YES; alpha = 0; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x7fd2dae1acc0>> | | <UILabel: 0x7fd2dae24bd0; frame = (0 0; 64 17.5); text = '1'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fd2dae240c0>> | | <UILabel: 0x7fd2dae25030; frame = (0 21.5; 64 24); text = '1,04'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fd2dae25240>> (lldb) po cell.contentView.backgroundColor UIDeviceRGBColorSpace 0.4 0.4 0.4 1
所以,如果你想使用selectedBackgroundView(这是打开/closures与cell.selected
和selectItemAtIndexPath...
)然后执行此操作:
cell.backgroundColor = SOME_COLOR; cell.contentView.backgroundColor = [UIColor clearColor];
它应该工作得很好。
我不知道我理解这个问题,但是选定的状态是为每个单元格设置的,并且会包含单元格内的所有子视图。 你不能解释你的意思是“一个主要的物体有许多与之相关的图像”。 关联在子视图? 或者你是什么意思?
这听起来像是一个devise问题。 也许你需要一个包含你需要的任何关联对象的UIView子类; 该子类可以被设置为内容视图。 我这样做,例如,我有一个图像,描述和与图像有关的录音。 所有都在子类中定义,然后每个这些子类成为单个单元格的内容视图。
我也使用了一种安排来将图像关联到包含它们的文件夹。 在这个设置下,文件夹和图像每个都有一个子类,可以将其中一个作为内容视图附加到一个单元格中(作为一个单独的实体存储在核心数据中)。
也许你可以进一步解释你的问题?
你看过吗:
- (BOOL)collectionView:(PSTCollectionView *)collectionView shouldDeselectItemAtIndexPath:(NSIndexPath *)indexPath;
请更清楚地说明你的问题,也许我们可以把它弄清楚。 我刚刚花了一些时间与UICollectionView。
我认为你的问题可能是由于混淆,如果你设置cell.selected = YES
编程,原因didSelectItemAtIndexPath:
没有得到调用是因为只有当collectionView本身负责细胞的select(例如通过一个TAP)。
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { let cell = collectionView.cellForItemAtIndexPath(indexPath) if cell?.selected == true{ cell?.layer.borderWidth = 4.0 cell?.layer.borderColor = UIColor.greenColor().CGColor } }func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) { let cell = collectionView.cellForItemAtIndexPath(indexPath) if cell?.selected == false{ cell?.layer.borderColor = UIColor.clearColor().CGColor } }
我find简单的解决scheme
我正在使用自定义单元格子类,对于我来说,我只需要在子类中的prepareForReuse()
中设置self.selected = false
。
单元格select和取消select最好通过设置一个backgroundView和一个选定的背景视图来处理。 我build议确保在layoutSubviews方法中正确设置这两个视图的框架(如果您通过IB设置选定视图和背景视图)。
不要忘了设置你的contentView的(如果你有一个)背景颜色清除,以便正确的背景视图显示。
不要直接设置单元格的select(即通过cell.selected = YES),在集合视图中使用为此devise的方法。 文件中有清楚的解释,尽pipe我会同意这些指南中的信息有些分散。
你不应该直接在你的collectionView数据源中捅入单元格的背景颜色。
另外,最后要注意的是,如果你在你的单元的类中实现了这些,不要忘记调用[super prepareForReuse]和[super setSelected:selected],因为你可能会阻止单元的超类进行单元select。
打我,如果你需要进一步澄清这个问题。
在[UICollectionView collectionView:cellForItemAtIndexPath:]
中同时调用[UICollectionViewCell setSelected:]
和[UICollectionView selectItemAtIndexPath:animated:scrollPosition:]
不起作用,请尝试在dispatch_async(dispatch_get_main_queue(), ^{});
调用它们dispatch_async(dispatch_get_main_queue(), ^{});
块。
这就是最终为我解决的问题。