Обновите модель данных в CollectionView для фильтрации ячеек - PullRequest
0 голосов
/ 07 ноября 2018

У меня есть 1 CollectionView с именем animalCollectionView, который заполняется более чем 100 объектами AnimalModel из структуры AnimalData. Ниже CollectionView у меня есть 4 кнопки с различными классификациями животных: Рыба, Амфибия, Птица, Рептилия. Я хотел бы, чтобы эти 4 кнопки переключали соответствующие данные в CollectionView. Каждый объект AnimalModel имеет свойство animalSelected, которое должно переключаться соответствующим образом.

Прогресс, я почти там. У меня просто возникают проблемы при переборе ВСЕХ данных, чтобы изменить свойство animalSelected для соответствующих объектов.

Вот данные:

struct AnimalModel {
    var animalName:String
    var animalClassification:Animal

    var animalSelected:Bool

    enum Animal:String {
        case bird
        case fish
        case reptile
        case amphibian
    }
}

struct AnimalData {
    static func allAnimal() -> [AnimalModel] {
        return [
            AnimalModel(animalName: "Salmon", animalClassification: .fish, animalSelected: false),
            AnimalModel(animalName: "Goldfish", animalClassification: .fish, animalSelected: false),
            AnimalModel(animalName: "Guppy", animalClassification: .fish, animalSelected: false),
            AnimalModel(animalName: "Shark", animalClassification: .fish, animalSelected: false),
            AnimalModel(animalName: "Tuna", animalClassification: .fish, animalSelected: false),
            AnimalModel(animalName: "Clownfish", animalClassification: .fish, animalSelected: false),
            AnimalModel(animalName: "Swordfish", animalClassification: .fish, animalSelected: false),
            AnimalModel(animalName: "Frog", animalClassification: .amphibian, animalSelected: false),
            AnimalModel(animalName: "Toad", animalClassification: .amphibian, animalSelected: false),
            AnimalModel(animalName: "Newt", animalClassification: .amphibian, animalSelected: false),
            AnimalModel(animalName: "Salamander", animalClassification: .amphibian, animalSelected: false),
            AnimalModel(animalName: "Ostrich", animalClassification: .bird, animalSelected: false),
            AnimalModel(animalName: "Peacock", animalClassification: .bird, animalSelected: false),
            AnimalModel(animalName: "Eagle", animalClassification: .bird, animalSelected: false),
            AnimalModel(animalName: "Duck", animalClassification: .bird, animalSelected: false),
            AnimalModel(animalName: "Chicken", animalClassification: .bird, animalSelected: false),
            AnimalModel(animalName: "Snake", animalClassification: .reptile, animalSelected: false),
            AnimalModel(animalName: "Chameleon", animalClassification: .reptile, animalSelected: false),
            AnimalModel(animalName: "Lizard", animalClassification: .reptile, animalSelected: false),
            AnimalModel(animalName: "Turtle", animalClassification: .reptile, animalSelected: false)
            // + about 80 more... 
        ]
    }
}

Вот ВК

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

    @IBOutlet weak var animalCollectionView: UICollectionView!

    @IBOutlet weak var birdOutlet: UIButton!
    @IBOutlet weak var fishOutlet: UIButton!
    @IBOutlet weak var reptileOutlet: UIButton!
    @IBOutlet weak var amphibion: UIButton!

    var all = AnimalData.allAnimal()

    override func viewDidLoad() {
        super.viewDidLoad()
        animalCollectionView.delegate = self
        animalCollectionView.dataSource = self
    }

    @IBAction func birdBtnPressed(_ sender: UIButton) {
//          for bird in all {
//              bird.animalSelected = true
//          }
        all[1].animalSelected = true
        animalCollectionView.reloadData()
    }
    @IBAction func fishBtnPressed(_ sender: UIButton) {
    }
    @IBAction func reptileBtnPressed(_ sender: UIButton) {
    }
    @IBAction func amphibionBtnPressed(_ sender: UIButton) {
    }


    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return all.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ANIMAL", for: indexPath) as! AnimalCollectionViewCell
        cell.animalNameLabel.text = all[indexPath.item].animalName
        cell.animalClassificationLabel.text = all[indexPath.item].animalClassification.rawValue

        if all[indexPath.item].animalSelected {
            cell.alpha = 1
        } else {
            cell.alpha = 0.2
        }

        return cell
    }

}

birdButtonPressed - это то место, где я пытался. Я прокомментировал:

for bird in all {
    bird.animalSelected = true 
}

потому что это дает ошибку: Cannot assign to property: 'bird' is a 'let' constant

all[1].animalSelected = true, очевидно, не перебирает птиц, но я просто делал это, чтобы убедиться, что вторая альфа-ячейка изменилась ... что она и сделала! (см. скриншот ниже)

Как перебрать данные, чтобы изменить animalSelected на true в соответствующих ячейках?

UI

1 Ответ

0 голосов
/ 07 ноября 2018

Сначала я бы извлек перечисление Animal из структуры AnimalModel для модульности. Это также позволяет лучше проверять использование перечислимых случаев на равенство.

Есть две вещи, которые вы должны сделать, чтобы ваша ценность изменилась. Поскольку вы используете структуру, тип значения вместо ссылочного типа, вы должны предоставить способ изменить его внутреннее значение. Вы достигаете этого, добавляя мутирующую функцию следующим образом:

struct AnimalModel {
   var animalName: String
   var animalClassification: Animal
   var animalSelected: Bool

   mutating func setAnimalToSelected(value: Bool) {
       animalSelected = value
   }
}

Мутирующая функция позволяет вам изменять значение внутри структуры.

Но прежде чем сделать это, вы должны получить его конкретный индекс и изменить эту конкретную структуру с помощью мутирующей функции.

for (index, animal) in all.enumerated() {
   if animal.animalClassification == Animal.bird {
       all[index].animalSelected = true
        //if you only have one section
       let indexPath = IndexPath(row: index, section: 0)
       self.collectionView.reloadItems(at: [indexPath])
   }
}
...