问题
I am quite new to this. I am getting an issue with selection items and post back to tableview on specific index cell (reload). Scenario: I have two view controllers and both contains tableview.
FirstViewController:
I am already displaying data from webservice into Tableview but on different action types I have used didSelectRow function which shows to ListViewController
for item selection. In FirstViewController main model is Unit.
ListViewController:
Simple list of data displaying in tableView for selection.
Issue: is how can I select item from ListViewController and pass data to FirstViewController tableview that change occurs on specific cell and then I have to post values with updated values. How can I reload tableview or model?
Model:
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?
}
Updated 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
}
}
Updated : 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)
}
}
回答1:
You've got a handful of options to accomplish this. Assuming that the selected value is the only value that you've got to pass, using closures would be the easiest thing you could do.
1) Declare a closure that holds a type of your need inside ListViewController
:
`var didSelectItem : ((YourType, IndexPath) -> ())?`
2) In ListViewController
's didSelectRow
method, use the closure:
`self.didSelectItem?(yourDataSourceItemAtIndexpath, indexPath)`
3) You'll get a callback for the triggered closure when you use this closure from your ListViewController
instance inside FirstViewController
like:
let myListInstance = ListViewController()
myListInstance.didSelectItem = { selectedItem, selectedIndex in
//You'll get the selected item inside this block, do model updation here
}
After updating your model with new values, if you want to reload your tableView only at the particular(updated) index, you can use:
self.yourTableView.reloadSections(sections: IndexSet, with: UITableView.RowAnimation)
to reload a whole section or..
self.yourTableView.reloadRows(at: [IndexPath], with: UITableView.RowAnimation)
to reload a row in a section
(If you're performing multiple updates simultaneously, keep in mind that you'll have to do these reloads inside self.yourTableView.beginUpdates()
and self.yourTableView.endUpdates()
)
NOTE:
You'll have to handle your dataSource properly during these reloads to make sure you have the right number of rows or sections before and after the reload, adding/subtracting the rows/sections that you insert/delete. Else, your app will crash!
If you don't want to risk that, just reload the whole table with yourTableView.reloadData()
Also keep in mind that there are other ways to pass data across controllers and this is just a suggestion based on what I assume your use case to be
回答2:
I hardly able to understand your code, it's totally messed up according to me.
I found that most of your code is done and I am adding rest your things that you need to do.
In your
FirstViewController.swift
,didSelectRowAt
func,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)
In
ViewController.swift
,didSelectRowAt
func,// 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)
Now check it should work.
来源:https://stackoverflow.com/questions/59100588/selections-from-list-and-reload-tableview-swift