Как очистить изображения из моего UIImageView - PullRequest
1 голос
/ 04 ноября 2019

У меня есть следующий код для layoutalLayout в Swift, но мои изображения не исчезают с повторным использованием ячеек.

import UIKit

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

    @IBOutlet var collectionView: UICollectionView!

    let myInset: CGFloat = 4.0

    let dataColors = [UIColor.red, UIColor.blue, UIColor.green, UIColor.magenta, UIColor.purple, UIColor.orange, UIColor.red, UIColor.blue, UIColor.green, UIColor.magenta, UIColor.purple, UIColor.systemYellow, UIColor.red, UIColor.blue, UIColor.green, UIColor.magenta, UIColor.purple, UIColor.orange, UIColor.red, UIColor.blue, UIColor.green, UIColor.magenta, UIColor.purple, UIColor.systemYellow]

    let theImages = [
            "MEN_8882","002","003","004","005","006","001","002","003","004","005","006",
            "MEN_8882","002","003","004","005","006","001","002","003","004","005","006"
    ]


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        collectionView.setCollectionViewLayout(createCustomLayout(), animated: false)
        collectionView.backgroundColor = .white
        self.collectionView.delegate = self
        self.collectionView.dataSource = self

        collectionView.register(QuickCell.self, forCellWithReuseIdentifier: "cellID")
       //configureCollectionView()
    }

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1//dataColors.count
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return dataColors.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellID", for: indexPath) as? QuickCell {
            cell.backgroundColor = dataColors[indexPath.row]
            let mySubView = UIImageView()
            mySubView.image = UIImage(named: theImages[indexPath.row])
            cell.addSubview(mySubView)
            mySubView.translatesAutoresizingMaskIntoConstraints =  false
            mySubView.topAnchor.constraint(equalTo: cell.topAnchor, constant: myInset).isActive = true
            mySubView.leadingAnchor.constraint(equalTo: cell.leadingAnchor, constant: myInset).isActive = true
            mySubView.trailingAnchor.constraint(equalTo: cell.trailingAnchor, constant: myInset * (-1)).isActive = true
            mySubView.bottomAnchor.constraint(equalTo: cell.bottomAnchor, constant: myInset * (-1)).isActive = true
            mySubView.clipsToBounds = true
           // mySubView.layer.cornerRadius = 8
            mySubView.contentMode = .scaleAspectFit
            cell.clipsToBounds = true
            cell.layoutIfNeeded()
            //cell.layer.cornerRadius = 12
            return cell
        } else {
            return UICollectionViewCell()
        }

    }

    func createCustomLayout() -> UICollectionViewLayout {

            let layout = UICollectionViewCompositionalLayout { (section: Int, environment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in

                let myItemInset: CGFloat = 2.0

                let leadingItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0)))
                leadingItem.contentInsets = NSDirectionalEdgeInsets(top: myItemInset, leading: myItemInset, bottom: myItemInset, trailing: myItemInset)

                let leadingGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.7), heightDimension: .fractionalHeight(1.0))
                let leadingGroup = NSCollectionLayoutGroup.vertical(layoutSize: leadingGroupSize, subitem: leadingItem, count: 1)

                let trailingGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.3), heightDimension: .fractionalHeight(1.0))
                let trailingGroup = NSCollectionLayoutGroup.vertical(layoutSize: trailingGroupSize, subitem: leadingItem, count: 5)

                let fullGroupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
                let fullGroup = NSCollectionLayoutGroup.horizontal(layoutSize: fullGroupSize, subitems: [leadingGroup, trailingGroup])

                let section = NSCollectionLayoutSection(group: fullGroup)

                section.orthogonalScrollingBehavior = .groupPagingCentered
                section.contentInsets = NSDirectionalEdgeInsets(top: 20, leading: 0, bottom: 20, trailing: 0)

                return section
            }
            return layout
        }

}

Изображение «МУЖЧИНА ...» является портретным, а остальные - альбомным, и при прокрутке назад и вперед я вижу перекрывающиеся изображения в элементах.

код дляQuickCell пуст - я не уверен, что поставить, какая-то инициализация? Но это должно работать в любом случае, верно?

import UIKit

class QuickCell: UICollectionViewCell {
}

Ответы [ 5 ]

0 голосов
/ 04 ноября 2019

Uncheck & try

Это проверено по умолчанию для UICollectionView, попробуйте снять его. Это должно работать для вас.

0 голосов
/ 04 ноября 2019

Подпредставление типа UIImageView добавляется в вашу пользовательскую ячейку (QuickCell) каждый раз, когда ваша ячейка представления коллекции возобновляется. Это происходит в cellForRowAt методе делегата.

Итак, вы должны сначала удалить ранее добавленные изображения из вашей ячейки, прежде чем добавлять новый.

Я предлагаю вам переместить код конфигурации вашей ячейки на QuickCell .

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellID", for: indexPath)
    if let quickCell = quickCell as? QuickCell {
        quickCell.backgroundColor = self.dataColors[indexPath.row]
        quickCell.setImage(self.theImages[indexPath.row], insetBy: self.myInset)
        return quickCell
    }
    return cell
}

Выполните ваши пользовательские настройки ячейки здесь!

class QuickCell: UICollectionViewCell {
    func setImage(_ image: UIImage, insetBy inset: CGFloat) {
        // Remove previously added image views first if any
        for subview in self.subviews where subview.isKind(of: UIImageView.self) {
            subview.removeFromSuperview()
        }
        let imageView = UIImageView()
        imageView.image = image
        imageView.clipsToBounds = true
        imageView.contentMode = .scaleAspectFit
        self.addSubview(imageView)

        imageView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            imageView.topAnchor.constraint(equalTo: self.topAnchor, constant: inset),
            imageView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: inset),
            imageView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: inset * (-1)),
            imageView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: inset * (-1))
        ])
        self.layoutIfNeeded()
    }
}
0 голосов
/ 04 ноября 2019

Вы продолжаете добавлять подпредставления внутри cellForItemAt, и это вызывает перекрытие при снятии очереди с ячеек, вам необходимо создать выход для изображения или , создать его программно внутри ячейки, например

class QuickCell: UICollectionViewCell {


    let mySubView = UIImageView()

    override init(frame: CGRect) {
        super.init(frame: frame)
        let myInset: CGFloat = 4.0
        self.contentView.addSubview(mySubView)
        mySubView.translatesAutoresizingMaskIntoConstraints =  false
        mySubView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: myInset).isActive = true
        mySubView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: myInset).isActive = true
        mySubView.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: myInset * (-1)).isActive = true
        mySubView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: myInset * (-1)).isActive = true
        mySubView.clipsToBounds = true
       // mySubView.layer.cornerRadius = 8
        mySubView.contentMode = .scaleAspectFit

    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


}

С

cell.mySubView.image = UIImage(named: theImages[indexPath.row])

или

    if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellID", for: indexPath) as? QuickCell {
        cell.subviews.forEach { 
             if $0.tag == 333 {
               $0.removeFromSuperview()
             }
         }
        cell.backgroundColor = dataColors[indexPath.row]
        let mySubView = UIImageView()
        mySubView.tag = 333
0 голосов
/ 04 ноября 2019

Проблема в том, что вы добавляете новый UIImageView каждый раз, когда ячейка используется повторно. Те, что были добавлены в предыдущих целях метода cellForItemAtIndexPath:, не исчезают, поэтому другие добавляются сверху.

Вот такие строки проблемы:

let mySubView = UIImageView()
mySubView.image = UIImage(named: theImages[indexPath.row])
cell.addSubview(mySubView)

Было бы лучшедобавьте представление изображения один раз, когда ячейка инициализируется (или в раскадровке с выходом), затем просто установите изображение в методе cellForItemAtIndexPath:.

0 голосов
/ 04 ноября 2019

Чтобы удалить image из UIImageView, выполните следующие действия.

yourImageView.image = nil 
...