-1

I have a collection view, when it loads for the first time everything works fine I have a photo archive, if the cell index exceeds the number of photos in the archive, then the photo is not added to the cell

1st photo is the moment of the first loading

But after I run the update data function, a complete house happens Added extra photos that should not have been Moreover, I did not change the archive itself, it remained the same, that is, according to the idea, nothing should have changed, but everything has changed

2nd photo is after data updateenter image description here

enter image description here

Here is my code:

import UIKit

class SettingsPhotoViewController: UIViewController {
    
    
    @IBOutlet weak var collectionPhotoView: UICollectionView!
    
    let imagePicker = UIImagePickerController()
    var imageArr = [UIImage(named: "1")!,UIImage(named: "2")!,UIImage(named: "3")!,UIImage(named: "4")!]
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        collectionPhotoView.delegate = self
        collectionPhotoView.dataSource = self
        
        imagePicker.delegate = self
        imagePicker.allowsEditing = false /// Спрашивает может ли пользователь редактикровать фото
        
    }


}




//MARK:  - Настройка фотоколлажа

extension SettingsPhotoViewController : UICollectionViewDataSource, UICollectionViewDelegate,UICollectionViewDelegateFlowLayout {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 9
    }
    
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "imageUserCell", for: indexPath)
        cell.layer.cornerRadius = 10
        cell.layer.masksToBounds = true
      
        
        if let imageView = createImage(indexPath: indexPath.row, cellWidth: cell.frame.width, cellHeight: cell.frame.height) {
            
            
            cell.contentView.addSubview(imageView)
            
            let button = createButton(x: cell.frame.maxX ,y: cell.frame.maxY,add: false)
            collectionPhotoView.addSubview(button)
            
        }else {
            
            cell.backgroundColor = UIColor(named: "PhotoCollage")
            
            let newBorder = createDottedLine(bounds: cell.bounds)
            cell.layer.addSublayer(newBorder)
            
            let button = createButton(x: cell.frame.maxX ,y: cell.frame.maxY,add: true)
            collectionPhotoView.addSubview(button)
            
        }
        
        return cell
    }
    
    
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { /// Расчитываем размеры ячейки
        return CGSize(width: (collectionView.frame.size.width / 3) - 14 , height: (collectionView.frame.height / 3) - 20)
    }
    
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { /// Запрашивает у делегата расстояние между последовательными строками или столбцами раздела.
        return 15
    }
    
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { /// Делаем отступы
        return UIEdgeInsets(top: 0, left: 3, bottom: 0, right: 10)
    }
    
    
}




//MARK: - Внешние оформление ячеек


extension SettingsPhotoViewController {
        
    func createImage(indexPath: Int,cellWidth: CGFloat,cellHeight: CGFloat) -> UIImageView? { /// Создание фото
        
        print(imageArr.count)
        if indexPath < imageArr.count {
            let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: cellWidth, height: cellHeight))
            imageView.image = imageArr[indexPath]
            imageView.contentMode = .scaleAspectFill
            return imageView
            
        }
        return nil
    }
    
    
    
//MARK: - Создаем пунктирную обводку
    
    func createDottedLine(bounds: CGRect) -> CAShapeLayer { /// Создание пунткирной границы
        
        let viewBorder = CAShapeLayer()
        viewBorder.strokeColor = UIColor.gray.cgColor
        viewBorder.lineDashPattern = [10,4]  /// Штриховой узор, применяемый к контуру фигуры при обводке.
        viewBorder.frame = bounds
        viewBorder.opacity = 0.4
        viewBorder.lineWidth = 5
        viewBorder.fillColor = nil
        viewBorder.path = UIBezierPath(rect: viewBorder.bounds).cgPath
        
        return viewBorder
        
    }
    
    
    
//MARK: - Создание кнопок удаления и добавления
    
    
    func createButton(x: CGFloat, y: CGFloat, add: Bool) -> UIButton {
        
        let button = UIButton(frame: CGRect(x: 0, y: 0,width: 30, height: 30))
        button.center = CGPoint(x: x - 5, y: y - 5)
        button.layer.cornerRadius = button.frame.size.width / 2
        button.layer.masksToBounds = true
        
        button.layer.shadowColor = UIColor.black.cgColor
        button.layer.shadowOffset = .zero
        button.layer.opacity = 1
        button.layer.shadowRadius = 10
        
        if add {
            
            button.backgroundColor = UIColor(named: "MainAppColor")
            button.setImage(UIImage(named: "Plus"), for: .normal)
            button.tintColor = UIColor.white
            
            let action = UIAction { action in
                self.collectionPhotoView.reloadData()
                
            }
            button.addAction(action, for: .touchUpInside)
            
            return button
            
        }else {
            
            button.backgroundColor = .white
            button.setImage(UIImage(named: "DeletePhoto1"), for: .normal)
            button.tintColor = UIColor.gray
            
            button.layer.borderWidth = 0.5
            button.layer.borderColor = UIColor.gray.cgColor
            
            let action = UIAction { action in
                print("Delete")
            }
            button.addAction(action, for: .touchUpInside)

            return button
        }
    }
}
mozway
  • 194,879
  • 13
  • 39
  • 75
Denim
  • 9
  • 2
  • UICollectionViewCell are reused, so each time there is a, `addSubview()` inside `collectionView(_:cellForItemAt:) -> UICollectionViewCell` there is mostly a misuse of that concept... – Larme May 01 '23 at 08:29
  • As @Larme says, collection view cells are reused so you can’t keep adding new views to them. Each time a cell is reused you will be adding a new image and/or a new button. You should have a custom collection view cell which can support showing what you need and use properties to control which state it is in. Configure those properties in `cellForItemAt:`. You could probably configure the appearance based on whether there is an image to display or not. – Geoff Hackworth May 01 '23 at 08:47

1 Answers1

-1

The whole problem was in the layers I added a new layer each time, but then did not delete it

After that, I decided to abandon the layers and created my own class where the cell had a default image view

Denim
  • 9
  • 2
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 04 '23 at 12:50