Passing data from tableView to ViewController in Swift
Try this.
ModelViewViewController
var selectedImage:String?
var selectedLabel:String?
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
println("Row \(indexPath.row)selected")
selectedImage = self.tableData[indexPath.row]
selectedLabel = self.tableData[indexPath.row]
performSegueWithIdentifier("detailView", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "detailView") {
var vc = segue.destinationViewController as DetailViewController
vc.img = selectedImage
vc.lblDetail = selectedLabel
}
}
class DetailViewController: UIViewController {
@IBOutlet var imgDetail: UIImage!
@IBOutlet var lblDetail: UILabel!
var img:String?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
imgDetail = UIImage(named: img)
}
This should work.
ios Swift: Passing data from tableView to view controller
You don't need to implement didSelectRow just to pass data through a segue. Assuming you're using Storyboards.
CTRL drag from the prototype TableViewCell in your storyboard to the ViewController you want to pass data to.
Choose Show for the segue type and give it an identifier
Do this in prepareForSegue:
if segue.identifier == "catView" {
if let indexPath = self.tableView.indexPathForSelectedRow {
let controller = segue.destinationViewController as! YourViewController
let value = values[indexPath.row]
controller.catTitleRec = value["NAME"] as! String
}
Swift 4: Passing Data from Tableview to ViewController
Your problem seems simple:
var image = [UIImage]() // lost here
That's an ARRAY of images.
Suggest for a single item, you want a single image?
var image:UIImage!
Warning, will crash if image is nil when used. (alternate use UIImage? but must unwrap).
Therereby, in the table view controller..
vc.image = foodImage[indexPath.section][indexPath.row]
Will be behave as expected. No need to use:
self.itemImage.image = UIImage(named: image) //not working!!! Cant seem to find the right code for this from converting UIIMAGE to String. I am just lost!
(Which is incorrect because you're trying to use an array of images to pass to the STRING parameter of load image from file.)
Just use:
self.itemImage.image = self.image
As they are both image types.
You do the correct thing in the cell and index the array within the array to get the image, so do the same here and have a singe image type in your detail view controller. In that way if you click beef, the image for beef is sent.
As an aside, consider using a data model type for your recipe.
class Ingredient {
var name:String = ""
var image:UIImage! = nil
var count:Int = 0
var calories:Int = 0
public init(name: String, image: UIImage, count: Int, calories: Int) {
self.name = name
self.image = image
self.count = count
self.calories = calories
}
}
then you can do say:
let ingredients = [Ingredient("Beef", beefImage, 100, 350), Ingredient("Onion", onionImage, 1, 20)]
or etc,
Passing data from table view cell to new view controller error
You should trigger this way
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "toUser", sender: indexPath.row)
}
and in prepare for segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
let selectedRow = sender as? Int
if let name = usersArray[selectedRow!].firstLastName{
destination.name = name
}
}
How pass data from button in TableViewCell to View Controller?
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)
}
}
Pass data from tableView Cell to another view controller using delegate protocol
Just simply take a variable for value to be passed in your another Viewcontroller
, then while pushing just pass the value.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
let vc = self.storyboard.instantiateViewController(withIdentifier: "AnotherVC") as! AnotherVC
vc.variable = your value
self.navigationController?.pushViewController(vc, animated: true)
}
Why do you need to use protocols?
How to pass data from a table view cell class back to view controller with the table view?
Use a closure to call back button action from cell to view controller.
CustomCell
class CustomCell : UITableViewCell {
var ClousureBtnActionHandler:((_ sender: AnyObject) -> Void)?
@IBAction func btnInfoActionHandler(_ sender : AnyObject) {
if self.ClousureBtnActionHandler != nil {
self.ClousureBtnActionHandler!(sender)
}
}
}
ViewController
TableView Datasource
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : CustomCell = tableView.dequeueReusableCell(withIdentifier: "CustomCell") as! CustomCell
cell.ClousureBtnActionHandler = { sender in
print("Do any thing with your button action")
}
}
Pass data between TableView and another ViewController in Swift
Your prepareForSegue
must override the UIViewController method which is
func prepare(for segue: UIStoryboardSegue, sender: Any?)
Therefore your method in NewsfeedViewController
should be
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let secondViewController = segue.destination as? EventViewController
secondViewController?.data = sender as? eventStruct
}
it would also be a good idea to add some error checking
Related Topics
Transform a Swift Sequence in to Adjacent Pairs
Expandable Sections Uitableview Indexpath Swift
How to Create an Array of Functions
Make Int Round Off to Nearest Value
Drag and Reorder - Uicollectionview with Sections
iOS 10 Imessage App Extension: How to Calculate the Height of the Extra Tall Navbar
How to Add an Optional String Extension
Distinction Between Private and Fileprivate Top-Level Classes
Multiple Bottom Sheets - the Content Doesn't Load Swiftui
Create Codable Struct with Generic Type
Cannot Load Underlying Module for Xctest
What Is a 'Non-Nominal Type' in Swift
Anonymous Closure Argument Not Contained in a Closure
Swift Instance Member Cannot Be Used on Type
Swift Arrays and Contains, How to Determine If a Collection Contains an Object or Value