保存多个选定 UITableViewCell 值的数组

Posted

技术标签:

【中文标题】保存多个选定 UITableViewCell 值的数组【英文标题】:Save an array of multiple selected UITableViewCell values 【发布时间】:2018-02-17 20:25:24 【问题描述】:

我在使用表格视图(XCode 9、Swift 4)时遇到了一个非常具体的问题。我想要做的是,用用户手动选择的表格单元格中的 foodName 标签的文本值创建一个名为 foodDetailInfoArray 的数组。目前,虽然 .setSelected 方法可以根据需要更改单元格的 UI,但它并不能帮助我正确记录 foodName.text 值。问题是即使在滚动表格视图时也会记录文本值,并且数组值也会被替换。以下是打印输出的代码和示例。

var foodDetailInfoArray: [String] = []

@IBOutlet var unselectedCell: UIView!
@IBOutlet var foodName: UILabel!
@IBOutlet var carbonValue: UILabel!

override func setSelected(_ selected: Bool, animated: Bool) 
    super.setSelected(selected, animated: animated)
    // Configure the view for the selected state
    if selected == true 
        self.unselectedCell.backgroundColor = UIColor.init(red: 4/255, green: 206/255, blue: 132/255, alpha: 1)
        self.foodName.textColor = UIColor.white
        self.carbonValue.textColor = UIColor.white
        foodDetailInfoArray.append(foodName.text!)
     else 
        self.unselectedCell.backgroundColor = UIColor.clear
        self.foodName.textColor = UIColor.black
        self.carbonValue.textColor = UIColor.black
    

    print(foodDetailInfoArray)

打印语句给了我这样的结果: (此时甚至没有选择单元格,我只是在滚动表格视图。)

["pepper"]
["pasta"]
["pasta", "pepper"]
["pepper"]
["pepper", "pasta"]
["stir-fry"]
["stir-fry", "stir-fry"]
["vegetable"]
["vegetable", "vegetable"]

然而,我理想中想要的是(按单击包含给定 foodName 的单元格的顺序):

["pasta"]
["pasta", "pepper"]
["pasta", "pepper", "tomato"]
["pasta", "pepper", "tomato", "stir-fry"]

如果取消选择某个单元格,则必须删除名称,即如果取消选择番茄,则数组将是

["pasta", "pepper", "stir-fry"]

...等等

PS:我不是专业的程序员,最近完全是自学成才,所以如果问题有任何不清楚的地方,请告诉我。

【问题讨论】:

【参考方案1】:

我将通过视图控制器处理单元格的选择和取消选择,因此您也可以更好地使用您的foodDetailInfoArray。在answer 的帮助下,您可以这样做:

import UIKit

class ViewController: UITableViewController 

    // example data
    let names = [ "pepper", "pasta", "stir-fry", "vegetable"]

    var foodDetailInfoArray: [String] = []

    override func viewDidLoad() 
        super.viewDidLoad()

        // allow multiselection
        tableView.allowsMultipleSelection = true
    


    // MARK: UITableViewDataSource

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return 4
    

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
        cell.textLabel?.text = names[indexPath.row]
        // Don't show highlighted state
        cell.selectionStyle = .none

        return cell
    

    // MARK: UITableViewDelegate

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        // also do your UI changing for the cell here for selecting

        // Add your food detail to the array
        foodDetailInfoArray.append(names[indexPath.row])
    

    override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) 
        // also do your UI changing for the cell here for deselecting

        // Remove your food detail from the array if it exists
        if let index = foodDetailInfoArray.index(of: names[indexPath.row]) 
            foodDetailInfoArray.remove(at: index)
        
    


结果

【讨论】:

嗨!这对我有用..顺便说一句,正在尝试类似的事情。非常感谢你说清楚!不过,我确实有一个后续问题 - 是什么导致滚动被解释为 .setSelected 方法中的选定单元格? 是的,很高兴我能帮助你!由于您的后续问题,似乎是因为 ios 7 通过touchesBegan 事件 UITableView 取消选择选定的单元格并选择touchDown,因此取决于您在初始解决方案中调用setSelected 的位置也设置了状态并多次取消设置,也是因为重用了单元格。另请参阅此处***.com/questions/13275405/… 和此处***.com/questions/28360919/…【参考方案2】:

我会为tableViews 尝试委托方法didSelectRowAtIndexPath。让您的视图控制器采用UITableViewDelegate 协议并实现以下内容。

假设您有一个 foods 数组和一个最初为空的 foodsSelected 数组。

let foods:[String] = ["Apples","Avocado","Bananas"]
var foodsSelected:[String] = []

现在,只要选择了一个单元格,就会调用此委托方法,并从 foodsSelected 数组中添加或删除选定的食物。

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    //Check if the selected food is in the foodsSelect array
    if(!foodsSelected.contains(foods[indexPath.row]))
        //If it's not, append it to the array
        foodsSelected.append(foods[indexPath.row])
    else
        //If it is, remove it from the array. 
        //Note there are many ways to remove an element from an array; I decided to use filter. 
        foodsSelected = foodsSelected.filter($0 != foods[indexPath.row])
    
    print(foodsSelected)

这是我按顺序选择这些项目时的输出:Apples, Avocado,Bananas,Avocado

["Apples"]
["Apples", "Avocado"]
["Apples", "Avocado", "Bananas"]
["Apples", "Bananas"]

【讨论】:

嗨!感谢您的回答.. 虽然我认为是一个小问题。在 didSelectRowAt 的代码中,您第一次单击了“Apples”。第二次单击“Apples”时,它实际上是此处未指定的 didDeselectRowAt 操作(由@ronatory 在他的回答中指定。),因此此代码块不会从大批。如果您第三次单击“Apples”,则结果数组将为空(不正确)。所以也必须指定 didDeselectRowAt @kavyajha1004 你说得很好,但事实并非如此。 didSelectRowAt,如果说单击Apples 两次,将从数组中添加然后删除ApplesdidDeselectRowAt 从未被调用过。 didDeselectRowAt 仅在单击新行后调用,例如首先是Apples,然后是BananasdidDeselectRowAt 会将Apples 识别为被取消选择。 嘿..好的,我确实尝试了该方法,但问题如下。如果表只包含两个项目 - “蔬菜”和“鸡蛋”。首先,我单击“蔬菜”,数组添加了这一点,我第二次单击它并没有任何反应,然后我第三次单击它并得到一个空数组,即使在 UI 上选择了“蔬菜”。如果我然后单击“egg”,它只是将值附加到空数组中并且不包括“vegetables”。不知道为什么如果为你工作它会给我一个不同的结果 你碰巧有tableView.allowsMultipleSelection = true吗?如果是这样,这会干扰。 哦,是的。因为我确实需要多项选择,并且已经阅读过它应该设置为 true!只是出于好奇,为什么会干扰?还有为什么当包含 didDeselectRowAt 方法时它会起作用?

以上是关于保存多个选定 UITableViewCell 值的数组的主要内容,如果未能解决你的问题,请参考以下文章

如何将 UITableViewCell 内的 UICollectionViewCell 的选定索引路径保存到数组中?

保存在 UIPicker 中选择的值的最佳方法?

Javascript将具有多个值的选定选项从一个列表移动到另一个列表

突出显示的 UITableViewCell 和选定的 UITableViewCell 有啥区别?

选定的 UIButton 在选定的 UITableViewCell 内消失

滚动时 UITableViewCell 的选定按钮消失