What am I doing wrong on trying to set data to Struct - swift

I'm trying to create a Struct to be able to pass data between screens. However, when I set data to my Struct properties and then I try to use it in another screen I got the value as "nil". What am I doing wrong?
Objects Struct:
import UIKit
struct Objetos {
var nome: String
var foto: UIImage
}
That's how I'm trying to set the value:
var objeto = Objeto(nome: "", foto: UIImage())
#IBAction func botaoAdcItem(_ sender: UIButton) {
if (self.namePreview!.text != nil) && (self.imagePreview!.image != nil) {
objeto?.nome = self.namePreview.text!
objeto?.foto = self.imagePreview.image!
self.navigationController?.popViewController(animated: true)
}
else { return }
}
That's how I'm trying to read the data:
class ViewController: UIViewController, CLLocationManagerDelegate, UITableViewDataSource {
#IBOutlet weak var itensTableView: UITableView!
var arrayNomes = NSMutableArray()
var objeto: Objetos?
var objetos = [Objetos]()
//TableView
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
for nome in objetos {
arrayNomes.add(nome)
}
return arrayNomes.count //Nil value
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = itensTableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! tableviewCell
cell.nameCell.text = objeto?.nome //Nil value
cell.imageViewCell.image = objeto?.foto //Nil value
return cell
}
override func viewDidAppear(_ animated: Bool) {
self.itensTableView.reloadData()
}
Storyboard:

In your second code snippet, you never initialize objetos to anything. Thus, when you try to set one of the properties on objetos, nothing happens, because objetos doesn't exist.
Solution: Initialize objetos before trying to use it.

You can try this if you want to set the data to the previous VC
// ! won't crash
let count = self.navigationController.viewControllers!.count
let tab = self.navigationController.viewControllers![count-2] as! UITabBarController
let vc = tab.viewControllers![0] as! ViewController
vc.objetos.append(Objetos(name:self.namePreview.text!,foto:self.imagePreview.image!))
self.navigationController?.popViewController(animated: true)
plus
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = objectos[indexPath.row]
let cell = itensTableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! tableviewCell
cell.nameCell.text = item.nome //Nil value
cell.imageViewCell.image = item.foto //Nil value
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return objetos.count
}

Try to replace
var objetos:Objetos?
with
var objeto = Objetos(nome: "", foto: UIImage())
you are starting your object as optional, and thus from the start is nil. When you try to assign properties in your struct you are failures because the object from the beginning is nonexistent
Regarding you other nil values, here is a revised view of your snippet
class ViewController: UIViewController, CLLocationManagerDelegate, UITableViewDataSource {
#IBOutlet weak var itensTableView: UITableView!
var objetos = [Objetos]()
//TableView
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return objetos.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = itensTableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! tableviewCell
let objeto = objectos[indexPath.row]
cell.nameCell.text = objeto.nome
cell.imageViewCell.image = objeto.foto
return cell
}
override func viewWillAppear(_ animated: Bool) {
self.itensTableView.reloadData()
}
In your Additional Novo Itens Vc you are going to need to pass the created data back to your original View Controller, one way to do this is
#IBAction func botaoAdcItem(_ sender: UIButton) {
if (self.namePreview!.text != nil) && (self.imagePreview!.image != nil) {
// create the objecto
var objeto = Objetos(nome: namePreview.text,
foto: imagePreview.image)
// create a reference to your previous view controller
let vc = self.navigationController?.viewControllers[0] as! ViewController
// add objecto to objectos
vc.objetos.append(objeto)
self.navigationController?.popViewController(animated: true)
}
else { return }
}

Related

How to delete a cell in the tableview from another View controller?

I am trying to delete a cell in the tableview from another view controller. I have modeled my code similar to the question posted below but I still can't seem to successfully delete the selected row/cell in the CalorieVC when the delete button is pressed in the DeleteVC
Deleting a row of a tableview from another viewcontroller
SideNote: there is button in the cells to popup the DeleteVC, I am also getting an error upon pressing the the deleteBtn in the CalorieVC: DeleteRowInTableviewDelegate on let picked saying Thread 1: Fatal error: Index out of range
import UIKit
class CalorieViewController: UIViewController {
var selectedFood: FoodList! // allows data to be passed into the CalorieVC
var deleteItems: CalorieItem? // passes data to DeleteVC
// allows data to be sepearted into sections
var calorieItems: [CalorieItem] = []
var groupedCalorieItems: [String: [CalorieItem]] = [:]
var dateSectionTitle: [String] = []
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView.dataSource = self
tableView.delegate = self
// Allows data in cells to seperate by section
groupedCalorieItems = Dictionary(grouping: calorieItems, by: {$0.foodList.date})
dateSectionTitle = groupedCalorieItems.map{$0.key}.sorted()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "DeleteSegue" {
let vc: DeleteViewController = segue.destination as! DeleteViewController
vc.deleteItems = self.deleteItems
// vc.delegate = self
}
}
}
extension CalorieViewController: UITableViewDelegate, UITableViewDataSource{
func numberOfSections(in tableView: UITableView) -> Int {
return dateSectionTitle.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let date = dateSectionTitle[section]
return groupedCalorieItems[date]!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let calorieCell = tableView.dequeueReusableCell(withIdentifier: "CalorieCell") as! CalorieCell
let date = dateSectionTitle[indexPath.section]
let caloriesToDisplay = groupedCalorieItems[date]![indexPath.row]
calorieCell.configure(withCalorieItems: caloriesToDisplay.foodList)
return calorieCell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let calorieHeader = tableView.dequeueReusableCell(withIdentifier: "CalorieHeader") as! CalorieHeader
let headerTitle = dateSectionTitle[section]
calorieHeader.dateLbl.text = "Date: \(headerTitle)"
return calorieHeader
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 45
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let calorieFooter = tableView.dequeueReusableCell(withIdentifier: "CalorieFooter") as! CalorieFooter
//Cell Total Code
let date = dateSectionTitle[section]
let subtotal = groupedCalorieItems[dispensary]?.map { $0.getCalorieTotal() }.reduce(0, +) ?? 0
calorieFooter.calorieTotal.text = String(subtotal!)
return calorieFooter
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 150
}
}
extension CalorieViewController: DeleteRowInTableviewDelegate {
func deleteRow(inTableview rowToDelete: Int) {
let picked = dateSectionTitle[rowToDelete]
let selectedCell = groupedCalorieItems[dod]
delete(selectedCell)
// calorieItems.remove(at: rowToDelete) // tried using this and I get an error code upon segueing back to the CalorieVC
tableView.reloadData()
}
}
import UIKit
protocol DeleteRowInTableviewDelegate: NSObjectProtocol {
func deleteRow(inTableview rowToDelete: Int)
}
class DeleteViewController: UIViewController {
var modifyItems: CartItem!
var delegate: DeleteRowInTableviewDelegate?
#IBOutlet weak var deleteLbl: UILabel!
#IBOutlet weak var deleteBtn: UIButton!
#IBOutlet weak var cancelBtn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if isMovingFromParent {
delegate!.deleteRow(inTableview: 1)
}
deleteLbl.text = "Are you sure you want to delete this Food Item from your calorie List?"
}
#IBAction func decline(_ sender: Any) {
dismiss(animated: true)
delegate!.deleteRow(inTableview: 1)
print("Delete Item")
}
#IBAction func cancel(_ sender: Any) {
dismiss(animated: true)
print("Cancel Delete")
}
}
Remove the value from the dataSource
Remove the table cell
extension CalorieViewController: DeleteRowInTableviewDelegate {
func deleteRow(inTableview rowToDelete: Int) {
if caloriesItems.count > rowToDelete {
calorieItems.remove(at: rowToDelete)
tableView.deleteRows(at: [IndexPath(row: rowToDelete, section: 0)], with: .automatic)
} else {
print("index not present")
}
}
}
Do not call reloadData just to delete one row. This is a bad practice.
Use deleteRows instead.

tableview to tableview protocol delegates

I am trying to finish this app that is a form. once filled out a button later will be pushed for print. The first controller has a tableview that has page 1 page 2 page 3. page 1 opens and you fill in all info. when hit save it should take you back to first controller. then when you push print opens the tableview and loads all info.
I am struggling to use structs correctly. also struggling on the save button to the delegate to the print controller page.
my page controller code
class PagesController: UIViewController, UITableViewDelegate {
var pages = ["Page 1","Page 2","Page 3"]
#IBOutlet weak var pagesTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
pagesTableView.delegate = self
pagesTableView.dataSource = self
}
#IBAction func printBtnPressed(_ sender: Any) {
} }
extension PagesController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return pages.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PagesCell")
cell?.textLabel?.text = pages[indexPath.row]
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
performSegue(withIdentifier: "ChildInfoSegue", sender: self)
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 90.0
}
}
Heres my form controller
protocol ChildDelegate {
func saveInfoBlock(form: ChildInfo)
}
class ChildInfoTableViewController: UITableViewController {
var formDelegate: ChildDelegate!
var firstNameText: UITextField = UITextField()
var lastNameText: UITextField = UITextField()
var middleNameText: UITextField = UITextField()
//MARK: From ChildInfo.swift STRUCT
var childInfo = [ChildInfo]()
var basicChildInfo = ["Child's First Name","Child's Middle Name","Child's Last Name"]
override func viewDidLoad() {
super.viewDidLoad()
}
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return basicChildInfo.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ChildInfoCell") as! ChildInfoTableViewCell
cell.formLabel.text = basicChildInfo[indexPath.row]
return cell
}
//MARK: Segue to printController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let path = self.tableView.indexPathForSelectedRow!
let destViewController = segue.destination as! PrintPageTableViewController
}
//MARK: Cancel Button Pressed
#IBAction func cancelBtnPressed(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
#IBAction func saveBtnPressed(_ sender: Any) {
let firstname = firstNameText.text ?? ""
let middlename = middleNameText.text ?? ""
let lastname = lastNameText.text ?? ""
let formData = ChildInfo(cFirstName: firstname, cMiddleName: middlename, cLastName: lastname)
self.navigationController?.popViewController(animated: true)
formDelegate.saveInfoBlock(form: formData)
saveInfoBLock()
}
func saveInfoBLock() {
print("Saving Info")
dismiss(animated: true, completion: nil)
}
}
Heres my struct that I don't properly use
struct ChildInfo {
var childFirstName: String?
var childMiddleName: String?
var childLastName: String?
var childsMadeUpName: String = ""
init(cFirstName: String, cMiddleName: String, cLastName: String) {
self.childFirstName = cFirstName
self.childMiddleName = cMiddleName
self.childLastName = cLastName
}
}
and lastly my tableviewcell
class ChildInfoTableViewCell: UITableViewCell {
#IBOutlet weak var formText: UITextField!
#IBOutlet weak var formLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
Once the delegate protocol gets passed. What would a put in the printtableviewcontroller to make the data show? I had someone help me on here, but It was all programmatically and I'm no that advanced yet.
There are several things you can do:
Use delegation. I am assuming this is what you want to achieve here.
Pass your data through Segues. ( Recommended )
To use delegation, you have to have a clear concept of how delegation works.
Here is a link to an explanation I gave someone on another site. It breaks it down, I think this may help you a bit.
https://teamtreehouse.com/community/totally-confused-with-the-example-used
For now, I think the solution to your problem is to use Segues.
When you tap on the button to take you to the ChildInfoTableViewController where you fill the information is where you want to create your "ChildInfo" object. Then when you press save, you trigger the segue and pass the "ChildInfo" object to the "PagesController".
Then from there, that same object should be pass through the segue into the print view.

Why is JSON data from local path shows incorrectly in the UITableView?

I want to parse JSON data from a local file that is available in the project and then populate these data to UITableView.
My Requirements
parse the json data from local path not from URL
Populate the json data to UITableView
Facing problems
Unable to display the parsed data, ( bracket is displaying in the table view.
I am able to print the data in console using dump() but unable to print data in tableView
Updated view controller for passing data to another controller.
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return lookArrayModel.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cells = myTableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let displayData = lookArrayModel[indexPath.row]
cells.textLabel?.text = String(describing: displayData.Lookname!)
cells.detailTextLabel?.text = String(describing: displayData.Lookdetails!)
// print(displayData.shadeModel)
return cells
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("You selected cell #\(indexPath.row)!")
// Get Cell Label
let indexPath = myTableView.indexPathForSelectedRow;
let currentCell = myTableView.cellForRow(at: indexPath!) as UITableViewCell!;
lookNameValue = currentCell?.textLabel?.text
lookDetailValue = currentCell?.detailTextLabel?.text
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
//let lookShade = LookModelData()
if (segue.identifier == "segueToLook") {
let destController:DetailsViewController = segue.destination as! DetailsViewController
//Set the selecte row index value
destController.LabelText = String(describing: lookNameValue)
destController.DetailText = String(describing: lookDetailValue)
// destController.arrayData = lookShade.shadeModel as! NSMutableArray
}
}
}
Destination view controller. Swift
class DetailsViewController:UIViewController,UITableViewDataSource,UITableViewDelegate {
var lookArrayModel = [LookModelData]()
var arrayData: NSMutableArray = []
#IBOutlet weak var secondView: UITableView!
var LabelText = String()
var DetailText = String()
var shadeText = String()
#IBOutlet weak var LookLabel: UILabel!
#IBOutlet weak var LookName: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
print(arrayData)
LookName?.text = LabelText
LookLabel?.text = DetailText
secondView.dataSource = self
secondView.delegate = self
secondView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayData.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cells = secondView.dequeueReusableCell(withIdentifier: "secondCell", for: indexPath)
let displayData = arrayData
// cells.textLabel?.text = String(describing: (displayData as AnyObject))
// print(arrayData)
return cells
}
}
Please check my code :
Changed lookArrayModel type NSMutableArray to [LookModelData]. Like those I did some changes. Please check.
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var lookArrayModel = [LookModelData]()
#IBOutlet weak var myTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
guard let Path = Bundle.main.path(forResource: "ColorShade", ofType: "json") else { return }
let url = URL(fileURLWithPath: Path)
do {
let data = try Data(contentsOf: url)
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
myTableView.dataSource = self
myTableView.delegate = self
//Calling the function for adding look
createLooks(dictionary: json as! NSArray)
myTableView.reloadData()
} catch {
print(error)
}
}
func createLooks(dictionary:NSArray) {
for item in dictionary {
let item1 = item as! NSDictionary
let lookModal = LookModelData()
lookModal.Lookname = item1.value(forKey: "Lookname") as? String
lookModal.LookId = item1.value(forKey: "LookId") as? String
lookModal.Lookdetails = item1.value(forKey: "Lookdetails") as? String
lookModal.shadeModel = createshade(shades: item1.value(forKey: "shades") as! NSArray)
lookArrayModel.append(lookModal)
}
}
func createshade(shades: NSArray) -> [ShadeDescription] {
var arrayShade = [ShadeDescription]()
for item in shades
{
let item1 = item as! NSDictionary
let shadeModal = ShadeDescription()
shadeModal.comboID = item1.value(forKey: "comboID") as? String
shadeModal.shadeName = item1.value(forKey: "shadeName") as? String
shadeModal.ShadeType = item1.value(forKey: "ShadeType") as? String
shadeModal.ShadeCode = item1.value(forKey: "shadeCode") as? String
arrayShade.append(shadeModal)
}
return arrayShade
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return lookArrayModel.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cells = myTableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let displayData = lookArrayModel[indexPath.row]
// You will get like this
// print(displayData.LookId!)
// print(displayData.Lookname!)
// print(displayData.Lookdetails!)
// print(displayData.shadeModel!)
// This is the way to get shade model data
if let shadeModels = displayData.shadeModel {
for var shadeModel in shadeModels {
print(shadeModel.comboID)
print(shadeModel.ShadeType)
print(shadeModel.shadeName)
print(shadeModel.ShadeCode)
}
}
cells.textLabel?.text = String(describing: displayData.Lookname!)
return cells
}
}
class LookModelData
{
var Lookname:String?
var LookId:String?
var Lookdetails:String?
//Shades Array
var shadeModel : [ShadeDescription]?
}
class ShadeDescription {
var ShadeType:String?
var shadeName:String?
var comboID:String?
var ShadeCode:String?
}

Swift 3.0 Autocomplete Address For Search Bar

I am interested in using a tableView to list possible addresses based on inputs in the search bar. After selecting the cell that contains the address desired, the search bar text consists of the address, however I want the possible addresses (cells) to disappear. Does self.searchResultsTableView.reloadData() in didSelectRowAt clear all the cells or is there another command? I am not certain how to clear the cells after selecting the appropriate address without iterating and having the suggestion introduce more cells.
import UIKit
import MapKit
class SearchViewController: UIViewController {
#IBOutlet weak var searchBar: UISearchBar!
var searchCompleter = MKLocalSearchCompleter()
var searchResults = [MKLocalSearchCompletion]()
var searchSource: [String]?
#IBOutlet weak var searchResultsTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
searchCompleter.delegate = self
searchBar.delegate = self
}
}
extension SearchViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchCompleter.queryFragment = searchText
}
}
extension SearchViewController: MKLocalSearchCompleterDelegate {
func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
searchResults = completer.results
searchResultsTableView.reloadData()
}
func completer(_ completer: MKLocalSearchCompleter, didFailWithError error: Error) {
// handle error
}
}
extension SearchViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return searchResults.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let searchResult = searchResults[indexPath.row]
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
cell.textLabel?.text = searchResult.title
cell.detailTextLabel?.text = searchResult.subtitle
return cell
}
}
extension SearchViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let completion = searchResults[indexPath.row]
let searchRequest = MKLocalSearchRequest(completion: completion)
let search = MKLocalSearch(request: searchRequest)
search.start { (response, error) in
let coordinate = response?.mapItems[0].placemark.coordinate
print(String(describing: coordinate))
print(response?.mapItems)
self.searchBar.text = response?.mapItems[0].name
}
self.searchResultsTableView.reloadData()
}
}
If you want to clear your tableView then you need to make your datasource array empty and then reload the tableView.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let completion = searchResults[indexPath.row]
let searchRequest = MKLocalSearchRequest(completion: completion)
let search = MKLocalSearch(request: searchRequest)
search.start { (response, error) in
let coordinate = response?.mapItems[0].placemark.coordinate
print(String(describing: coordinate))
print(response?.mapItems)
self.searchBar.text = response?.mapItems[0].name
}
//Make empty your array ant then reload tableView
searchResults = []
self.searchResultsTableView.reloadData()
}

Data not passing in Swift

I'm working on a journal app and now I want people to be able to click on a cell/entry and then go to a more detailed view where they can read/edit their entry. The thing is, the strings I'm trying to pass to the next view aren't coming through.
Edit:
This is the code on the TableViewController:
class TableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var items: [Entry] = []
var passedEntry:String = ""
func fetchData() {
do {
items = try context.fetch(Entry.fetchRequest())
print(items)
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch {
print("Couldn't fetch data")
}
}
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as UITableViewCell
let date = items.reversed()[indexPath.row].date
cell.textLabel?.text = items[indexPath.row].title
if let date = date {
let dateStamp = "Added on \(date)"
cell.detailTextLabel?.text = dateStamp
}
return cell
}
#objc(tableView:editActionsForRowAtIndexPath:) func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .default, title: "Delete") { (action, indexPath) in
// delete item at indexPath
let item = self.items[indexPath.row]
self.context.delete(item)
(UIApplication.shared.delegate as! AppDelegate).saveContext()
self.items.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
}
return [delete]
}
public func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
if (segue.identifier == "showEntry") {
// initialize new view controller and cast it as your view controller
let viewController = EntryViewController()
// your new view controller should have property that will store passed value
viewController.passedEntry = passedEntry
}
}
public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
passedEntry = items[indexPath.row].title!
self.performSegue(withIdentifier: "showEntry", sender: self)
}
override func viewWillAppear(_ animated: Bool) {
fetchData()
}
This is the code on the EntryViewController which still prints nil:
class EntryViewController: UIViewController {
var passedEntry:String!
#IBOutlet weak var dreamTitle: UITextView!
#IBOutlet weak var dreamPost: UITextView!
#IBAction func saveChanges(_ sender: Any) {
}
override func viewWillAppear(_ animated: Bool) {
print(passedEntry)
}
I'm sorry for being a newbie, but I need some more detailed instructions...
Two issues:
The signature of prepareForSegue is wrong for Swift 3.
Never create view controllers with the default initializer when using storyboard
This main issue occurs in this line:
let viewController = EntryViewController()
You are creating a brand new instance of EntryViewController which is not the controller in the storyboard. You have to use the destination view controller of the segue:
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showEntry" {
// initialize new view controller and cast it as your view controller
let viewController = segue.destination as! EntryViewController
// your new view controller should have property that will store passed value
let title = items[indexPath.row].title
viewController.passedEntry = title
}
}
And I recommend to declare the string in the destination view controller as non-optional empty string rather than an implicit unwrapped optional. Non-optional types will never crash the app.
var passedEntry = ""
You are defining prepareForSegue() as a local function inside the tableView-function. It will not be used. Put a debugger breakpoint into it and see yourself if it will be reached.