Reputation: 53
I faced a question when I tried to proceed on passing data from my UITableView to the other UIViewController. What should I do on my "If" statement to be able to pass the data on each selected cell? Can you guys give me a hand?
ViewController:
import UIKit
class ViewController: UIViewController, UICollectionViewDataSource, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var tableViewTopSell: UITableView!
@IBOutlet var collectionView: UICollectionView!
@IBOutlet weak var collectionViewBanner: UICollectionView!
var dataSource: [Content] = [Content]()
var dataBanner: [Banner] = [Banner]()
var dataTopSold: [Top10] = [Top10]()
override func viewDidLoad() {
super.viewDidLoad()
//Delegate TableView
self.tableViewTopSell.delegate = self
//SetupNavBarCustom
self.navigationController?.navigationBar.CustomNavigationBar()
let logo = UIImage(named: "tag.png")
let imageView = UIImageView(image:logo)
self.navigationItem.titleView = imageView
//CallAPIData
getTopSold { (data) in
DispatchQueue.main.async {
self.dataTopSold = data
self.tableViewTopSell.reloadData()
}
}
getBanner { (data) in
DispatchQueue.main.async {
self.dataBanner = data
self.collectionViewBanner.reloadData()
}
}
getAudiobooksAPI { (data) in
DispatchQueue.main.async {
self.dataSource = data
self.collectionView.reloadData()
}
}
}
//CollectionView
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if (collectionView == self.collectionView) {
return self.dataSource.count
}else{
return self.dataBanner.count
}}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if (collectionView == self.collectionView) {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as! CollectionViewCell
let content = self.dataSource[indexPath.item]
cell.bookLabel.text = content.descricao
cell.bookImage.setImage(url: content.urlImagem, placeholder: "")
return cell
}else if (collectionView == self.collectionViewBanner) {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCellBanner", for: indexPath) as! CollectionViewCell
let content = self.dataBanner[indexPath.item]
cell.bannerImage.setImage(url: content.urlImagem, placeholder: "")
return cell
}
return UICollectionViewCell()
}
//TableView
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.dataTopSold.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "topSoldCell", for: indexPath) as! TableViewCell
let content = self.dataTopSold[indexPath.item]
cell.labelNomeTopSell.text = content.nome
cell.imageViewTopSell.setImage(url: content.urlImagem, placeholder: "")
cell.labelPrecoDe.text = "R$ \(content.precoDe)"
cell.labelPrecoPor.text = "R$ 119.99"
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "segueId", sender:self.dataTopSold[indexPath.item])
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueId" {
let des = segue.destination as! TelaDetalheProdutos
des.stringNomeeDesc = sender as? String
}
}
}
extension UIImageView{
func setImage(url : String, placeholder: String, callback : (() -> Void)? = nil){
self.image = UIImage(named: "no-photo")
URLSession.shared.dataTask(with: NSURL(string: url)! as URL, completionHandler: { (data, response, error) -> Void in
guard error == nil else{
return
}
DispatchQueue.main.async(execute: { () -> Void in
let image = UIImage(data: data!)
self.image = image
if let callback = callback{
callback()
}
})
}).resume()
}
}
AudioBook file:
import Foundation
//Categorias
struct Contents : Decodable {
let data : [Content]
}
struct Content : Decodable {
let id : Int
let descricao : String
let urlImagem : String
}
//Banner
struct BannerData : Decodable {
let data : [Banner]
}
struct Banner : Decodable {
let id : Int
let urlImagem : String
let linkUrl : String
}
//Top10
struct Top10Data:Decodable {
let data: [Top10]
}
struct Top10:Decodable {
let id : Int
let nome : String
let urlImagem : String
let descricao : String
let precoDe : Int
}
Detail ViewController:
import UIKit
class TelaDetalheProdutos: UIViewController {
//Properties
@IBOutlet weak var ImageView: UIImageView!
@IBOutlet weak var labelNomeEDesc: UILabel!
@IBOutlet weak var labelDe: UILabel!
@IBOutlet weak var labelPor: UILabel!
@IBOutlet weak var labelNomeProduto: UILabel!
@IBOutlet weak var labelDescricao: UILabel!
//Strings
var stringImageView = String()
var stringNomeeDesc = String()
var stringLabelDe = String()
var stringLabelPor = String()
var stringNomeProduto = String()
var stringlabeDescricao = String()
override func viewDidLoad() {
super.viewDidLoad()
***//What should I do here?***
}
}
[Edit 1]:
I'm doing this way, but I got this crash:
Cannot assign value of type 'Top10' to type 'String'
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "topSoldCell", for: indexPath) as! TableViewCell
let content = self.dataTopSold[indexPath.item]
cell.labelNomeTopSell.text = content.nome
cell.imageViewTopSell.setImage(url: content.urlImagem, placeholder: "")
cell.labelPrecoDe.text = "R$ \(content.precoDe)"
cell.labelPrecoPor.text = "R$ 119.99"
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "segueId", sender:self.dataTopSold[indexPath.row])
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueId" {
let des = segue.destination as! TelaDetalheProdutos
des.stringNomeeDesc = sender as! Top10
}
}
[Edit 3] -SOLVED - What happened was that in Storyboard I linked the UITableViewCell to the other screen instead of linking the ViewController. That's why it appeared twice.
When the screen does the transition after select the cell, the next screen containing the results appear automatically twice. The first time it has empty fields and after 1 second or less there's another automatically transition once again, but this time containing all the data I've passed. The same occur when I click in the "back" TopBar button. What might be happening?
Upvotes: 0
Views: 82
Reputation: 100503
You can try
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "segueId", sender:self.dataTopSold[indexPath.row])
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueId" {
let des = segue.destination as! TelaDetalheProdutos
des.item = sender as! Top10
}
}
//
class TelaDetalheProdutos: UIViewController {
var item:Top10?
}
Upvotes: 2
Reputation:
Save the selected indexpath in did select
In prepare for segue get the data and pass it on to the DetailViewController
//in prepare for segue
let content = self.dataTopSold[indexPath.item]
//cast segue.destination controller to DetailViewController and pass content
guard let detailViewController = segue.destinationViewController as? DetailViewController else {return}
detailViewController.content = content
Upvotes: 0