Passing access from tableViewController to another view controller - swift

I have spent a fair bit of time on this and still can't seem to figure out what I'm doing wrong.
I would like to run the reloadData() function in my own function on another view controller than the tableViewController but I get the error Type 'HomeViewController' has no member 'reloadData'.
HomeViewController:
import UIKit
import CoreData
class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var index = ""
var item : [ListItem] = [] //listName
var listName = [""]
override func viewDidLoad() {
super.viewDidLoad()
self.homeListsTableView.delegate = self
self.homeListsTableView.dataSource = self
homeListsTableView.reloadData()
//List Names
//List Items - Within a list Name
let listItem1 = ListItem()
listItem1.name = "" //Update so names are updated via append the ListItem Array
listItem1.location = ""
item.append(listItem1)
let listItem2 = ListItem()
listItem2.name = ""
listItem2.location = ""
item.append(listItem2)
}
#IBOutlet weak var homeListsTableView: UITableView!
#IBAction func templatesButton(_ sender: Any) {
tabBarController?.selectedIndex = 2
}
override func viewWillAppear(_ animated: Bool) {
if let context = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext {
if let coreDataListItems = try? context.fetch(ListName.fetchRequest()) as? [ListName] {
print(coreDataListItems)
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return listName.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = listName[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// performSegue(withIdentifier: "goToItems", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let vc = segue.destination as! ListNameViewController
vc.homeListsTableViewVC = homeListsTableView
}
}
ListName View Controller:
import UIKit
import CoreData
class ListNameViewController: UIViewController, UITableViewDelegate {
// var listName = [""]
let context = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext
var homeListsTableViewVC = HomeViewController.self
override func viewDidLoad() {
super.viewDidLoad()
}
#IBOutlet weak var listNameValue: UITextField!
#IBOutlet weak var locationOption: UITextField!
#IBOutlet weak var createButtonChange: UIButton!
#IBAction func createButton(_ sender: Any) {
let newList = ListName(context: context!)
newList.listName = listNameValue.text
// let location = locationOption.text!
//tabBarController?.selectedIndex = 0
//performSegue(withIdentifier: "home", sender: nil)
}
func saveList() {
do {
try context!.save()
} catch {
print("Error saving context \(error)")
}
homeListsTableViewVC.reloadData()
}
}
I'm trying to use the prepare for segue function to pass the homeListsTableView data to then use the reloadData() function. Could someone tell me what I'm doing wrong?
Thanks!

You can use delegate or closure to update your tableview.. here is pointers of how you can use closure in your classes to update view
class ListNameViewController: UIViewController, UITableViewDelegate {
var callback: (()->())?
//....
func saveList() {
do {
try context!.save()
} catch {
print("Error saving context \(error)")
}
callback?()
}
}
And while creating ListNameViewController
class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let vc = segue.destination as! ListNameViewController
vc.callback = { [weak self] in
self?.homeListsTableView.reloadData()
}
}
}

Related

How pass data from button in TableViewCell to View Controller?

I have 2 ViewControllers, one of is called ProductListVC the other is MoreInfoVC. I have a tableView on ProductListViewController that shows cells multiple labels and buttons.
MoreInfoVC is a Modal pop-up VC with a few labels for the brand, Name, and description. I have all my data stored in Firestore and already have created class(ProductList) to help retrieve the data which presents the data in the tableview from the Cloud Firestore.
what I need to do is use the MoreInfo button in the individual TBV cell to pass the data into MoreInfoVC so that it can present the information of selected product
Now i can easily do this with either didSelectRowAt method or using indexPathForSelectedRow in prepare segue method. But both cases requires me to tap on the cell itself but not the button.
how would I be able to pass data from an individual tableview cell through the MoreInfo button onto the MoreInfoVC. I think I'm on the right path since it seems my MoreInfoVC is passing data but showing this at the moment
import UIKit
import Firebase
import FirebaseFirestore
class ProductListVC: UIViewController {
#IBOutlet weak var productListTableView: UITableView!
var productInventory: [ProductList] = []
var productSetup: [ProductList] = []
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidLoad() {
super.viewDidLoad()
productListTableView.dataSource = self
productListTableView.delegate = self
searchBar.delegate = self
fetchProducts { (products) in
self.productSetup = products
self.productListTableView.reloadData()
}
}
func fetchProducts(_ completion: #escaping ([ProductList]) -> Void) {
let ref = Firestore.firestore().collection("products")
ref.addSnapshotListener { (snapshot, error) in
guard error == nil, let snapshot = snapshot, !snapshot.isEmpty else {
return
}
completion(snapshot.documents.compactMap( {ProductList(dictionary: $0.data())} ))
}
}
}
extension ProductListVC: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return productSetup.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "ProductListCell") as?
ProductListCell else { return UITableViewCell() }
cell.configure(withProduct: productSetup[indexPath.row])
cell.delegate = self
return cell
}
}
extension ProductListVC: ProductListCellDelegate {
func onTouchInfoButton(from cell: ProductListCell) {
self.selectedProduct = cell.product
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
self.performSegue(withIdentifier: "MoreInfo", sender: self)
}
}
import UIKit
import Firebase
class MoreInfoVC: UIViewController {
var products: ProductList?
#IBOutlet weak var productName: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
productName.text = "\(String(describing: products?.brand)): \(String(describing: products?.name))"
}
#IBAction func closeBtn(_ sender: Any) {
dismiss(animated: true, completion: nil)
print("Close More Information")
}
}
import UIKit
import SDWebImage
import Firebase
protocol ProductListCellDelegate: class {
func onTouchInfoButton(from cell: ProductListCell)
}
class ProductListCell: UITableViewCell {
weak var product: ProductList!
weak var delegate: ProductListCellDelegate?
#IBOutlet weak var productImage: UIImageView!
#IBOutlet weak var productName: UILabel!
#IBOutlet weak var categoryLabel: UILabel!
#IBOutlet weak var strain: UILabel!
#IBOutlet weak var moreInfo: RoundButton!
func configure(withProduct product: ProductList) {
productName.text = "\(String(describing: product.brand)): \(String(describing: product.name))"
categoryLabel.text = product.category
productImage.sd_setImage(with: URL(string: product.imageUrl))
strain.text = product.strain
self.product = product
}
#IBAction func infoButtonAction(_ sender: Any) {
self.delegate?.onTouchInfoButton(from: self)
}
}
Function #IBAction func infoButtonAction(_ sender: Any) {} should be in the ProductListCell
When that button is tapped, connect with the ProductListVC by delegate or closure to get the selected product.
Update
Using delegate:
Update your ProductListCell
import UIKit
import SDWebImage
import Firebase
protocol ProductListCellDelegate: class {
func onTouchInfoButton(from cell: ProductListCell)
}
class ProductListCell: UITableViewCell {
#IBOutlet weak var productImage: UIImageView!
#IBOutlet weak var dispensaryName: UILabel!
#IBOutlet weak var productName: UILabel!
#IBOutlet weak var thcPercent: UILabel!
#IBOutlet weak var cbdPercent: UILabel!
#IBOutlet weak var categoryLabel: UILabel!
#IBOutlet weak var categoryStrain: UILabel!
#IBOutlet weak var moreInfo: RoundButton!
weak var product: Product!
weak var delegate: ProductListCellDelegate?
func configure(withProduct product: ProductList) {
self.product = product
productName.text = "\(String(describing: product.brand)): \(String(describing: product.name))"
dispensaryName.text = product.dispensaryName
categoryLabel.text = product.category
productImage.sd_setImage(with: URL(string: product.imageUrl))
cbdPercent.text = product.cbd
thcPercent.text = product.thc
categoryStrain.text = product.strain
}
#IBAction func infoButtonAction(_ sender: Any) {
self.delegate?.onTouchInfoButton(from: self)
}
}
In your ProductListVC:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "ProductListCell") as?
ProductListCell else { return UITableViewCell() }
cell.configure(withProduct: productSetup[indexPath.row])
cell.delegate = self
return cell
}
extension ProductListVC: ProductListCellDelegate {
func onTouchInfoButton(from cell: ProductListCell) {
let selectedProduct = cell.product
// Do your stuff here
}
}
UPDATE
Because you use segue for navigation so let's create a variable to store your selected product in your ProductListVC
import UIKit
import Firebase
import FirebaseFirestore
class ProductListVC: UIViewController {
#IBOutlet weak var productListTableView: UITableView!
var productInventory: [ProductList] = []
var productSetup: [ProductList] = []
var selectedProduct: Product?
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidLoad() {
super.viewDidLoad()
productListTableView.dataSource = self
productListTableView.delegate = self
searchBar.delegate = self
fetchProducts { (products) in
self.productSetup = products
self.productListTableView.reloadData()
}
}
func fetchProducts(_ completion: #escaping ([ProductList]) -> Void) {
let ref = Firestore.firestore().collection("products")
ref.addSnapshotListener { (snapshot, error) in
guard error == nil, let snapshot = snapshot, !snapshot.isEmpty else {
return
}
completion(snapshot.documents.compactMap( {ProductList(dictionary: $0.data())} ))
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? MoreInforVC {
vc.product = self.selectedProduct
}
}
}
extension ProductListVC: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return productSetup.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "ProductListCell") as?
ProductListCell else { return UITableViewCell() }
cell.configure(withProduct: productSetup[indexPath.row])
cell.delegate = self
return cell
}
}
extension ProductListController: ProductListCellDelegate {
func onTouchInfoButton(from cell: ProductListCell) {
self.selectedProduct = cell.product
self.performSegue(withIdentifier: "YourSegueIdentifier", sender: self)
}
}

Blank labels after data passing in Swift 4?

I am currently trying to pass data from my table view controller to a second view controller but my labels and image are appearing as blank in the second view controller.
This is my main event view controller:
class EventsTableViewController: PFQueryTableViewController {
override func queryForTable() -> PFQuery<PFObject> {
let query = PFQuery(className: "Events")
//query.order(byAscending: "location")
query.order(byAscending: "date")
return query
}
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Upcoming Events"
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "MasterToDetail" {
let detailVC = segue.destination as! DetailViewController
detailVC.myEventCell = sender as? EventCell
}
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath, object: PFObject?) -> PFTableViewCell? {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! EventCell
cell.dateLabel.text = object?.object(forKey: "date") as? String
cell.locationLabel.text = object?.object(forKey: "location") as? String
cell.nameLabel.text = object?.object(forKey: "name") as? String
let imageFile = object?.object(forKey: "image") as? PFFile
cell.eventImage.image = UIImage(named: "download")
cell.eventImage.file = imageFile
cell.eventImage.loadInBackground()
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "MasterToDetail", sender: EventCell())
}
#IBAction func reloadTable(_ sender: Any) {
self.loadObjects()
}
#IBAction func onSignOutTapped(_ sender: Any) {
let firebaseAuth = Auth.auth()
do {
try firebaseAuth.signOut()
performSegue(withIdentifier: "signOutSegue", sender: nil)
} catch {
print (error)
}
}
}
and my second view controller:
class DetailViewController: UIViewController {
#IBOutlet weak var detailImageView: UIImageView!
#IBOutlet weak var detailNameLabel: UILabel!
#IBOutlet weak var detailDescriptionLabel: UILabel!
#IBOutlet weak var detailLocationLabel: UILabel!
var myEventCell: EventCell?
override func viewDidLoad() {
super.viewDidLoad()
setUI()
}
func setUI () {
detailNameLabel.text = myEventCell?.nameLabel.text
detailImageView.image = myEventCell?.eventImage.image
detailLocationLabel.text = myEventCell?.locationLabel.text
}
}
As you send an empty cell here
performSegue(withIdentifier: "MasterToDetail", sender: EventCell())
You need
let cell = tableView.cellForRow(at:indexPath)
performSegue(withIdentifier: "MasterToDetail", sender:cell)

Swift 4 delegates and passing textfield data

I am trying to make an app using the GoogleBooks API where I can use either a title or author or both to search for books. I am currently just working on the delegate portion to be able to pass the search terms to the results table view. However, I am getting errors with the variables I am using being let constants but I have them declared as var so I'm not sure where I am messing up.
This is the UIViewController code for the view with the two search boxes and the button:
import UIKit
protocol ViewControllerDelegate: class {
func searchInput(_ titleFromSearch: String?, authorFromSearch: String?)
}
class ViewController: UIViewController {
#IBOutlet weak var titleFromSearch: UITextField!
#IBOutlet weak var authorFromSearch: UITextField!
weak var delegate: ViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
titleFromSearch.delegate = self
authorFromSearch.delegate = self
}
override func touchesEnded(_ touches: Set<UITouch>, with event:
UIEvent?) {
super.touchesEnded(touches, with: event)
titleFromSearch.resignFirstResponder()
authorFromSearch.resignFirstResponder()
}
}
extension ViewController: UITextFieldDelegate {
func fieldsDidEndEditing(_ titleEntered: UITextField, authorEntered:
UITextField) {
if let delegateController = delegate {
delegateController.searchInput(titleFromSearch.text,
authorFromSearch: authorFromSearch.text)
}
}
}
And this is the code for the TableViewController that I have set up for the results to be displayed in.
import UIKit
import GoogleBooksApiClient
class SearchResultsTableViewController: UITableViewController {
var titleFromSearch: String?
var authorFromSearch: String?
var data = [Volume]()
override func viewDidLoad() {
super.viewDidLoad()
let session = URLSession.shared
let client = GoogleBooksApiClient(session: session)
let req = GoogleBooksApi.VolumeRequest.List(query: "Google")
let task: URLSessionDataTask = client.invoke(
req,
onSuccess: { [weak self] volumes in
self?.data = volumes.items
self?.tableView.reloadData()
},
onError: { error in
print("\(error)") }
)
task.resume()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection
section: Int) -> Int {
return data.count
}
override func tableView(_ tableView: UITableView, cellForRowAt
indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell",
for: indexPath)
let item = data[indexPath.row]
cell.textLabel?.text = item.volumeInfo.title
cell.detailTextLabel?.text = item.volumeInfo.authors.first
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
if let destination = segue.destination as? ViewController {
destination.delegate = self
}
}
}
Here is where I get the let constant error is with these two assignment statements:
extension SearchResultsTableViewController: ViewControllerDelegate {
func searchInput(_ titleFromSearch: String?, authorFromSearch: String?)
{
titleFromSearch = titleFromSearch
authorFromSearch = authorFromSearch
}
}
I added all the code because as I said I am new to iOS and I'm not sure where this error stems from in the code.
In the two lines causing your errors:
titleFromSearch = titleFromSearch
authorFromSearch = authorFromSearch
you are attempting to assign the parameters to themselves. You want to set the parameter values to your properties of the same name. To do this, add self. to the property references:
self.titleFromSearch = titleFromSearch
self.authorFromSearch = authorFromSearch

Swift 3 - Get value from core data

I have a class that will take 2 inputs, Sets and Reps
Using prepare(for segue: UIStoryboardSegue, sender: Any?) I passed the values back to the WorkoutViewController.Swift
The data is successfully saved since after pressing save barbutton in the SetRepsViewController.Swift the window pops
However the labels do not show the values
What am I doing wrong here
I believe that targetLog?.setAndrep?.sets is not correctly getting the value
Can someone please help me on what I should do?
Screenshow of the viewController
WorkoutViewController.swift
import UIKit
import CoreData
class WorkoutViewController: UIViewController{
var muscleLog: MuscleList?
var targetLog: Log?
#IBOutlet weak var LogTableView: UITableView!
#IBOutlet weak var input: UITextField!
#IBOutlet weak var weightInput: UITextField!
#IBOutlet weak var repsInput: UITextField!
#IBOutlet weak var dateView: UILabel!
#IBOutlet weak var setsLabel: UILabel!
#IBOutlet weak var repsLabel: UILabel!
let dateFormatter = DateFormatter()
func workoutTitle(title: String){
self.title = title
}
override func viewDidLoad() {
super.viewDidLoad()
dateFormatter.calendar = Calendar(identifier: .persian)
dateFormatter.dateFormat = "dd/MM/yyyy"
let date = Date()
let dateInPersian = dateFormatter.string(from: date)
dateView.text = dateInPersian
}
override func viewWillAppear(_ animated: Bool) {
setsLabel.text = targetLog?.repLog?.sets
repsLabel.text = targetLog?.setAndrep?.reps
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "addTarget"{
guard let destination = segue.destination as? SetRepsViewController else {
return
}
destination.destLog = targetLog
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//hide keybaord method
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
#IBAction func addLog(_ sender: Any) {
let weight = Double(weightInput.text ?? "") ?? 0.0
let reps = Int16(repsInput.text ?? "") ?? 0
let todayDate = dateView.text ?? ""
let notes = input.text ?? ""
if let log = Log(weight: weight, reps: reps, currentday: todayDate, notes: notes){
muscleLog?.addToDailyLogs(log)
do{
try log.managedObjectContext?.save()
}catch {
print("Could not Log")
}
}
LogTableView.reloadData()
}
func deleteMuscle(at indexPath: IndexPath){
guard let logs = muscleLog?.logList?[indexPath.row],
let managedContext = logs.managedObjectContext else{
return
}
managedContext.delete(logs)
do{
try managedContext.save()
LogTableView.deleteRows(at: [indexPath], with: .automatic)
}catch{
print("Could not save")
LogTableView.reloadRows(at: [indexPath], with: .automatic)
}
}
}
extension WorkoutViewController: UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return muscleLog?.logList?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let WorkCell = LogTableView.dequeueReusableCell(withIdentifier: "WorkCell", for: indexPath)
if let logs = muscleLog?.logList?[indexPath.row] {
WorkCell.textLabel?.text = logs.currentday
let weight = String(logs.weight)
let reps = String(logs.reps)
let note = logs.notes
WorkCell.detailTextLabel?.text = weight + " kg x " + reps + " reps Notes: "+note!
}
return WorkCell
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete{
deleteMuscle(at: indexPath)
}
}
}
SetRepsViewController.swift
import UIKit
class SetRepsViewController: UIViewController {
var destLog: Log?
#IBOutlet weak var setText: UITextField!
#IBOutlet weak var repText: UITextField!
#IBAction func saveTarget(_ sender: UIBarButtonItem) {
let sets = setText.text ?? ""
let reps = repText.text ?? ""
if let target = SetRep(sets: sets, reps: reps){
destLog?.addsetAndrep(target)
do{
try target.managedObjectContext?.save()
self.navigationController?.popViewController(animated: true)
}catch{
print("Could not save workout")
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
#IMan after saving the data in core data you will have to fetch the data from CoreData then you can show your data.
You need to set the value for destLog in your prepareForSegue by determining which row has been selected in your tableView:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "addTarget"{
guard let destination = segue.destination as? SetRepsViewController else {
return
}
let indexPath = LogTableView.indexPathForSelectedRow
targetLog = muscleLog?.logList?[indexPath.row]
destination.destLog = targetLog
}
}
That will ensure that the Log corresponding to the selected row in your table view is passed to the SetRepsViewController. When you dismiss the SetRepsViewController, the viewWillAppear code will update the labels correctly as targetLog and destLog both refer to the same Log object.
#IMan Try this
func fetchList() {
let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let fetchRequest: NSFetchRequest<"YOUR ENTITY NAME"> = ("YOUR ENTITY NAME").fetchRequest()
do {
let fetchResults = try self.moc.fetch(fetchRequest)
for Entity in fetchResults as [NSManagedObject] {
let entity1 = Entity.value(forKey: "YOUR ENTITY KEY VALUE")
let entity12 = Entity.value(forKey: "YOUR ENTITY KEY VALUE")
print(entity1, entity2)
} catch {
print(error.localizedDescription)
}
}

unabe to Reload data in tableview via userdefault

I am a newbie and learning ios programming. I have made a custom table view cell. I am trying to append data in it via user defaults but its not storing the data, every time i go back the app refreshes making the table view blank screen.
// data sent from here
class ViewController: UIViewController {
#IBOutlet weak var textfield: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func submit(_ sender: AnyObject) {
performSegue(withIdentifier: "move", sender: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destination = segue.destination as? secondviewcontroller
destination?.list.append(textfield.text!)
let defaults = UserDefaults.standard
defaults.set(destination?.list, forKey: "listarray")
UserDefaults.standard.synchronize()
}
}
// here i want to retreive
class secondviewcontroller: UIViewController {
#IBOutlet weak var tblView: UITableView!
var list = ["fahad","Ali","tahir"]
var abc = ""
override func viewDidLoad() {
super.viewDidLoad()
tblView.dataSource = self;
tblView.delegate = self;
let storedarray = UserDefaults.standard.object(forKey: "listarray")
print("hi\(storedarray)")
}
override func viewDidAppear(_ animated: Bool) {
tblView.register(TableViewCell.self, forCellReuseIdentifier: "TableViewCell")
tblView.reloadData()
}
#IBAction func backbtn(_ sender: AnyObject) {
dismiss(animated: true, completion: nil)
}
}
import UIKit
class secondviewcontroller: UIViewController {
#IBOutlet weak var tblView: UITableView!
var list = ["fahad","Ali","tahir"]
var abc = ""
override func viewDidLoad() {
super.viewDidLoad()
tblView.dataSource = self;
tblView.delegate = self;
}
override func viewDidAppear(_ animated: Bool) {
tblView.register(TableViewCell.self, forCellReuseIdentifier: "TableViewCell")
let storedarray = UserDefaults.standard.object(forKey: "listarray")
print("hi\(storedarray)")
tblView.reloadData()
}
#IBAction func backbtn(_ sender: AnyObject) {
dismiss(animated: true, completion: nil)
}
}
extension secondviewcontroller : UITableViewDataSource , UITableViewDelegate{
func numberOfSections(in tableView: UITableView) -> Int {
return 1;
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print (list)
return list.count;
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell;
cell.textlabel.text = list[indexPath.row];
return cell;
}
}
// my custom table view
import UIKit
class TableViewCell: UITableViewCell {
#IBOutlet weak var textlabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
}
My UI storyboardgetting this error
you must subclass the UITableViewDelegate and UITableViewDataSource methods and implement the required methods for it to display the data in your custom view.
refer to this: http://clean-swift.com/refactoring-table-view-data-source-and-delegate-methods/
try adding the code for stored array into the viewwillappear method..
These lines recreates the same list with an new element without considering the saved items:
destination?.list.append(textfield.text!)
let defaults = UserDefaults.standard
defaults.set(destination?.list, forKey: "listarray")
UserDefaults.standard.synchronize()
You should instead:
let newEntry = textfield.text!
let defaults = UserDefaults.standard
if destination?.list.count == 3 { //3 because you hardcoded 3 items in next controller
destination?.list.append(newEntry)
} else {
let obj = defaults.object(forKey: "listarray") as? [String] ?? [String]()
destination?.list = obj.append(newEntry)
}
defaults.set(destination?.list, forKey: "listarray")
UserDefaults.standard.synchronize()