如何在集合视图中单个 select 单元格..?
how to single select cell in collection view..?
这些代码可以正常工作,但是当我滚动我的集合视图时,另一个单元格也会 selected,例如有 18 张图像可用,首先在 运行 显示六张当我将 select 任何一个位置然后下一个六位置图像自动 select 的时候。为什么一次有两个单元格 selecting 我在这里感到困惑。请给我解决方案
这里我在主要节目分镜中拍摄了 6 个单元格
UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout*)self.collectionView.collectionViewLayout;
flowLayout.minimumLineSpacing = 15;
CGFloat availableWidthForCells = CGRectGetWidth(self.collectionView.frame) - flowLayout.sectionInset.left - flowLayout.sectionInset.right - flowLayout.minimumInteritemSpacing *2;
cellWidth = availableWidthForCells /6;
NSLog(@"cellWidth:%f",cellWidth);
flowLayout.itemSize = CGSizeMake(cellWidth, cellWidth);
这是我的Didselect和didDeselect方法
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
cell.layer.cornerRadius = cellWidth / 2.0;
cell.layer.backgroundColor = [UIColor blackColor].CGColor;
NSLog(@"INDEXPATH:-%ld",(long)indexPath.row);
}
-(void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
cell.layer.cornerRadius = cellWidth / 2.0;
cell.layer.backgroundColor = [UIColor whiteColor].CGColor;
}
那是因为细胞被重复使用了。当你
UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
改变单元格的角半径,实际上改变了不止一个单元格的角半径。所以你应该这样做:
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("YourCell", forIndexPath: indexPath) as! YourCell
发生这种情况是因为 collectionView 重用了单元格;
您应该将所选单元格的 IndexPath 存储在一个变量中:
ObjC:
@property (nonatomic, retain) NSIndexPath *selectedIndexPath;
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
cell.layer.backgroundColor = [UIColor blackColor].CGColor;
NSLog(@"INDEXPATH:-%ld",(long)indexPath.row);
self.selectedIndexPath = indexPath
}
-(void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
cell.layer.backgroundColor = [UIColor whiteColor].CGColor;
self.selectedIndexPath = nil
}
Swift :
var selectedIndexPath: IndexPath?
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
cell.layer.backgroundColor = UIColor.black
self.selectedIndexPath = indexPath
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
cell.layer.backgroundColor = UIColor.white
self.selectedIndexPath = nil
}
比 "cell for row at indexPath" 检查:
ObjC:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
cell.layer.cornerRadius = cellWidth / 2.0;
if (self.selectedIndexPath != nil && indexPath == self.selectedIndexPath) {
cell.layer.backgroundColor = [UIColor blackColor].CGColor;
else {
cell.layer.backgroundColor = [UIColor whiteColor].CGColor;
}
return cell
}
Swift :
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.cellForItem(at: indexPath)
cell.layer.cornerRadius = cellWidth / 2
if self.selectedIndexPath != nil && indexPath == self.selectedIndexPath {
cell.layer.backgroundColor = UIColor.black
else {
cell.layer.backgroundColor = UIColor.white
}
}
感谢 Alberto Scampini
此代码用于 swift 3.1
var selectedIndexPath: IndexPath?
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "SegmentChoiceCVCell", for: indexPath) as! SegmentChoiceCVCell
//configure cell
if selectedIndexPath != nil && indexPath == selectedIndexPath {
cell.checkIcon.backgroundColor = UIColor.black
}else{
cell.checkIcon.backgroundColor = UIColor.white
}
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath) as! SegmentChoiceCVCell
cell.checkIcon.backgroundColor = UIColor.black
self.selectedIndexPath = indexPath
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let cell: SegmentChoiceCVCell = collectionView.cellForItem(at: indexPath) as! SegmentChoiceCVCell
cell.checkIcon.backgroundColor = white
selectedIndexPath = nil
}
我知道我迟到了。我有同样的问题。在 Whosebug 中环顾四周之后。这是我的解决方案。它可以帮助初学者更容易理解 UICollectionViewCell。
“cellForItemAtIndexPath”方法控制单元格的显示方式。屏幕外的单元格将不会更新。
Swift 4
首先,您需要 class 您的手机。
class SubclassedCell: UICollectionViewCell {
@IBOutlet var cellImage: UIImageView!
@IBOutlet var cellCaption: UILabel!
}
extension SubclassedCell{
func highlightEffect(){
self.layer.borderWidth = 3.0
self.layer.borderColor = UIColor.lightGray.cgColor
}
func removeHighlight(){
self.layer.borderColor = UIColor.clear.cgColor
}
}
现在是“cellForItemAt”方法。
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "blahblahblah", for: indexPath) as! SubclassedCell
cell.cellImage.image = yourImages[indexPath.item]
cell.cellCaption.text = yourImageNames[indexPath.item]
cell.removeHighlight() // Call subclassed cell method.
if indexPath.item == selectedItem {
cell.highlightEffect() // Call subclassed cell method.
preSelected = IndexPath(item: indexPath.item, section: indexPath.section)
}
collecttionRef = collectionView
return cell
}
然后,对于“didSelectItemAt”方法
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath){
collectionView.allowsMultipleSelection = false
if let cell = collectionView.cellForItem(at: indexPath) as! SubclassedCell?{
let indexPathData = NSKeyedArchiver.archivedData(withRootObject: indexPath)
UserDefaults.standard.set(indexPathData,forKey: "backgroundIndexPath")
//I got some unwrapped crash for my App so I have to use UserDefault to fix the unwrapped problem. You could ignore these both lines.
selectedItem = indexPath.item //selectedItem is used in the "cellForItemAt" method above.
collectionView.reloadData() //update all cells. It could be heavy if you have many cells.
}
}
这些代码可以正常工作,但是当我滚动我的集合视图时,另一个单元格也会 selected,例如有 18 张图像可用,首先在 运行 显示六张当我将 select 任何一个位置然后下一个六位置图像自动 select 的时候。为什么一次有两个单元格 selecting 我在这里感到困惑。请给我解决方案
这里我在主要节目分镜中拍摄了 6 个单元格
UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout*)self.collectionView.collectionViewLayout;
flowLayout.minimumLineSpacing = 15;
CGFloat availableWidthForCells = CGRectGetWidth(self.collectionView.frame) - flowLayout.sectionInset.left - flowLayout.sectionInset.right - flowLayout.minimumInteritemSpacing *2;
cellWidth = availableWidthForCells /6;
NSLog(@"cellWidth:%f",cellWidth);
flowLayout.itemSize = CGSizeMake(cellWidth, cellWidth);
这是我的Didselect和didDeselect方法
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
cell.layer.cornerRadius = cellWidth / 2.0;
cell.layer.backgroundColor = [UIColor blackColor].CGColor;
NSLog(@"INDEXPATH:-%ld",(long)indexPath.row);
}
-(void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
cell.layer.cornerRadius = cellWidth / 2.0;
cell.layer.backgroundColor = [UIColor whiteColor].CGColor;
}
那是因为细胞被重复使用了。当你
UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
改变单元格的角半径,实际上改变了不止一个单元格的角半径。所以你应该这样做:
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("YourCell", forIndexPath: indexPath) as! YourCell
发生这种情况是因为 collectionView 重用了单元格;
您应该将所选单元格的 IndexPath 存储在一个变量中:
ObjC:
@property (nonatomic, retain) NSIndexPath *selectedIndexPath;
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
cell.layer.backgroundColor = [UIColor blackColor].CGColor;
NSLog(@"INDEXPATH:-%ld",(long)indexPath.row);
self.selectedIndexPath = indexPath
}
-(void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
cell.layer.backgroundColor = [UIColor whiteColor].CGColor;
self.selectedIndexPath = nil
}
Swift :
var selectedIndexPath: IndexPath?
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
cell.layer.backgroundColor = UIColor.black
self.selectedIndexPath = indexPath
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
cell.layer.backgroundColor = UIColor.white
self.selectedIndexPath = nil
}
比 "cell for row at indexPath" 检查:
ObjC:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
cell.layer.cornerRadius = cellWidth / 2.0;
if (self.selectedIndexPath != nil && indexPath == self.selectedIndexPath) {
cell.layer.backgroundColor = [UIColor blackColor].CGColor;
else {
cell.layer.backgroundColor = [UIColor whiteColor].CGColor;
}
return cell
}
Swift :
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.cellForItem(at: indexPath)
cell.layer.cornerRadius = cellWidth / 2
if self.selectedIndexPath != nil && indexPath == self.selectedIndexPath {
cell.layer.backgroundColor = UIColor.black
else {
cell.layer.backgroundColor = UIColor.white
}
}
感谢 Alberto Scampini 此代码用于 swift 3.1
var selectedIndexPath: IndexPath?
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "SegmentChoiceCVCell", for: indexPath) as! SegmentChoiceCVCell
//configure cell
if selectedIndexPath != nil && indexPath == selectedIndexPath {
cell.checkIcon.backgroundColor = UIColor.black
}else{
cell.checkIcon.backgroundColor = UIColor.white
}
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath) as! SegmentChoiceCVCell
cell.checkIcon.backgroundColor = UIColor.black
self.selectedIndexPath = indexPath
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let cell: SegmentChoiceCVCell = collectionView.cellForItem(at: indexPath) as! SegmentChoiceCVCell
cell.checkIcon.backgroundColor = white
selectedIndexPath = nil
}
我知道我迟到了。我有同样的问题。在 Whosebug 中环顾四周之后。这是我的解决方案。它可以帮助初学者更容易理解 UICollectionViewCell。
“cellForItemAtIndexPath”方法控制单元格的显示方式。屏幕外的单元格将不会更新。
Swift 4
首先,您需要 class 您的手机。
class SubclassedCell: UICollectionViewCell {
@IBOutlet var cellImage: UIImageView!
@IBOutlet var cellCaption: UILabel!
}
extension SubclassedCell{
func highlightEffect(){
self.layer.borderWidth = 3.0
self.layer.borderColor = UIColor.lightGray.cgColor
}
func removeHighlight(){
self.layer.borderColor = UIColor.clear.cgColor
}
}
现在是“cellForItemAt”方法。
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "blahblahblah", for: indexPath) as! SubclassedCell
cell.cellImage.image = yourImages[indexPath.item]
cell.cellCaption.text = yourImageNames[indexPath.item]
cell.removeHighlight() // Call subclassed cell method.
if indexPath.item == selectedItem {
cell.highlightEffect() // Call subclassed cell method.
preSelected = IndexPath(item: indexPath.item, section: indexPath.section)
}
collecttionRef = collectionView
return cell
}
然后,对于“didSelectItemAt”方法
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath){
collectionView.allowsMultipleSelection = false
if let cell = collectionView.cellForItem(at: indexPath) as! SubclassedCell?{
let indexPathData = NSKeyedArchiver.archivedData(withRootObject: indexPath)
UserDefaults.standard.set(indexPathData,forKey: "backgroundIndexPath")
//I got some unwrapped crash for my App so I have to use UserDefault to fix the unwrapped problem. You could ignore these both lines.
selectedItem = indexPath.item //selectedItem is used in the "cellForItemAt" method above.
collectionView.reloadData() //update all cells. It could be heavy if you have many cells.
}
}