如何使用 Array 中已有的值选择 tableview 行。迅速

Posted

技术标签:

【中文标题】如何使用 Array 中已有的值选择 tableview 行。迅速【英文标题】:How to make tableview rows select with already existing values in Array. in swift 【发布时间】:2021-06-12 08:57:39 【问题描述】:

细胞模型

class LangModel
var name: String?
var id: Int?
var isSelected: Bool?

init(name: String?, id: Int?, isSelected: Bool?) 
    self.name = name
    self.id = id
    self.isSelected = isSelected


我正在从 JSON 向 tableview 添加值,如下所示

for langData in getuserData?.result?.language ?? []

   self.langCellArray.append(LangModel(name: langData.language ?? "", id: langData.id ?? 0, isSelected: false))
  
 tableView.reloadData()

使用下面的代码,当我单击languagesBtn 并选择和取消选择 tableview 行时,我可以显示 tableview..

但这里我需要的是..如果languageTextField.text 包含语言,那么如果我点击languageBtn,那么应该使用languageTextField 文本选择tableview 行

怎么做

showPop 显示带有 DONE 和 CANCEL 按钮的 tableview 视图以及设计中的languageTextField is inside languagesBtn

@IBAction func languagesBtn(_ sender: Any) 
    showPop()


@IBAction func cancelBtn(_ sender: Any) 
remove()


@IBAction func doneBtn(_ sender: Any) 

languageTextField.text = selectedlangArray.joined(separator: ", ")
print("Lang array \(selectedlangArray)")
remove()
tableView.reloadData()


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
return langCellArray.count


 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 


let cell = tableView.dequeueReusableCell(withIdentifier: "EditLangTableVIewCell", for: indexPath) as! EditLangTableVIewCell

cell.langLbl.text = langCellArray[indexPath.row].name

let selectedIndexPaths = tableView.indexPathsForSelectedRows
let rowIsSelected = selectedIndexPaths != nil && selectedIndexPaths!.contains(indexPath)
cell.accessoryType = rowIsSelected ? .checkmark : .none

return cell


func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 

let cell:EditLangTableVIewCell = tableView.cellForRow(at: indexPath) as! EditLangTableVIewCell

cell.accessoryType = .checkmark
langCellArray[indexPath.row].isSelected = true
selectedlangArray.append((cell.langLbl?.text)!)



func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) 
let cell:EditLangTableVIewCell = tableView.cellForRow(at: indexPath) as! EditLangTableVIewCell
cell.accessoryType = .none

请帮忙

【问题讨论】:

【参考方案1】:

由于您在模型中有一个属性isSelected,请使用它(并将其声明为非可选,不存在可能状态)。

selectedIndexPaths 以及额外的数组根本不需要。删除它们。

你甚至可以使用结构体(初始化器是免费的)

struct LangModel 
    var name: String?
    var id: Int?
    var isSelected: Bool

cellForRowAt 中根据isSelected 设置附件视图。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell         
    let cell = tableView.dequeueReusableCell(withIdentifier: "EditLangTableVIewCell", for: indexPath) as! EditLangTableVIewCell
    
    let item = langCellArray[indexPath.row]
    cell.langLbl.text = item.name
    cell.accessoryType = item.isSelected ? .checkmark : .none
    
    return cell

didSelect 中切换isSelected 并仅重新加载该行。不要直接修改单元格,通过调用reloadRows(at:with:)告诉cellForRow去做

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    langCellArray[indexPath.row].isSelected.toggle()
    tableView.reloadRows(at: [indexPath], with: .automatic) 

同时删除

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) 
    let cell:EditLangTableVIewCell = tableView.cellForRow(at: indexPath) as! EditLangTableVIewCell
    cell.accessoryType = .none
  
罢工>

【讨论】:

谢谢.. 我需要在文本字段中添加选定的行文本,所以在你的代码didSelectRowAt 中我添加了这样的selectedlangArray.append((cell.langLbl?.text)!) 在这里,当 tableview 到来时,复选标记显示,但是.. 我猜单元格没有选择.. bcz 如果我选择选中标记的行然后复选标记消失,然后单元格值进入文本字段.. ..如何解决这个问题 不要从单元格中获取(静态)数据,永远不要那样做,总是从模型中获取。 cell.langLbl.text langCellArray[indexPath.row].name 相同。并停止使用那些额外的数组。 filter 数据源。您将使用langCellArray.filter$0.isSelected.map(\.name) 获得所有选定单元格的名称。对于可见的选择问题,将模型cellForRow 中单元格的isSelected 设置为isSelected 大部分问题都解决了,但问题是如果我添加如果我像这样添加languageTextField.text = langCellArray.filter$0.isSelected.map(\.name) 那么错误是Cannot assign value of type '[String?]' to type 'String' 我需要在带有逗号分隔的文本字段中显示语言数组【参考方案2】:

当您调用tableView.reloadData() 时,它会清除UITableView 实例中之前选择的所有indexPath 值。

解决此问题的一个方法是替换以下内容 -

let selectedIndexPaths = tableView.indexPathsForSelectedRows
let rowIsSelected = selectedIndexPaths != nil && selectedIndexPaths!.contains(indexPath)

let rowIsSelected = (langCellArray[indexPath.row].isSelected == true)

还有-

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) 
    let cell: EditLangTableVIewCell = tableView.cellForRow(at: indexPath) as! EditLangTableVIewCell
    cell.accessoryType = .none

    langCellArray[indexPath.row].isSelected = false


更新

如果我们想继续使用indexPathsForSelectedRows 中内置的UITableView 来跟踪选定状态,我们可以丢弃我在上面解释过的rowIsSelected 的更改。

修复方法是 - 像这样在重新加载后手动重新选择所有先前选择的索引路径 -

tableView.reloadData()

for (index, model) in langCellArray.enumerated() 
    if model.isSelected == true 
        let ip = IndexPath(row: index, section: 0)
        tableView.selectRow(at: ip, animated: false, scrollPosition: .none)
    

【讨论】:

显示此代码复选标记但未选中该行.. bcz 当我点击复选标记行时,复选标记消失并将行值添加到文本字段

以上是关于如何使用 Array 中已有的值选择 tableview 行。迅速的主要内容,如果未能解决你的问题,请参考以下文章

Django DB 迁移添加新列,但不要编辑表中已有的值

如何使用 DBus 中已有的服务?

如何在Allegro PCB封装中修改PAD怎么保存Allegro PCB封装中已有的PAD?

js数组如何去重?

如何在Allegro PCB封装中修改PAD怎么保存Allegro PCB封装中已有的PAD?

django如何连接Mysql中已有的数据库