【问题标题】:remove element of custom type from array in swift快速从数组中删除自定义类型的元素
【发布时间】:2017-11-16 14:06:00
【问题描述】:

我正在使用集合视图将对象添加到名为collectiveSelection 的数组中

选择收集视图单元格(CurrentsElection)时,我想测试该对象是否存在于阵列(收集器)中是否存在。如果是这样,我想将其删除(以实现切换开/关效果)。如果它不在数组中,我想添加它。

我添加到数组中的项目属于自定义类,因此当我尝试在我的检查中使用 .index(of:) 时,这会导致我出现问题。

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    currentSelection = itMachine.selection[indexPath.row]  // returns some selection of type 'Attractions'

    if collectiveSelection.contains(where: { $0 == currentSelection}){ // if selection exists in array, remove it, if it doesn't, add it

        let itemIndex = collectiveSelection.index(of: currentSelection) // error message about .index not being available for custom class Attractions

        collectiveSelection.remove(at: itemIndex)

        updateCell(having: indexPath, selected: false)

    } else { // deselect

        collectiveSelection.append(currentSelection!) 

        updateCell(having: indexPath, selected: true)
    }
}

我尝试让我的自定义类符合 Equatable,但这并没有帮助,因为我仍然遇到错误。关于如何在数组collectiveSelection 中获取自定义元素currentSelection 的索引的任何想法?

【问题讨论】:

  • 你应该尝试使用 .index(where:) 方法,而不是检查是否包含
  • 如果您发布错误所说的内容会很有帮助。
  • 您可以在collectiveSelection 上使用filter 来删除该元素 - 只需执行collectiveSelection.filter { $0 != currentSelection } 但听起来您的问题与equals有关
  • 不要使用数组。使用Set<Attractions>。然后你可以使用containsinsertremove,只要你的Attractions对象符合Hashable

标签: ios arrays swift uicollectionview


【解决方案1】:

您可能会发现跟踪选定的索引比跟踪您的自定义对象要容易得多。毕竟,您的对象一开始就放在一个数组中。

看看这个:

//
//  TrackSelectedViewController.swift
//
//  Created by Don Mag on 11/16/17.
//

import UIKit

private let reuseIdentifier = "TrackingCell"

class TrackSelectedViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {

    @IBOutlet weak var theCV: UICollectionView!

    // this will maintain a list of IndexPath for selected cells
    var collectiveSelection = [IndexPath]()

    override func viewDidLoad() {
        super.viewDidLoad()

        theCV.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
    }

    // MARK: UICollectionViewDataSource

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)

        // does collectiveSelection contain this indexPath?
        let idx = collectiveSelection.index(of: indexPath) ?? -1

        if idx > -1 {
            // indexPath IS in collectiveSelection
            cell.backgroundColor = .red
        } else {
            // indexPath IS NOT in collectiveSelection
            cell.backgroundColor = .lightGray
        }

        // of course, you'll configure your cell other than just setting the background color

        return cell
    }

    // MARK: UICollectionViewDelegate

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        // get a reference to the cell
        let cell = collectionView.cellForItem(at: indexPath)

        // does collectiveSelection contain this indexPath?
        let idx = collectiveSelection.index(of: indexPath) ?? -1

        if idx > -1 {

            // indexPath IS in collectiveSelection
            // so remove it and set the cell to Gray
            collectiveSelection.remove(at: idx)

            cell?.backgroundColor = .lightGray

            // your code:
            // updateCell(having: indexPath, selected: true)

        } else {

            // indexPath IS NOt in collectiveSelection
            // so add it and set the cell to Red
            collectiveSelection.append(indexPath)

            cell?.backgroundColor = .red

            // your code:
            // updateCell(having: indexPath, selected: true)

        }

    }

}

如果您创建一个新的 UIViewController 并添加一个 UICollectionView(并将其连接到 IBOutlet 和 DataSource 和 Delegate),您可以按原样运行该代码...它将在灰色和红色之间切换单元格,取决于他们是否在collectiveSelection

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-28
    • 2017-11-22
    相关资源
    最近更新 更多