'UITableView' does not have a member in dequeneResusableCell - swift

I can't figure out how to solve this. It keeps throwing an error with the dequeneResuableCell. I've tried every variable available. I have xcode 6. I removed the outlets, because they are not the problem and I have not included the constructor/iniitalization for the HospitalList class.
This is the code
import UIKit
class HospitalList: UIViewController {
#IBOutlet weak var hospitals: UITableView!
var Hos: [Hospital] = []
override func viewDidLoad() {
super.viewDidLoad()
Hos = createArray()
hospitals.delegate = self
hospitals.dataSource = self
}
func createArray() -> [Hospital] {
\\more code to create an array of Information
return tempHospitals
}
}
extension HospitalList: UITableViewDelegate, UITableViewDataSource {
//counts number of elements in Table View
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return Hos.count
}
//sets up whats in the table view
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let Hop = Hos[indexPath.row]
// this line is the problem right here
let cell = tableView.dequeueReusableCell(withIdentifier: "InfoHospitals")
cell.HName.text = Hop.name \\and more, but not including
return cell
}
return UITableViewCell
}

Related

Problem using an extension to load image into a custom cell

My last question for today. I'm too newby with swift to know what's happening but my problem is as follows:
I've use the next extension to load an image from a URL and it works when I use it in a imageView in a normal view, but when the imageView is inside of a custom cell It doesn't recognize de method so I can`t use the extension. What am I doing wrong? Thank you all in advances.
My code for the extesion is:
import UIKit
extension UIImageView {
func loadFrom(URLAddress: String) {
guard let url = URL(string: URLAddress) else {
return
}
DispatchQueue.main.async { [weak self] in
if let imageData = try? Data(contentsOf: url) {
if let loadedImage = UIImage(data: imageData) {
self?.image = loadedImage
}
}
}
}
}
And the code for the table where I try to use it into a custom cell:
import UIKit
class EventosCustomCellController: UITableViewCell {
#IBOutlet weak var imEvento: UIView!
#IBOutlet weak var txtNombreEvento: UILabel!
#IBOutlet weak var txtFechaEvento: UILabel!
#IBOutlet weak var txtEstadoEvento: UILabel!
}
class ListaEventosTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Eventos"
}
// MARK: - Table view data source
override func viewWillAppear(_ animated: Bool) {
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return eventos.contarEventos()
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "prototipoCeldaEvento", for: indexPath) as! EventosCustomCellController
let evento = eventos.buscarEventoPorID(id: indexPath.row)
cell.txtNombreEvento?.text = evento?.nombre
cell.txtFechaEvento?.text = evento?.fecha
cell.txtEstadoEvento?.text = evento?.tipo
if evento?.tipo == "deportivo"{
cell.backgroundColor = .blue}
else if evento?.tipo == "cultural"{
cell.aplicarFondoDegradado()
cell.backgroundColor = .green}
else{
cell.backgroundColor = .red}
cell.layer.masksToBounds = true
cell.layer.cornerRadius = 10
//There is no method loadFrom when I try to use as follows
cell.imEvento?.loadFrom(URLAddress: (evento?.imagenes![0])!)
return cell
}
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
}
After updating code my problem is that the cell isn`t growthn appropiately
I think, you better use UIImageView instead of UIView because your extension for UIImageView and you can access to this.
#IBOutlet weak var imEvento: UIImageView!
and then it is good to override the prepareForReuse method like this:
override func prepareForReuse() {
super.prepareForReuse()
imEvento.image = nil
}
you can read more about the prepareForReuse method from apple documentation

How do I call a different function for each TextField in a UITableView (Swift)?

I have a UITableView and my prototype cell consists of a label and a TextField. I also have a class MyClass that contains functions func1, func2, fun3, ... I have several ViewControllers that use the same tableViewCell prototype. Each viewController will have an instance of MyClass, called inst1, inst2, and inst3. When I enter text into FirstViewController's TableView I want each row to call a function from the instance of MyClass that corresponds to the row.
So when I enter text into row 1 on the FirstViewController I want to pass the data entered into the textField into func1 of inst1. When data is entered into row 2 of FirstViewController I want the data in the textfield to be passed into func2 of inst1. And so on and so forth down the rows.
I am very new to this and would really appreciate some help figuring out how to do this. Let me know if that doesn't make sense and I can try to rephrase it. I really need help with this. Thanks in advance!
*Updated question to show my code
Below is my Code:
FirstViewController.swift
extension FirstViewController: MyCellDelegate {
func MyCell(_ cell: UITableViewCell, didEnterText text: String) {
if let indexPath = tableView.indexPath(for: cell) {
if (indexPath.hashValue == 0) {
inst1.func1(one: text)
}
if (indexPath.hashValue == 1) {
inst1.func2(two: text)
}
}
totalText.text = inst1.getMyTotal()
}
}
import UIKit
class FirstViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let inst1 = MyClass()
#IBOutlet weak var totalText: UILabel!
#IBOutlet weak var tableView: UITableView!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 11
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myTableCell") as! TableViewCell
let text = cell.cellData[indexPath.row]
cell.myTextField.tag = indexPath.row
cell.delegate = self
cell.myLabel.text = text
cell.myTextField.placeholder = text
return cell
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
TableViewCell.swift
import UIKit
protocol MyCellDelegate: class {
func MyCell(_ cell: UITableViewCell, didEnterText text: String)
}
class TableViewCell: UITableViewCell {
weak var delegate: MyCellDelegate?
public var cellData: [String] = ["1","2","3","4","5","6","7","8","9","10","11"]
#IBOutlet weak var myLabel: UILabel!
#IBOutlet weak var myTextField: UITextField!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
}
}
When I set a breakpoint in the FirstViewController extension it never runs that code.
In WillDisplayCell add the tag to the UITextField. Also create a protocol to notify the Corrosponding viewController and set itself as the delegate here.
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier")
cell.textField.tag = indexPath.row
cell.delegate = self
}
The protocol in your cell class will look something like this
protocol MyCellDelegate: class {
func MyCell(_ cell: UITableViewCell, didEnterText text: String)
}
class MyCell: UITableViewCell, UITextFieldDelegate {
weak var delegate: MyCellDelegate?
override fun awakeFromNib() {
super.awakeFromNib()
textField.delegate = self
}
//All the remaining code goes here
func textFieldShouldReturn(_ textField: UITextField) -> Bool { //delegate method
textField.resignFirstResponder()
delegate?.MyCell(self, didEnterText: textField.text! )
return true
}
}
Now again in your FirstViewController which has conformed to be its delegate do this
extension FirstViewController: MyCellDelegate {
func MyCell(_ cell: UITableViewCell, didEnterText text: String) {
if let indexPath = tableView.indexPathForCell(cell) {
// call whichever method you want to call based on index path
}
}

Some UITableView Delegate methods called 5 times, others not called at all

I have a separate class from a UIViewController set up as my UITableView delegate and my UITableViewDataSource.
I attempt to initialize the UITableViewDelegate class and then assign it to the UITableView.
Here's what's odd...
The methods numberOfSectionsInTableView and tableView(:numberOfRowsInSection) are called five times, while tableView(_:cellForRowAtIndexPath) is never called.
I have verified both numberOfSectionsInTableView and tableView(:numberOfRowsInSection) return values of at least one.
If I move the UITableViewDataSource and UITableViewDelegate methods to the ViewController, the code works correctly.
What is causing this behavior?
class MessagesViewController: UIViewController, ManagedObjectContextSettable {
var managedObjectContext: NSManagedObjectContext!
#IBOutlet var messagesTableView: UITableView!
override func viewDidLoad() {
setupMessagesTableView()
}
private func setupMessagesTableView() {
let dataSource = MessagesTableViewDataSource(managedObjectContext: managedObjectContext, conversationList: fetchedObjects as! [Conversation])
// Assume fetchedObjects is an array fetched from CoreData store. I have removed the code that defines it for the purpose of this example.
self.messagesTableView.dataSource = dataSource
self.messagesTableView.delegate = dataSource
}
}
class MessagesTableViewDataSource: NSObject, UITableViewDataSource, UITableViewDelegate {
var managedObjectContext: NSManagedObjectContext!
var conversationList: [Conversation]
required init(managedObjectContext: NSManagedObjectContext, conversationList: [Conversation]) {
self.managedObjectContext = managedObjectContext
self.conversationList = conversationList
let conversation = Conversation()
self.conversationList.append(conversation)
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.conversationList.count }
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("CellID", forIndexPath: indexPath) as UITableViewCell!
let conversation: Conversation = self.conversationList[indexPath.row]
cell.textLabel!.text = conversation.name as? String
return cell
}
}
The problem is that your instance of MessagesTableViewDataSource gets deallocated. The delegate and dataSource properties on UITableView are weak. You declare your datasource (MessagesTableViewDataSource) as a local variable inside your function and thus nothing holds a strong reference to the instance of MessagesTableViewDataSource.
To fix this, define an instance variable for dataSource and assign it in viewDidLoad.
Example Code:
class MessagesViewController: UIViewController, ManagedObjectContextSettable {
let dataSource: MessagesTableViewDataSource?
var managedObjectContext: NSManagedObjectContext!
#IBOutlet var messagesTableView: UITableView!
override func viewDidLoad() {
setupMessagesTableView()
}
private func setupMessagesTableView() {
dataSource = MessagesTableViewDataSource(managedObjectContext: managedObjectContext, conversationList: fetchedObjects as! [Conversation])
// Assume fetchedObjects is an array fetched from CoreData store. I have removed the code that defines it for the purpose of this example.
self.messagesTableView?.dataSource = dataSource
self.messagesTableView?.delegate = dataSource
}
}
Check the frame of your table view. If the height or width is 0, tableView:cellForRowAtIndexPath: will not be called.
I have the same problem and I believe this to be a bug in UIKit.
I created a simple list data source and a small view Controller to test this and I can confirm that cellForRowAtIndexPath does not get called. 'numberOfRowsInSection' returns a value greater 0 and the tableView's frame is set correctly.
The same code works when put in the view controller. Maybe I'm missing something here, but I think this is a bug on Apple's side.
SimpleListDataSource.swift
import UIKit
class SimpleListDataSource : NSObject, UITableViewDataSource {
var items: [String]
var cellIdentifier: String
typealias CellConfiguration = (UITableViewCell, String) -> ()
var cellConfiguration: CellConfiguration
init(items: [String], cellIdentifier: String, cellConfiguration: CellConfiguration) {
self.items = items
self.cellIdentifier = cellIdentifier
self.cellConfiguration = cellConfiguration
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("Number of rows: \(self.items.count)")
return self.items.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
print(__FUNCTION__)
let cell = tableView.dequeueReusableCellWithIdentifier(self.cellIdentifier, forIndexPath: indexPath)
self.cellConfiguration(cell, self.items[indexPath.row])
return cell
}
}
ViewController.swift
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
let data = ["a", "b", "c"]
let dataSource = SimpleListDataSource(items: data, cellIdentifier: "cell") { (cell, string) -> () in
cell.textLabel?.text = string
}
self.tableView.dataSource = dataSource
self.tableView.reloadData()
}
}

Not able to display anything on table view Swift

This is my history view, I have a tableview inside view controller. But for some reason i can't output anything, I am trying to hardcode it and its not displaying anything at all. One thing i know is i need to make tableView functions override and if i do that i get error.
import UIKit
class History: UIViewController, UITableViewDataSource, UITableViewDelegate
{
#IBOutlet var tableView: UITableView!
override func viewDidLoad()
{
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
self.view.backgroundColor = UIColor(patternImage: UIImage(named: "newBackground.jpg")!)
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("historyCell", forIndexPath: indexPath) as! historyCell
cell.durationLabel.text = "98"
return cell
}
override func viewWillAppear(animated: Bool)
{
super.viewWillAppear(animated)
}
}
heres my class for the cell prototype, and i made sure that the identifier is also "historyCell"
public class historyCell: UITableViewCell{
#IBOutlet var durationLabel: UILabel!
#IBOutlet var kicksLabel: UILabel!
}
How did you connect your prototype cell's controls to the IBOutlets in you historyCell class ? I didn't know that was possible when you're not using a UITableviewController. I've been using tags all this time.
Unless there's something new that I wasn't aware of, your assignment to cell.durationLabel.text should cause unwrapping of a nil (is that the error you're getting ?)

UITableView Prototype cell not found

every one.
After lots of search and different test my code doesn't work yet...
I try to do a simple UITableView with a simple Prototype cell whit using "dequeueReusableCellWithIdentifier" but this function doesn't found my Prototype Cell.
My code :
import Foundation
import UIKit
class DanceClubViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableViewSound: UITableView!
override func viewDidLoad()
{
super.viewDidLoad()
self.tableViewSound.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cellVote")
self.tableViewSound.dataSource = self
self.tableViewSound.delegate = self
self.tableViewSound.reloadData()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
#IBAction func backToViewPlay(sender: AnyObject) {
self.navigationController?.popToRootViewControllerAnimated(true)
}
func tableView(tableView:UITableView, numberOfRowsInSection section:Int)->Int
{
return 10
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var cell : UITableViewCell = self.tableViewSound.dequeueReusableCellWithIdentifier("cellVote") as UITableViewCell
return cell
}
If anyone had already had this problem?
The identifier for my Prototype Cell is : cellVote
The key to address your label is to create a custom TableViewCell class in another file:
import UIKit
class DanceCell: UITableViewCell {
#IBOutlet weak var num: UILabel! //connect the label
}
Then for your ViewController:
import Foundation
import UIKit
class DanceClubViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableViewSound: UITableView!
override func viewDidLoad()
{
super.viewDidLoad()
self.tableViewSound.dataSource = self
self.tableViewSound.delegate = self
self.tableViewSound.reloadData()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
#IBAction func backToViewPlay(sender: AnyObject) {
self.navigationController?.popToRootViewControllerAnimated(true)
}
func tableView(tableViewSound:UITableView, numberOfRowsInSection section:Int)->Int
{
return 10
}
func tableView(tableViewSound: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableViewSound.dequeueReusableCellWithIdentifier("cellVote", forIndexPath: indexPath) as DanceCell
cell.num.text = "Hello"
return cell
}
}
I removed some stuff, and added he key line in the 'cellForRowAtIndexPath' function to register the cell. I then was able to communicate with the label. Make sure the prototype cell has set 'cellVote' as the identifier in at attributes inspector.