I'm trying to pass data from one tableView to to a static one. I'm not using a segue and using instantiateviewcontrollerwithidentifier
instead, i dont know where i'm going wrong here. I'm using cloudkit and fetching ckRecords from icloud. i have a collectionView first where i tap a cell and displays books corresponding to that cell. However when they are displayed in the cells, i want to tap on the cell to bring up the detailViewController. It's not working at the moment and can't get the head around why.
import CloudKit
class DetailViewController: UITableViewController {
@IBOutlet weak var aboutBookLabel: UILabel!
@IBOutlet weak var bookLengthLabel: UILabel!
@IBOutlet weak var amazonPriceLabel: UILabel!
@IBOutlet weak var ebayPriceLabel: UILabel!
@IBOutlet weak var websitePriceLabel: UILabel!
@IBOutlet weak var authorLabel: UILabel!
@IBOutlet weak var bookTitleLabel: UILabel!
@IBOutlet weak var bookImageView: UIImageView!
var bookRecord: CKRecord?
override func viewDidLoad() {
super.viewDidLoad()
populateData()
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.backgroundColor = UIColor(red: 27.0/255.0, green: 28.0/255.0 , blue: 32.0/255.0, alpha: 1.0)
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
func populateData() {
aboutBookLabel.text = bookRecord?.object(forKey: "description") as? String
bookLengthLabel.text = bookRecord?.object(forKey: "length") as? String
amazonPriceLabel.text = bookRecord?.object(forKey: "amazon") as? String
ebayPriceLabel.text = bookRecord?.object(forKey: "ebay") as? String
websitePriceLabel.text = bookRecord?.object(forKey: "authorPrice") as? String
authorLabel.text = bookRecord?.object(forKey: "author") as? String
bookTitleLabel.text = bookRecord?.object(forKey: "name") as? String
if let imageFile = bookRecord?.object(forKey: "image") as? CKAsset {
bookImageView.image = UIImage(contentsOfFile: imageFile.fileURL.path)
}
}
}
class BooksViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
let cellIdentifier = "bookCell"
var books = [CKRecord]()
var sectorTitle = "language"
override func viewDidLoad() {
super.viewDidLoad()
registerNib()
fetchBooksFromCloud()
configureTableView()
}
func fetchBooksFromCloud() {
books = [CKRecord]()
books.removeAll()
tableView.reloadData()
let cloudContainer = CKContainer.default()
let publicDatabase = cloudContainer.publicCloudDatabase
let predicate = buildBookPredicate()
let query = CKQuery(recordType: "Book", predicate: predicate)
query.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
let queryOperation = CKQueryOperation(query: query)
queryOperation.desiredKeys = ["name", "author", "image", "format", "description", "length", "amazon", "ebay", "authorPrice"]
queryOperation.queuePriority = .veryHigh
queryOperation.resultsLimit = 25
queryOperation.recordFetchedBlock = { (record) -> Void in
self.books.append(record)
}
DispatchQueue.global(qos: .userInteractive).async {
queryOperation.queryCompletionBlock = { (cursor, error) -> Void in
if let error = error {
print("Download failed \(error.localizedDescription)")
return
}
print("Download Successful")
OperationQueue.main.addOperation {
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}
queryOperation.qualityOfService = .userInteractive
publicDatabase.add(queryOperation)
}
private func buildBookPredicate() -> NSPredicate {
return NSPredicate(format:"self contains '\(sectorTitle)'")
}
extension BooksViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return books.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier , for: indexPath) as! BookCell
let book = books[indexPath.row]
let bookName = book.object(forKey: "name") as? String
let authorName = book.object(forKey: "author") as? String
let image = book.object(forKey: "image") as? CKAsset
let formatName = book.object(forKey: "format") as? String
cell.nameLabel.text = bookName
cell.authorLabel.text = authorName
cell.formatLabel.text = formatName
cell.bookImageName.image = UIImage(contentsOfFile: image!.fileURL.path)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let record = books[indexPath.row]
if let detailVC = storyboard?.instantiateViewController(withIdentifier: "DetailVC") as? DetailViewController {
detailVC.bookRecord = record
navigationController?.pushViewController(detailVC, animated: true)
}
tableView.deselectRow(at: indexPath, animated: true)
}
The storyboard
property of UIViewController
represents the storyboard from which the view controller originated. If you want to load another view controller from the same storyboard you can use it.
However, if you want to load the UIViewController
from another storyboard you have to create the UIStoryboard
instance first.
You can do it like this.
UIStoryboard(name: "YourStoryboardName", bundle: nil).instantiateViewController(withIdentifier: "DetailVC")