Home > Enterprise >  How do I create new rows in UITableView by passing structs from one ViewController to another?
How do I create new rows in UITableView by passing structs from one ViewController to another?

Time:09-21

I have two ViewControllers. In VC2 you can enter some data and pick an image and when pressing a Button that data image then gets passed as two structs to VC1 and is displayed as a TableViewCell. Now when I enter new data in VC2 the old cell gets overwritten instead of being displayed as a new row (or entry).

I guess I would need to save the struct objects in an array and use the tableView.beginUpdates() and .endUpdates() functions but I'm not sure about the notation and everything I've tried so far didn't work. I'm still a beginner, so I'd appreciate any help.

VC2

import UIKit

protocol SendingBookDataProtocol {
    func sendDataToHomeController(bookEntry: bookItem)
    func sendImageToHomeController(bookImage: bookPreview)
}

struct bookItem {
    let title,author,currentPage,totalPages:String
}

struct bookPreview {
    let image: UIImage
}

class AddBookController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    
    
    var delegate: SendingBookDataProtocol? = nil

 @IBAction func buttonSave(_ sender: Any) {
let bookEntry = bookItem(title: textfieldTitle.text!, author: textfieldAuthor.text!, currentPage: fieldCurrentPage.text!, totalPages: fieldTotalPages.text!)
        
        self.delegate?.sendDataToHomeController(bookEntry: bookEntry)
                  dismiss(animated: true, completion: nil)

}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        
        guard let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else {return}
        
        let bookImage = bookPreview(image: pickedImage)
        
        guard let image = info[.editedImage] as? UIImage else {return}
        
        imageViewAddBook.image = image
        
        
        self.delegate?.sendImageToHomeController(bookImage: bookImage)
                  dismiss(animated: true, completion: nil)
    }

}

VC1

import UIKit

class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SendingBookDataProtocol {

    var item:bookItem?
    var itemImg:bookPreview?

override func viewDidLoad() {
    super.viewDidLoad()
    // some Code
    }

    // tableView Functions

    func sendDataToHomeController(bookEntry item:bookItem) {
       self.item = item
        tableView.reloadData()
    }
    
    func sendImageToHomeController(bookImage itemImg:bookPreview) {
       self.itemImg = itemImg
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return item == nil ? 0 : 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "BookCell", for: indexPath) as! BookCell
        
        cell.title.text = item!.title
        cell.author.text = item!.author
        cell.currentPage.text = item!.currentPage item!.totalPages
        cell.totalPages.text = item!.totalPages
        cell.bookImage.image = itemImg?.image  // Image is optional
        
        return cell
        
    }

        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if segue.identifier == "getBookData" {
                let addBookVC: AddBookController = segue.destination as! AddBookController
                addBookVC.delegate = self
                self.tableView.reloadData()
            }
        }

}

CodePudding user response:

You specifically set the number of row here:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return item == nil ? 0 : 1
}

You explicitly specify 0 of 1 cells. How do you expect to see more than one cell? If you had something like this:

var items = [bookItem]() // This should be BookItem, not bookItem, it's not an instant, it's a type. This is misleading.

...

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    items.count
}

...

func sendDataToHomeController(bookEntry item:bookItem) {
    items.append(item)
    tableView.reloadData()
}

This will add items, not override the single existing one.

  • Related