从列表中选择并重新加载 Tableview Swift

Posted

技术标签:

【中文标题】从列表中选择并重新加载 Tableview Swift【英文标题】:Selections from List and reload Tableview Swift 【发布时间】:2019-11-29 07:38:14 【问题描述】:

我对此很陌生。我遇到了选择项目的问题,并在特定索引单元格(重新加载)上回发到 tableview。 场景:我有两个视图控制器,并且都包含 tableview。

FirstViewController: 我已经将来自 web 服务的数据显示到 Tableview 中,但是在不同的操作类型上,我使用了 didSelectRow 函数,该函数显示给ListViewController 用于项目选择。在 FirstViewController 中,主要模型是 Unit。

ListViewController: tableView 中显示的简单数据列表供选择。

问题: 是如何从 ListViewController 中选择项目并将数据传递给 FirstViewController 表格视图,在特定单元格上发生更改,然后我必须发布具有更新值的值。如何重新加载 tableview 或模型?

型号:

struct Unit : Codable 

    let sectionList : [SectionList]?



struct SectionList : Codable 

    let title : String?
    let items : [Item]?



struct Item : Codable 

    let actionType : Int?
    let textField : String?
    let textValue : String?
    let pickList: [SectionList]?
    let multiSelect: Bool?
    let selectedValue: [String]?
    let version: Int?
    let masterId: Int?
    let itemValue: String?


更新了 FirstController:

class FirstViewController: UIViewControlller, ListDelegate 

   var selectedIndex: Int?
   var selectedSection: Int?

   //Click event for navigation from FirstViewController to SecondViewController
   @IBAction func BackButtonAction(_ sender: Any) 
       let vc = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
       vc.delegate = self
       self.navigationController?.pushViewController(vc, animated: true)
   

   func listFunc(listValue: String) 
       AppData?.sectionList?[selectedSection!].items?[selectedIndex!].textField = listValue
       tableView.reloadData()
   

   func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
       //Add these two line in your code
       selectedIndex = indexPath.row
       selectedSection = indexPath.section
    


更新:ListViewController:

protocol ListDelegate 
    func listFunc(listValue: String)


class SecondViewController: UIViewControlller 
    var delegate: ListDelegate?

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        let indexPath = tableView.indexPathForSelectedRow
        let currentCell = tableView.cellForRow(at: indexPath!)!
        //print(currentCell.textLabel?.text as Any)
        currentCell.accessoryType = .checkmark
        delegate?.listFunc(listValue: currentCell.textLabel?.text ?? "")
        self.navigationController?.popViewController(animated: true)
   

【问题讨论】:

Examples of Delegates in Swift的可能重复 @dahiya_boy 我已经阅读了代表,但不知道如何选择发送到上一个 viewController tableView 单元格的项目.. 您需要在委托函数中传递选定的数据。有关更多详细信息,请访问此appcoda.com/swift-delegate。如果您在直接进入主项目之前尝试一些委托和协议的演示,那就更好了。这并不难,但您需要先清除基础知识。 @dahiya_boy 我正在努力实现但达不到标准。我可以和你分享我的测试项目吗? 好的,分享 github 链接。 【参考方案1】:

您有多种选择来完成此任务。假设所选值是您必须传递的唯一值,那么使用闭包将是您可以做的最简单的事情。

1) 在ListViewController 中声明一个包含您需要的类型的闭包:

`var didSelectItem : ((YourType, IndexPath) -> ())?`

2) 在ListViewControllerdidSelectRow方法中,使用闭包:

`self.didSelectItem?(yourDataSourceItemAtIndexpath, indexPath)`

3) 当您在 FirstViewController 内部的 ListViewController 实例中使用此闭包时,您将收到触发闭包的回调,例如:

let myListInstance = ListViewController()

myListInstance.didSelectItem =  selectedItem, selectedIndex in
  //You'll get the selected item inside this block, do model updation here


使用新值更新模型后,如果您只想在特定(更新的)索引处重新加载 tableView,您可以使用:

self.yourTableView.reloadSections(sections: IndexSet, with: UITableView.RowAnimation) 重新加载整个部分或..

self.yourTableView.reloadRows(at: [IndexPath], with: UITableView.RowAnimation) 重新加载节中的一行

(如果您同时执行多个更新,请记住您必须在 self.yourTableView.beginUpdates()self.yourTableView.endUpdates() 中执行这些重新加载)

注意:

您必须在这些重新加载期间正确处理您的数据源,以确保在重新加载之前和之后拥有正确数量的行或节,添加/减去您插入/删除的行/节。否则,您的应用将崩溃!

如果您不想冒险,只需使用 yourTableView.reloadData() 重新加载整个表格

另外请记住,还有其他方法可以跨控制器传递数据,这只是基于我假设您的用例的建议

【讨论】:

谢谢你让我实现这个并回复你。 酷,乐于助人;) 您介意我与您分享我的代码吗?我试过但没有达到标准。可能是因为我有复杂的 json 模型。【参考方案2】:

我几乎无法理解您的代码,在我看来,这完全是一团糟。

我发现你的大部分代码已经完成,我正在添加你需要做的事情。


    在你的 FirstViewController.swiftdidSelectRowAt 函数中,

    let vc = self.storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController
    vc.Indexdata = // your data that you wanted to show in your next controller, 
    // if variable is different then assign data to that var
    vc.delegate = self
    self.navigationController?.pushViewController(vc, animated: true)
    

    ViewController.swiftdidSelectRowAt函数,

    // Comment these below lines
    
    // let vc = self.storyboard?.instantiateViewController(withIdentifier: "FirstViewController") as! FirstViewController
    // self.navigationController?.pushViewController(vc, animated: true)
    
    // Add below line        
    self.navigationController?.popViewController(animated: true)
    

现在检查它应该可以工作。

【讨论】:

是的,谢谢它的工作。只有一件事如何在 tableview 特定的索引位置或模型中重新加载。 let indexPathRow:Int = 0 let indexPosition = IndexPath(row: indexPathRow, section: 0) tableView.reloadRows(at: [indexPosition], with: .none) 你的代码很好。您只需要找出需要重新加载的 IndexPath。如果您指定何时要重新加载,则更好。以便我可以提供相应的帮助。 谢谢。实际上基于动作类型1420我正在使用列表选择项。所以在 firstViewController 我在多个表格单元格上使用相同的列表。 print(indexPath.row) & print(indexPath.section) 是否可以更新数据模型和 tableview 重新加载,因为一旦完成所有选择和 table reload() 我必须将值发布到服务器。 对不起,我被清除了,你的意思是,当你从SecondViewController 弹出时,你需要更新tableView?? 干杯????

以上是关于从列表中选择并重新加载 Tableview Swift的主要内容,如果未能解决你的问题,请参考以下文章

从 UITableViewController 重新加载 tableView

modalview 关闭后 TableView 未重新加载

TableView:是不是可以在不重新加载 tableview 或部分的情况下删除现有行并插入新行?

使用重新加载数据选择子项后,Tableview 刷新到父视图

TableView 未使用来自 AFNetworking 响应对象的新数据重新加载

从 UIAlertController 重新加载 tableView 数据不起作用