ios 如何在集合视图中单选单元格..?

ljo96ir5  于 2023-05-19  发布在  iOS
关注(0)|答案(5)|浏览(130)

这是代码正常工作,但当我将滚动我的集合视图,然后另一个单元格也被选中,例如18个图像可用,并首先显示六个在运行时,当我将选择任何一个位置,然后下六个位置的图像自动选择。为什么一次选两个小区我就搞不懂了。请给予我答案

这里我有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;

}
pgky5nke

pgky5nke1#

这是因为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
}

而不是在“索引路径行的单元格”检查中:

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
    }
}
ne5o7dgx

ne5o7dgx2#

感谢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
}
ruarlubt

ruarlubt3#

我知道我迟到了。我也有同样的问题。而且在stackoverflow里看了一圈之后。这是我的解决方案。它可以帮助初学者更容易地理解UICollectionViewCell。
“cellForItemAtIndexPath”方法控制单元格将如何显示。屏幕外的单元格将不会更新。

Swift 4

首先,你需要对你的细胞进行子类化。

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.
        
    }
   
}
f4t66c6m

f4t66c6m4#

那是因为细胞被重复利用了。当你

UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];

改变单元格的角半径,实际上你改变了不止一个单元格的角半径。所以你应该这样做:

let cell = collectionView.dequeueReusableCellWithReuseIdentifier("YourCell", forIndexPath: indexPath) as! YourCell
r6hnlfcb

r6hnlfcb5#

*Swift 5酒店

//这是100%有效的!!!//在我的例子中,我想改变按钮的背景,换句话说,改变集合视图中单元格的背景:类CustomCVCell:UICollectionViewCell {

override var isSelected: Bool {
    didSet {
        grayBackgroundViewWithImage.image = isSelected ? UIImage(named: "") : UIImage()
    }
}

}
//在存储集合视图的主类中创建这个变量:类CustomViewController:UIViewController {

// save the indexPath of last selected cell
private var lastSelectedIndexPath: IndexPath?

// In viewDidLoad() set this value to false:

override func viewDidLoad() {
    super.viewDidLoad()
    customCollectionView.allowsMultipleSelection = false
}

// Further code in data source. In my case, the first cell should be is selected:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CustomCVCell.cellID(), for: indexPath) as! CustomCVCell
    // update first select state from initial.
    if indexPath.row == 0 && lastSelectedIndexPath == nil {
        lastSelectedIndexPath = indexPath
        cell?.isSelected = true
    } else {
        // update last select state from lastSelectedIndexPath
        cell?.isSelected = (lastSelectedIndexPath == indexPath)
    }
    cell.isSelected = (lastSelectedIndexPath == indexPath)
    return cell
}

// Further code in the delegate:
// UICollectionViewDelegate
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    guard lastSelectedIndexPath != indexPath else { return }
    
    if let index = lastSelectedIndexPath {
        let cell = collectionView.cellForItem(at: index) as! CustomCVCell
        cell.isSelected = false
    }
    let cell = collectionView.cellForItem(at: indexPath) as! CustomCVCell
    cell.isSelected = true
    lastSelectedIndexPath = indexPath
}

}

相关问题