问题
In VC#1, I have a UITableView. When I tap on a cell, I am brought to VC#2 where information about that cell is displayed.
I want to be able to press a button in VC#2 which changes the title of the cell it corresponds with in VC#1, but I am confused on how to do this?
Should I create a variable in VC#2 to save the indexPath for the cell that was tapped, and then call a function in VC#1 from VC#2 that uses that indexPath to update the cell? If I did this, wouldn't VC#1 need to be static so I know I'm modifying the right instance of VC#1? I'm using a push segue and a navigation controller to go back, so creating a new instance of VC#1 wouldn't reference the same VC im trying to modify as I believe?
Is there an easier way to do this?
回答1:
You should use the delegate pattern.
VC1 should know what cell that VC2 is showing. You should have an IndexPath
property in VC1 that stores what cell is VC2 currently displaying, right?
Now, create a protocol called VC2Delegate
:
protocol VC2Delegate : class {
func titleDidChange(_ vc2: VC2, to title: String)
}
Now, add this property in VC2:
weak var delegate: VC2Delegate?
Now, when you think the title of the cell should change, call the delegate:
delegate?.titleDidChange(self, to: "Some Title")
That's all for VC2.
Make VC1 conform to VC2Delegate
:
extension VC1: VC2Delegate {
func titleDidChange(_ vc2: VC2, to title: String) {
// set the text of the table cell here...
}
}
Now, when you are passing data to VC2 from VC1, probably in the prepareForSegue
method, do
vc2.delegate = self
Learn more about delegates here.
回答2:
You can pass every data you want through view controllers using delegates
First create a protocol whatever you want
protocol ViewControllerDelegate {
func getSelected(value:Int)
}
Create a variable from your ViewController you want pass the data
var delegate: ViewControllerDelegate?
On didSelectRowAt method you will do
if delegate != nil {
delegate.getSelected(value: indexPath.row)
}
self.navigationController?.popViewController(animated: true)
On ViewController that will receive data you have to do this
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? SecondViewController {
vc.delegate = self
}
}
extension YourViewController: ViewControllerDelegate {
fun getSelected(value:Int) {
// Get value from another view controller and manage it
}
}
This code is in Swift 4
If you don't understand something let me know
回答3:
It's wrong approach you are pursuing. You must separate your data layer from your presentation layer. So in VC#2 you edit your visualized data, then VC#1 reloads the data to update its view.
回答4:
Short answer: You should not do that at all.
View controllers should not modify other view controller's views.
You should modify the data model in VC2, then send a message back to VC1 telling it to update the cell.
(In the push segue you can set up VC1 to be VC2's delegate, then define a protocol that VC2 uses to notify VC1 about the indexPath's of the data model that need to be updated.)
来源:https://stackoverflow.com/questions/48505991/how-to-modify-a-cell-of-uitableview-from-another-viewcontroller