Search code examples
iosswiftcrud

Failed to reload and display data in tableview


Firstly, I'm a beginner in Swift and iOS development. This is my first app, which I am working on after learning the basics of Swift and iOS.

Reloading the data in the tableview after adding new data is working properly using Realm. Unfortunately, after an update or deletion, reloading the data in the tableview does not work. Showing the previous data in table view after an update or deletion. Please help.

How the code works or app works:

  1. Home page HomeViewController contains an empty list of data in table view and a button called ADD.
  2. ADD pressed --> jump to add page, having field for title and notes --> DONE pressed --> return to home, reload and display the title in the Data.(This is working)
  3. Using didSelectRowAt it jumps to the DisplayDataViewController, just to view the title and notes in the Data. This page contains EDIT and DELETE button.
  4. EDIT pressed --> jump to edit page ie AddNotesViewController (same page is used for add and edit, that's why I used flagAdd/flagEdit variables) --> after update it goes to home page, and it should be reloaded and display (reloading fails here, no changes in tableview).
  5. DELETE pressed --> goes home, unfortunately reloading fails here also.

And the thing is, CRUD is working properly with the database.

Data

import Foundation
import RealmSwift

@objcMembers class Data: Object {
    dynamic var title = ""
    dynamic var notes = ""
}

HomeViewController:

import UIKit
import RealmSwift

class HomeViewController: UIViewController, RefreshDelegate {

    @IBOutlet var tableViewField: UITableView!
    
    let realm = try! Realm()
    
    var taskView: Results<Data>?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        tableViewField.delegate = self
        tableViewField.dataSource = self
        loadData()
        
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let addVc = segue.destination as! AddNotesViewController
        addVc.flagAdd = 0
        addVc.delegate = self
    }

    func loadData() {
        
        taskView = realm.objects(Data.self)
        tableViewField.reloadData()
        
    }

}




extension HomeViewController: UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return taskView?.count ?? 1
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = taskView?[indexPath.row].title ?? "Empty List"
        return cell
    }
    
    
}




extension HomeViewController: UITableViewDelegate {
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        let displayVc = storyboard?.instantiateViewController(identifier: "displayData") as! DisplayDataViewController
        displayVc.index1 = indexPath.row
        displayVc.viewDetails = taskView![indexPath.row]
        
        navigationController?.pushViewController(displayVc, animated: true)
    }
    
}

AddNotesViewController:

import UIKit
import RealmSwift

protocol RefreshDelegate {
    func loadData()
}

class AddNotesViewController: UIViewController {
    
    @IBOutlet var titleTextField: UITextField!
    @IBOutlet var notesTextView: UITextView!
    
    let realm = try! Realm()
    
    var delegate: RefreshDelegate?
    
    var EditView : Data?
    var index2: Int?
    
    var flagAdd: Int?
    var flagEdit: Int?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
    
    
    override func viewWillAppear(_ animated: Bool) {
        if flagEdit == 1 {
            navigationItem.title = "Edit Page"
            if let myEdit = self.EditView {
                titleTextField.text = myEdit.title
                notesTextView.text = myEdit.notes
            }
        }
    }
        
        
        
        @IBAction func doneButtonPressed(_ sender: UIBarButtonItem) {
            let note = notesTextView.text
            
            if titleTextField.text == ""
            {
                titleTextField.placeholder = "Write Something.."
            }
            
            else if note == "" || note == "Write notes here...." || note == "Sorry! Write Something here."
            {
                notesTextView.text = "Sorry! Write Something here."
            }
            
            else if flagAdd == 0
            {
                let titleText = titleTextField.text
                let notesField = notesTextView.text
                
                let dataRealm = Data()
                dataRealm.title = titleText!
                dataRealm.notes = notesField!
                
                try! realm.write{
                    realm.add(dataRealm)
                }
                delegate?.loadData()
                titleTextField.endEditing(true)
                notesTextView.endEditing(true)
                
                navigationController?.popViewController(animated: true)
            }
            
            else
            {
                let newData = realm.objects(Data.self)[index2!]
                
                try! realm.write {
                    newData.title = titleTextField.text!
                    newData.notes = notesTextView.text
                }
                
                delegate?.loadData()
                
                titleTextField.endEditing(true)
                notesTextView.endEditing(true)
                
                navigationController?.popToRootViewController(animated: true)
                
            }
            
        }
        
        
    }

The same add page is used as an edit page. That's why I used the flagAdd/flagEdit variable.

DisplayDataViewController:

import UIKit
import RealmSwift

class DisplayDataViewController: UIViewController {

    @IBOutlet var DisplayTitleField: UITextField!
    @IBOutlet var DisplayNotesField: UITextView!
    
    let realm = try! Realm()

    var index1 : Int?
    var viewDetails : Data?
    
    var delegate : RefreshDelegate?
    
    override func viewDidLoad() {
        super.viewDidLoad()

    }
    
    override func viewWillAppear(_ animated: Bool) {
        if let myView = self.viewDetails {
            DisplayTitleField.text = myView.title
            DisplayNotesField.text = myView.notes
        }
    }
    
    @IBAction func EditButtonPressed(_ sender: UIButton) {
        let editVc = storyboard?.instantiateViewController(identifier: "goToAdd") as! AddNotesViewController
        editVc.index2 = index1
        editVc.EditView = viewDetails
        editVc.flagEdit = 1
        
        navigationController?.pushViewController(editVc, animated: true)
    }
    
    
    
    @IBAction func deleteButtonPressed(_ sender: UIBarButtonItem) {
        
        try! realm.write {
            realm.delete(viewDetails!)
        }
        
        delegate?.loadData()
        navigationController?.popViewController(animated: true)
        
    }
    
}

Solution

  • HomeViewController, What I did is just add one line of code in didSelectRowAt. Here is the updated didSelectRowAt :

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            tableView.deselectRow(at: indexPath, animated: true)
            
            let dv = (storyboard?.instantiateViewController(identifier: "displayData"))! as! DisplayDataViewController
            
            dv.index1 = indexPath.row
            dv.viewDetails = taskView![indexPath.row]
    
            dv.delegate = self // Newly added code.It solves a problem for deletion.
    
            navigationController?.pushViewController(dv, animated: true)
    }
    

    DisplayDataViewController , Here also I added ev.delegate = delegate. Here is the updated code for EditButtonPressed

    @IBAction func EditButtonPressed(_ sender: UIButton) {
            let ev = storyboard?.instantiateViewController(identifier: "goToAdd") as! AddNotesViewController
            ev.EditView = viewDetails
            ev.index2 = index1!
            ev.flagEdit = 1
    
            ev.delegate = delegate // Newly added code.It solves a problem for updating.
            
            navigationController?.pushViewController(ev, animated: true)    
        }
    

    Finally it's working.