How to send selected cell to another view controller? - swift

Hey guys so I'm working on an application where I have imported a contacts list from my device and I am given the option to "add" the contact but it really doesn't do much when it comes to functionality. I'm not the best coder so try to hear me out. what I am trying to do is take the data/ selected table view cell and display it on another page. I "think" that this is what I should do because I have tried to display the data on another page but get an error when I move my OVERRIDE function. that makes me believe that I need to take the data, which I believe is newContact? and set that as a variable and then display it on a new page where I can create a new view controller and add the code without error.
I essentially need to figure out what my JSON data is saved as, then set that equivalent to a string if that is possible, so I can send it to my new view controller or and send it to my database with code I already have created.
I am just not sure where to enter the statements because of errors that I am getting and what the exact code would be.
Sorry for the awful description of what I am trying to perform, I have a grasp of what is needed to be done but I am a beginner.
My Master View Controller that takes the contacts from my phone and accesses them.
import UIKit
import Contacts
import ContactsUI
class MainViewController: UIViewController {
#IBOutlet weak var textField: UITextField!
#IBOutlet weak var tableView: UITableView!
var store = CNContactStore()
var contacts: [CNContact] = []
override func viewDidLoad() {
super.viewDidLoad()
}
//MARK: - User Actions
#IBAction func contactListPressed(_ sender: AnyObject) {
let contactPickerViewController = CNContactPickerViewController()
contactPickerViewController.delegate = self
present(contactPickerViewController, animated: true, completion: nil)
}
#IBAction func addContactPressed(_ sender: AnyObject) {
let newContact = CNMutableContact()
newContact.givenName = "Apps"
newContact.familyName = "Foundations"
newContact.nickname = "AF"
if let image = UIImage(named: "logo-apps-foundation.jpg"),
let data = UIImagePNGRepresentation(image){
newContact.imageData = data
}
let phone = CNLabeledValue(label: CNLabelWork, value: CNPhoneNumber(stringValue: "+441234567890"))
newContact.phoneNumbers = [phone]
let email = "" //Your Input goes here
let Email = CNLabeledValue(label:CNLabelWork, value: email as NSString)
newContact.emailAddresses = [Email]
newContact.jobTitle = "Apps Foundation"
newContact.organizationName = "Apps Foundation"
newContact.departmentName = "IT"
let facebookProfile = CNLabeledValue(label: "Facebook", value: CNSocialProfile(urlString: "https://www.facebook.com/appsfoundation", username: "AppsFoundation", userIdentifier: "appsfoundation", service: CNSocialProfileServiceFacebook))
let twitterProfile = CNLabeledValue(label: "Twitter", value: CNSocialProfile(urlString: "https://twitter.com/AppsFoundation", username: "AppsFoundation", userIdentifier: "appsfoundation", service: CNSocialProfileServiceTwitter))
newContact.socialProfiles = [facebookProfile, twitterProfile]
let skypeProfile = CNLabeledValue(label: "Skype", value: CNInstantMessageAddress(username: "AppsFoundation", service: CNInstantMessageServiceSkype))
newContact.instantMessageAddresses = [skypeProfile]
var birthday = DateComponents()
birthday.year = 1991
birthday.month = 1
birthday.day = 1
newContact.birthday = birthday
let request = CNSaveRequest()
request.add(newContact, toContainerWithIdentifier: nil)
do {
try store.execute(request)
let alert = UIAlertController(title: "Contacts iOS 9", message: "New contact has been created", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alert, animated: true, completion: nil)
} catch let error{
print(error)
}
}
#IBAction func textFieldValueChanged(_ sender: AnyObject) {
if let query = textField.text {
findContactsWithName(query)
}
}
//MARK: - Private Methods
func findContactsWithName(_ name: String) {
AppDelegate.sharedDelegate().checkAccessStatus({ (accessGranted) -> Void in
if accessGranted {
DispatchQueue.main.async(execute: { () -> Void in
do {
let predicate: NSPredicate = CNContact.predicateForContacts(matchingName: name)
let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactBirthdayKey, CNContactViewController.descriptorForRequiredKeys()] as [Any]
self.contacts = try self.store.unifiedContacts(matching: predicate, keysToFetch:keysToFetch as! [CNKeyDescriptor])
self.tableView.reloadData()
}
catch {
print("Unable to refetch the selected contact.")
}
})
}
})
}
func updateContact(_ contactIdentifier: String) {
do {
let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactBirthdayKey, CNContactPhoneNumbersKey, CNContactViewController.descriptorForRequiredKeys()] as [Any]
let contact = try store.unifiedContact(withIdentifier: contactIdentifier, keysToFetch:keysToFetch as! [CNKeyDescriptor])
let contactToUpdate = contact.mutableCopy() as! CNMutableContact
contactToUpdate.phoneNumbers = [CNLabeledValue(label: CNLabelWork, value: CNPhoneNumber(stringValue: "+440987654321"))]
let saveRequest = CNSaveRequest()
saveRequest.update(contactToUpdate)
try store.execute(saveRequest)
} catch let error{
print(error)
}
}
}
//MARK: - UITableViewDataSource
extension MainViewController: CNContactPickerDelegate {
func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
let selectedContactID = contact.identifier
updateContact(selectedContactID)
}
}
//MARK: - UITableViewDataSource
extension MainViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return contacts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let CellIdentifier = "MyCell"
let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier)
cell!.textLabel!.text = contacts[indexPath.row].givenName + " " + contacts[indexPath.row].familyName
if let birthday = contacts[indexPath.row].birthday {
let formatter = DateFormatter()
formatter.dateStyle = DateFormatter.Style.long
formatter.timeStyle = .none
cell!.detailTextLabel?.text = formatter.string(from: ((birthday as NSDateComponents).date)!)
}
return cell!
}
}
//MARK: - UITableViewDelegate
extension MainViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let controller = CNContactViewController(for: contacts[indexPath.row])
controller.contactStore = self.store
controller.allowsEditing = false
self.navigationController?.pushViewController(controller, animated: true)
}
}
I know I need to incorporate something like this but I am not sure where or how to set the JSON data to a variable or the correct type and then incorporate code of this type
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
if let indexPath = self.tableView.indexPathForSelectedRow {
let controller = segue.destination as! ViewControllerB
controller.selectedName = objects[indexPath.row]
}
}
}
sorry for the awful explanation. any help possible would be appreciated, I have been struggling for quite some time.

First of all, you need to have the other view controller that you are trying to pass data to. It can either be on the Interface Builder or done programmatically (I'll assume it's on the IB for now). Then you'll need to setup a segue between the Main VC and the Details VC and give it an identifier e.g. showDetail.
Next would be to determine the data that Details VC needs for it to work properly. You can have individual variables for each data item (e.g. name, age, phone, email, etc) but usually if there is a lot of info, it's best to use a data model. In your case, since you are trying to display contact info, you can simply reuse CNContact.
So you simply need a CNContact in your Details VC that you'll set before transitioning from Main VC in the prepareForSegue function. And to initiate the segue, all you have to do is call performSegue function.
Hope that at least gives you some direction

Related

Testing tableview.reloadData()

while using a MockTableView this code still not calling reloadData() from the mock,
please i wanna know what is wrong here.
following this book: Test-Driven IOS Development with Swift 4 - Third Edition
page 164, i was as an exercise
full code repo - on github
ItemListViewController.swift
import UIKit
class ItemListViewController: UIViewController, ItemManagerSettable {
#IBOutlet var tableView: UITableView!
#IBOutlet var dataProvider: (UITableViewDataSource & UITableViewDelegate &
ItemManagerSettable)!
var itemManager: ItemManager?
override func viewDidLoad() {
super.viewDidLoad()
itemManager = ItemManager()
dataProvider.itemManager = itemManager
tableView.dataSource = dataProvider
tableView.delegate = dataProvider
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
}
#IBAction func addItem(_ sender: UIBarButtonItem) {
if let nextViewController =
storyboard?.instantiateViewController(
withIdentifier: "InputViewController")
as? InputViewController {
nextViewController.itemManager = itemManager
present(nextViewController, animated: true, completion: nil)
}
}
}
ItemListViewControllerTest.swift
import XCTest
#testable import ToDo
class ItemListViewControllerTest: XCTestCase {
var sut: ItemListViewController!
var addButton: UIBarButtonItem!
var action: Selector!
override func setUpWithError() throws {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier:
"ItemListViewController")
sut = vc as? ItemListViewController
addButton = sut.navigationItem.rightBarButtonItem
action = addButton.action
UIApplication.shared.keyWindow?.rootViewController = sut
sut.loadViewIfNeeded()
}
override func tearDownWithError() throws {}
func testItemListVC_ReloadTableViewWhenAddNewTodoItem() {
let mockTableView = MocktableView()
sut.tableView = mockTableView
guard let addButton = sut.navigationItem.rightBarButtonItem else{
XCTFail()
return
}
guard let action = addButton.action else{
XCTFail()
return
}
sut.performSelector(onMainThread: action, with: addButton, waitUntilDone: true)
guard let inputViewController = sut.presentedViewController as?
InputViewController else{
XCTFail()
return
}
inputViewController.titleTextField.text = "Test Title"
inputViewController.save()
XCTAssertTrue(mockTableView.calledReloadData)
}
}
extension ItemListViewControllerTest{
class MocktableView: UITableView{
var calledReloadData: Bool = false
override func reloadData() {
calledReloadData = true
super.reloadData()
}
}
}
You inject a MockTableview Then you call loadViewIfNeeded(). But because this view controller is storyboard-based and the table view is an outlet, the actual table view is loaded at this time. This replaces your MockTableview.
One solution is:
Call loadViewIfNeeded() first
Inject the MockTableview to replace the actual table view
Call viewDidLoad() directly. Even though loadViewIfNeeded() already called it, we need to repeat it now that we have a different tableview in place.
Another possible solution:
Avoid MockTableview completely. Continue to use a real table view. You can test whether it reloads data by checking whether the number of rows matches the changed data.
Yet another solution:
Avoid storyboards. You can do this with plain XIBs (but these lack table view prototype cells) or programmatically.
By the way, I see all your tearDownWithError() implementations are empty. Be sure to tear down everything you set up. Otherwise you will end up with multiple instances of your system under test alive at the same time. I explain there here: https://qualitycoding.org/xctestcase-teardown/

In Xcode 11.4, I Cannot Hide A Button

So I am trying to make an Painting app that can store the data that user gives (such as name of the painting, artist of the painting, year of the painting and image of the painting) and shows in a table view. I have 2 view controllers, first one is called ViewController that has a table view for showing the data (only name of the painting for the table view cell) and the second one is called DetailedVC which is for entering and saving the data, also showing the details of the data. In the second view controller I added 3 text fields, 1 image view that enables the user to go the photo library and a save button. I wrote this in my DetailedVC script for when the user taps one of the elements from the table view in my ViewController:
override func viewDidLoad() {
super.viewDidLoad()
if chosenPainting != "" {
savebutton.isHidden = true //Trying to hide the save button here!!
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Paintings")
let idString = chosenPaintingId?.uuidString
fetch.predicate = NSPredicate(format: "id = %#", idString!)
fetch.returnsObjectsAsFaults = false
do {
let results = try context.fetch(fetch)
if results.count > 0 {
for result in results as! [NSManagedObject] {
if let name = result.value(forKey: "name") as? String {
nameText.text = name
}
if let artist = result.value(forKey: "artist") as? String {
artistText.text = artist
}
if let year = result.value(forKey: "year") as? Int {
yearText.text = String(year)
}
if let imageData = result.value(forKey: "image") as? Data {
let imageD = UIImage(data: imageData)
imageView.image = imageD
}
}
}
} catch {
print("error")
}
} else {
savebutton.isEnabled = false
nameText.text = ""
artistText.text = ""
yearText.text = ""
}
I get the information from my ViewController like this:
#objc func AddButtonTapped(){
selectedPainting = ""
performSegue(withIdentifier: "toDetailedVC", sender: self)
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedPaintingId = ids[indexPath.row]
selectedPainting = names[indexPath.row]
performSegue(withIdentifier: "toDetailedVC", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toDetailedVC" {
let destination = segue.destination as! DetailedVC
destination.chosenPainting = selectedPainting
destination.chosenPaintingId = selectedPaintingId
}
}
It works just fine below the savebutton.isHidden = true. I don't understand why the button is not disappearing. Everything else works correctly, text field's texts turn into the information that user gave but, the button is standing still right in the bottom. And even the savebutton.isEnabled = false is working. I thought there must be a problem with connection between my script and my storyboard so I deleted and did it again, but it didn't work again. I must have doing something wrong, can you help me about this?

pass Data When Long Press in Table view Cell

there is a Table View to show phone contact . i want to send phone number and email to another View Controller when Long Pressed the Cell . Long Press Work Correctly But I cant Pass Data to another View Controller .
enter image description here
VC 1 :
override func viewDidLoad() {
super.viewDidLoad()
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longpress))
tbMain.addGestureRecognizer(longPress)
}
Long Press Method for table view cell :
#objc func longpress(sender: UILongPressGestureRecognizer) {
if sender.state == UIGestureRecognizer.State.began {
let touchPoint = sender.location(in: tbMain)
if tbMain.indexPathForRow(at: touchPoint) != nil {
let cell = tbMain.dequeueReusableCell(withIdentifier: "testCell") as! NewContactCell
print("Long press Pressed:)")
self.actionVC = self.storyboard!.instantiateViewController(withIdentifier: "ActionsViewController") as? ActionsViewController
UIView.transition(with: self.view, duration: 0.25, options: [.transitionCrossDissolve], animations: {
self.view.addSubview( self.actionVC.view)
}, completion: nil)
}
}
}
VC 2 :
internal var strPhoneNUmber : String!
internal var strEmail : String!
override func viewDidLoad() {
super.viewDidLoad()
print("Phone: \(strPhoneNUmber!)")
// Do any additional setup after loading the view.
}
Get phone number and email from cell object
self.actionVC.strPhoneNUmber = cell.strPhoneNUmber // get phone number from cell object
self.actionVC. strEmail = cell.strEmail // get email from cell object
code would be like
#objc func longpress(sender: UILongPressGestureRecognizer) {
if sender.state == UIGestureRecognizer.State.began {
let touchPoint = sender.location(in: tbMain)
if tbMain.indexPathForRow(at: touchPoint) != nil {
let cell = tbMain.dequeueReusableCell(withIdentifier: "testCell") as! NewContactCell
print("Long press Pressed:)")
self.actionVC = self.storyboard!.instantiateViewController(withIdentifier: "ActionsViewController") as? ActionsViewController
**self.actionVC.strPhoneNUmber = cell.strPhoneNUmber // get phone number from cell object
self.actionVC. strEmail = cell.strEmail // get email from cell object**
UIView.transition(with: self.view, duration: 0.25, options: [.transitionCrossDissolve], animations: {
self.view.addSubview( self.actionVC.view)
}, completion: nil)
}
}
}
I don't see when your trying to pass the data.. you have quite a few way to perform that action first you can use delegation to achieve passing the data
protocol YourDelegate : class {
func passData(phoneNumber: String, email: String)
}
weak var delegate: YourDelegate?
#objc func longpress(sender: UILongPressGestureRecognizer) {
if sender.state == UIGestureRecognizer.State.began {
let touchPoint = sender.location(in: tbMain)
if tbMain.indexPathForRow(at: touchPoint) != nil {
let cell = tbMain.dequeueReusableCell(withIdentifier: "testCell") as! NewContactCell
print("Long press Pressed:)")
self.actionVC = self.storyboard!.instantiateViewController(withIdentifier: "ActionsViewController") as? ActionsViewController
self.delegate = self
**delegate?.passData(cell.strPhoneNumber, cell.strEmail)**
UIView.transition(with: self.view, duration: 0.25, options: [.transitionCrossDissolve], animations: {
self.view.addSubview( self.actionVC.view)
}, completion: nil)
}
}
}
class ???: UIViewController, YourDelegate {
var strPhoneNUmber : String!
var strEmail : String!
override func viewDidLoad() {
super.viewDidLoad()
print("Phone: \(strPhoneNUmber!)")
// Do any additional setup after loading the view.
}
func passData(phoneNumber: String, email: String) {
handle...
}
}
its not clear to me if the actionVC is the one you want to pass the data to but if so you have an instance.. just set the properties but ill still recommend sticking with the delegation pattern
actionVC.strPhoneNumber = cell.strPhoneNumber
or use a segue
self.performSegue(withIdentifier: "yourIdentifier", sender: arr[indexPath.row])
use prepare for segue to create an instance to set his properties according to the sender..
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destvc = segue.destination as? YourClass
destvc.phoneNumber = sender.phoneNumber as? String
destvc.email = sender.email as? String
}

Tableview keeps going back to top? After leaving to "detailed" vc?

How can I prevent the view controller from starting from the top of the feed when a user leaves and goes back?
Basically, I have the main VC and a detailed VC. When the user selects a cell, it should jump to the detailed VC. If she/he goes back, it should leave her back to where she/he was.
I get that my code is calling "reload Data" every time the VC loads, but what other options do I have then if I don't call that method?
Here's an image of my main storyboard if it helps. Main VC(left) is the feed tableView where the user can tap on the cell. When he/she taps on the cell, it "segues" to the comment table VC (right). When he/she is done commenting she/he can go back to the main VC and continuing going down the feed. (ideally, except it keeps loading from the newest post, rather than segueing the user back to where she/he was down in the feed)
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostCell
let post: PostModel
post = postList[indexPath.row]
func set(post: PostModel) {
ImageService.downloadImage(withURL: post.author.patthToImage) { image in
cell.profileImage.image = image
}
}
set(post: postList[indexPath.row])
cell.descriptionLabel.numberOfLines = 0 // line wrap
cell.descriptionLabel.lineBreakMode = NSLineBreakMode.byWordWrapping
cell.descriptionLabel.text = post.message
cell.authorLabel.text = post.author.username
cell.timeLabel.text = post.createdAt.calendarTimeSinceNow()
//takes care of post image hidding and showing
if self.postList[indexPath.row].pathToImage != "" {
cell.postImage.isHidden = false
cell.postImage?.downloadImage(from: self.postList[indexPath.row].pathToImage)
} else {
cell.postImage.isHidden = true
}
if cell.postImage.isHidden == true {
cell.postImage.frame = CGRect(x: 0, y: 0, width: 0, height: 0)
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let post: PostModel
post = postList[indexPath.row]
myIndex = indexPath.row
myPost = post.postID!
performSegue(withIdentifier: "segue", sender: self)
print(myIndex)
print(post.postID)
}
override func viewDidLoad() {
super.viewDidLoad()
beginBatchFetch()
}
func beginBatchFetch() {
fetchingMore = true
fetchPosts { newPosts in
self.postList.append(contentsOf: newPosts)
self.endReached = newPosts.count == 0
self.fetchingMore = false
self.tableViewPost.reloadData()
}
}
func fetchPosts(completion: #escaping(_ postList:[PostModel])->()) {
ref = Database.database().reference().child("posts")
var queryRef:DatabaseQuery
let lastPost = self.postList.last
if lastPost != nil {
let lastTimestamp = lastPost!.createdAt.timeIntervalSince1970 * 1000
queryRef = ref.queryOrdered(byChild: "timestamp").queryEnding(atValue: lastTimestamp).queryLimited(toLast:20)
} else {
queryRef = ref.queryOrdered(byChild: "timestamp").queryLimited(toLast:20)
}
queryRef.observeSingleEvent(of: .value, with: { snapshot in
var tempPosts = [PostModel]()
for child in snapshot.children {
if let childSnapshot = child as? DataSnapshot,
let dict = childSnapshot.value as? [String:Any],
let author = dict["author"] as? [String:Any],
let uid = author["uid"] as? String,
let username = author["username"] as? String,
let fullname = author["fullname"] as? String,
let patthToImage = author["patthToImage"] as? String,
let url = URL(string:patthToImage),
let pathToImage = dict["pathToImage"] as? String,
let likes = dict["likes"] as? Int,
let postID = dict["postID"] as? String,
let message = dict["message"] as? String,
let genre = dict["genre"] as? String,
let timestamp = dict["timestamp"] as? Double {
let userProfile = UserProfile(uid: uid, fullname: fullname, username: username, patthToImage: url)
let post = PostModel(genre: genre, likes: likes, message: message, pathToImage: pathToImage, postID: postID, userID: pathToImage, timestamp: timestamp, id: childSnapshot.key, author: userProfile)
tempPosts.insert(post, at: 0)
}
}
//first two
self.postList = tempPosts
self.tableViewPost.reloadData()
// return completion(tempPosts)
})
The issue, as Matt pointed out, is that you are segueing to the detailVC and then segueing back to the original VC. This is creating a new instance of the original VC.
What you should do, in your VC with the table view, is instantiate and present the destination view controller when a cell is selected. So you should replace performSegue(withIdentifier: "segue", sender: self) with something like:
let storyboard = UIStoryboard(name: "Main", bundle: .main)
var destinationVC = (storyboard.instantiateViewController(withIdentifier: "DestinationVC") as! DestinationViewController)
present(destinationVC!, animated: ture, completion: nil)
NOTE: View Controller storyboard identifiers can be set in the interface builder. So, if you are wanting to use this line: var destinationVC = (storyboard.instantiateViewController(withIdentifier: "DestinationVC") as! DestinationViewController), you will first have to set the Storyboard ID in the interface builder:
Now, within your destination view controller, instead of segueing when your done button is pressed, you want to use the dismiss method to dismiss the presented view controller.
class DestinationViewController: UIViewController {
#IBAction func backButtonPressed(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
}
Now, the original VC with the table view stays in memory while the destination VC is presented over it. When the user presses the "back" button, it will dismiss the destination VC and the original VC should reappear as you left it.
"I added a "back" button to segue back" That's the problem. The way to go back is to call dismiss — not use a second segue (unless it is a special "unwind" segue, but you don't know how to do that).

Why delegate event is not received swift?

I would like to pass data from EditPostViewController to NewsfeedTableViewController using delegates, but func remove(mediaItem:_) is never called in the adopting class NewsfeedTableViewController. What am I doing wrong?
NewsfeedTableViewController: UITableViewController, EditPostViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
//set ourselves as the delegate
let editPostVC = storyboard?.instantiateViewController(withIdentifier: "EditPostViewController") as! EditPostViewController
editPostVC.delegate = self
}
//remove the row so that we can load a new one with the updated data
func remove(mediaItem: Media) {
print("media is received heeeee")
// it does't print anything
}
}
extension NewsfeedTableViewController {
//when edit button is touched, send the corresponding Media to EditPostViewController
func editPost(cell: MediaTableViewCell) {
let editPostVC = storyboard?.instantiateViewController(withIdentifier: "EditPostViewController") as? EditPostViewController
guard let indexPath = tableView.indexPath(for: cell) else {
print("indexpath was not received")
return}
editPostVC?.currentUser = currentUser
editPostVC?.mediaReceived = cell.mediaObject
self.navigationController?.pushViewController(editPostVC!, animated: true)
}
protocol EditPostViewControllerDelegate: class {
func remove(mediaItem: Media)
}
class EditPostViewController: UITableViewController {
weak var delegate: EditPostViewControllerDelegate?
#IBAction func uploadDidTap(_ sender: Any) {
let mediaReceived = Media()
delegate?.remove(mediaItem: mediaReceived)
}
}
The objects instantiating in viewDidLoad(:) and on edit button click event are not the same objects. Make a variable
var editPostVC: EditPostViewController?
instantiate in in viewDidLoad(:) with delegate
editPostVC = storyboard?.instantiateViewController(withIdentifier: "EditPostViewController") as! EditPostViewController
editPostVC.delegate = self
and then present it on click event
navigationController?.pushViewController(editPostVC, animated: true)
or
present(editPostVC, animated: true, completion: nil)
you can pass data from presenter to presented VC before or after presenting the VC.
editPostVC.data = self.data
I suggest having a property in NewsfeedTableViewController
var editPostViewController: EditPostViewController?
and then assigning to that when you instantiate the EditPostViewController.
The idea is that it stops the class being autoreleased when NewsfeedTableViewController.viewDidLoad returns.