UITableView has no member 'dequeueReusableCell' - ios

I'm attempting to make a list using a UITableView and am getting the error:
[UITableView] has no member 'dequeueReusableCell'
I have created a table ui with a prototype cell that has the identifier "CellController".
I have initialised my table view at the beginning of my class
#IBOutlet var myTaskListView: [UITableView]!
Then when I'm trying to declare a new cell I'm unable to use dequeueReusableCell
let cell = myTaskListView.dequeueReusableCell(withIdentifier: String(CellController)) as! CellController
Is there something more I have to do to make "dequeueReusableCell" a member of UITableView?
I'm relatively new to Xcode and swift programming, I hope I provided everything needed to help solve the issue.

There is problem with outlet that you have created for your table view.
#IBOutlet var myTaskListView: [UITableView]!
You can try this:
#IBOutlet var yourTableView: UITableView!
let cell : yourCell = self.yourTableView.dequeueReusableCell(withIdentifier: "yourCellIdentifier") as! yourCell

Related

ios Swift ViewController Loaded from Selecting TableView Cell Loses Reference

Full code for this branch here
View controller "MovieDetailsVC" is presented to the navigation controller when a cell is selected.
The presenting view controller, "ViewController", stores the row of the tableView to display in NSUserDefaults as an Int.
"MovieDetailsVC" reads the row ok. It then pulls the whole array of custom class info from CoreData and stores the array row in a property.
The data is displayed ok at first. The IBOutlet connections are setup ok. I've disconnected and reconnected twice all outlets on MovieDetailsVC, so that should be ok.
"viewDidLoad" is called a successive time. Not sure from where. When it is called, the coredata entity and row number are pulled ok.
The issue is at line "lblTitle.text = self.movieRecord.title". I'm assuming any of the IBOutlets would cause the same issue.
The error thrown is what you would see if the outlets were not connected:
fatal error: unexpectedly fond nil while unwrapping Optional value.
code for the MovieDetailsVC is below. Any ideas why this outlet link would break after working ok would be greatly appreciated.
import UIKit
import CoreData
class MovieDetailsVC: UIViewController {
#IBOutlet var lblTitle: UILabel!
#IBOutlet var lblDescr: UILabel!
#IBOutlet var lblLink: UILabel!
#IBOutlet var imgMovie: UIImageView!
var movieRecord:FavMovie!
var favMovies = [FavMovie]()
override func viewDidLoad() {
super.viewDidLoad()
fetchAndSetResult()
}
func fetchAndSetResult() {
let app = UIApplication.sharedApplication().delegate as! AppDelegate
let context = app.managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "FavMovie")
do {
let results = try context.executeFetchRequest(fetchRequest)
self.favMovies = results as! [FavMovie]
} catch let err as NSError {
print(err.description)
}
if let row = NSUserDefaults.standardUserDefaults().objectForKey("movieRow") as? Int {
self.movieRecord = self.favMovies[row]
configureCellDescr()
}
}
func configureCellDescr() {
lblTitle.text = self.movieRecord.title
lblDescr.text = self.movieRecord.descrWhyGood
lblLink.text = self.movieRecord.linkImdb
imgMovie.image = self.movieRecord.getImg()
}
}
I just have a look at your source code in github and find the problem. There are two issues and I will explain it following.
it does that the second time that the app overrides viewdidload
The reason that your code would call the viewDidLoad method twice is because you have a segue in your storyboard that connect the tableViewCell to movieDetailVC. This will present the movieDetailVC once you click the cell.
And in your code for didSelectCell method, you create another movieDetailVC object and present it.
So actually movieDetailVC would be presented twice when you click the cell. This cause the issue.
Any ideas why this outlet link would break after working ok would be greatly appreciated
The reason why the IBOutlet is nil is because of the way you present movieDetailVC in your code. You create the movieDetailVC object using: let movieDetailsVC = MovieDetailsVC(). Doing it this way, the IBOutlets will not be connected correctly, because ios dont know about the storyboard information.
The correct way to create a MovieDetailVC object is to instantiate from storyboard. See this post for difference.
Solution
There is a very simple solution for your code design:
just remove let movieDetailsVC = MovieDetailsVC() and self.navigationController?.presentViewController(movieDetailsVC, animated: true, completion: nil) from your ViewController class. Since you save the selection data in NSUserDefault, the cell segue will present movieDetailVC and your movieDetailVC can also get the selection data from userDefault.

FirebaseUi - Swift - Cast value of UITableViewCell to custom class

I have an issue when working with a custom class for the UITableViewCell with Firebase-UI. Here is my code:
In my TableViewController:
self.dataSource = FirebaseTableViewDataSource(ref: firebaseRef, cellClass: MyEventTableViewCell.self, cellReuseIdentifier: "MyEventTableViewCell", view: self.tableView)
self.dataSource.populateCellWithBlock { (cell, obj) -> Void in
let snap = obj as! FDataSnapshot
print(cell)
let myEventCell = cell as! MyEventTableViewCell
myEventCell.eventNameLabel.text = "hello"
}
In my MyEventTableViewCell:
class MyEventTableViewCell: UITableViewCell {
#IBOutlet weak var eventImageView: UIImageView!
#IBOutlet weak var eventNameLabel: UILabel!
var error:String?
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
I got:
'fatal error: unexpectedly found nil while unwrapping an Optional
value"
on this line:
myEventcell.eventNameLabel.text = "hello"
Weird is that the "print" gives the following output:
<test.MyEventTableViewCell: 0x7dab0400; baseClass = UITableViewCell; frame = (0 0; 320 44); autoresize = W; layer = <CALayer: 0x7be738c0">>
What do we have to do to manage subclass of UITableViewCell?
PS: I am working with the storyboard to define my Custom cell and I am working with Xcode 7.
FirebaseUI developer here:
If you're using storyboards/prototype cells, use the constructor that has the prototypeReuseIdentifier vs the cellReuseIdentifier (see here). This is an unfortunate wart caused by how iOS started doing UICollectionViews but left the UITableView implementation of Storyboards different. TL;DR: Storyboards automatically register the cell reuse identifier for you, and if you try to register it again it'll override it and consider it different, meaning you don't see anything. See the FirebaseUI docs on Using Storyboards and Prototype Cells for more info (though looks like I need to add in the prototype bit, so apologies for the confusion).
It seems you forgot to implement init in your custom cell
For FirebaseUI-ios github
Create a custom subclass of UITableViewCell or UICollectionViewCell, with or without the XIB file. Make sure to instantiate -initWithStyle: reuseIdentifier: to instantiate a UITableViewCell or -initWithFrame: to instantiate a UICollectionViewCell. You can then hook the custom class up to the implementation of FirebaseTableViewDataSource.

passing data from UItableviewController to UItableViewcell

I cannot understand why some values are well passed from the tableViewController to my custom UITableViewCell, and some others are not.
In my UItableviewController.cellForRowAtIndexPath i set up a cell with some values, before returning this cell :
cell.label1.text = myCustomObject.id
cell.label2.text = myCustomObject.path
cell.myCustomObjectCellMember = myCustomObject
cell.pathCellMember = myCustomObject.path
return cell
On the custom UITableViewCell side, in awakeFromNib method, the two first cell members are Ok, the two last ones contain nil.
The only difference between the two first cell members and the two last ones is that the two first are declared as IBOutlet and linked to the storyboard, while the two others are not linked to the UI. But yet, it should be OK to write in these vars from the tableViewController, right ?
Here are the declarations of these variables in the custom UITableViewCell:
#IBOutlet weak var label1: UILabel!
#IBOutlet weak var label2: UILabel!
var pathCellMember : String!
var myCustomObjectCellMember: MyCustomObjectCellMember!
When logged (inside UITableViewCell.awakeFromNib), label1.text and label2.text show the correct value,
but pathCellMember and myCustomObjectCellMember display nil instead of the value assigned in UItableviewController.cellForRowAtIndexPath.
As requested, a more explicit code :
class CustomCellTableViewCell: UITableViewCell {
#IBOutlet weak var label1: UILabel!
#IBOutlet weak var label2: UILabel!
var pathCellMember : String!
var myCustomObjectCellMember: MyCustomObjectCellMember!
override func awakeFromNib() {
super.awakeFromNib()
println("label1 : \(self.label1.text!)") //displays the value assigned
println("label2 : \(self.label2.text!)") //displays the value assigned
println("pathCellMember: \(self.pathCellMember!)") //displays nil
println("myCustomObjectCellMember.path : \(self.myCustomObjectCellMember.path)") //displays `nil`
}
Thank you
In cellForRowAtIndexPath is where you will reuse (deque) each cell. This is where you need to assign your vars values to each cell. While awake does set the initial values they will only fire the first time before the cell is reused. Assign everything in cellForRow or willDisplayCell (background colors, etc).
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/
Discussion
For performance reasons, a table view’s data source should generally reuse UITableViewCell objects when it assigns cells to rows in its tableView:cellForRowAtIndexPath: method. A table view maintains a queue or list of UITableViewCell objects that the data source has marked for reuse. Call this method from your data source object when asked to provide a new cell for the table view. This method dequeues an existing cell if one is available or creates a new one using the class or nib file you previously registered. If no cell is available for reuse and you did not register a class or nib file, this method returns nil.
If you registered a class for the specified identifier and a new cell must be created, this method initializes the cell by calling its initWithStyle:reuseIdentifier: method. For nib-based cells, this method loads the cell object from the provided nib file. If an existing cell was available for reuse, this method calls the cell’s prepareForReuse method instead.

Saving CoreData in UITableViewController but UISlider data is only in the Prototype Cell - how do I pull this over in order to save to CoreData

I have created a tableviewcontroller, with a dynamic prototype cell. Within this view the user has an option to type in a review of a location from a button press as well as can rate the location on a scale of 1 to 10 with a UI Slider. The review is done with a UIAlertController within the tableviewcontroller - but the UISlider is within the cell itself. I am trying to save both pieces of data to core data within the tableviewcontroller. But the UISlider rating value is not available within the tableviewcontroller - is there a way to reference it in tableview from the cell or do I need to have two separate save functions? Here is some of my code thus far - within the tableview controller it doesn't recognize the variable assigned to the UISLider value in the prototype cell. Thanks in advance for any help!
In my tableviewcell:
class WineryInfoTableViewCell: UITableViewCell {
#IBOutlet weak var ratingLabel: UILabel!
#IBOutlet weak var sliderbutton: UISlider!
#IBAction func sliderValueChanged(sender: UISlider) {
var ratingValue = Float(sender.value)
var roundedRatingValue = roundf(ratingValue/0.5)*0.5
ratingLabel.text = "\(roundedRatingValue)"
}
in my tableviewcontroller
#IBAction func save() {
if let managedObjectContext = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext {
myRatingData = NSEntityDescription.insertNewObjectForEntityForName("WineryReview", inManagedObjectContext: managedObjectContext) as wineryReview
myRatingData.wineryName = wineryNames
//myRatingData.rating = ratingLabel.text how do I call this for saving?
myRatingData.review = myRatingEntry
var e:NSError?
if managedObjectContext.save(&e) != true {
println("insert error: \(e!.localizedDescription)")
return
}
}
// If all fields are correctly filled in, extract the field value
println("Winery: " + myRatingData.wineryName)
println("Review: " + myRatingData.review)
//println("Rating: " + ratingLabel.text!) how do I call this for saving?
}
I'm still new at Swift, but I think I may have an answer to a part of your dilemma. To reference the UISlider in your table cell, you can use 'tags' to get a reference to it.
For example:
let cell = tableView.dequeueReusableCellWithIdentifier(TableViewCellIdentifiers.someCell, forIndexPath: indexPath) as UITableViewCell
let slider = cell.viewWithTag(100) as UISlider
In the above example, I would have used assigned the UISlider with a tag of 100, so I am able to get a reference to it using the cell.viewWithTag(100).
Forgive me if this doesn't work!
You could pass a WineryReview object into the cell and set its rating directly from sliderValueChanged.
In cellForRowAtIndex:
cell.wineryReview = myReviewData
In TableViewCell:
#IBOutlet weak var ratingLabel: UILabel!
#IBOutlet weak var sliderbutton: UISlider!
var wineryReview: WineryReview?
#IBAction func sliderValueChanged(sender: UISlider) {
var ratingValue = Float(sender.value)
var roundedRatingValue = roundf(ratingValue/0.5)*0.5
wineryReview.rating = roundedRatingValue
ratingLabel.text = "\(roundedRatingValue)"
}
You could call save on the context from the TableViewController if you like. I did something very similar to this in a project.

Global Variables vs Direct Conection to pass data between view controllers ios

I don't think the title uses the right terminology so I'll try to clarify now.
I have two view controllers which i want to pass data between. view 1 has a tableView and the 2nd view has a MKMapView. Now in the corresponding controllers I want when you click on a cell in view 1 it sends you to the place on the map which the cell indicates eg. a New York cell would send to a map of new York. So I tried in the didSelectRowAtIndexPath that I create an instance of the second controller which would transfer the data to it. But when I did that it would always return a nil value in the second view controller.
So instead I created a 3rd swift file which has some global variables and when I transfer the data via them it works perfectly. Why is this so?
Cheers.
EDIT: Before the I went via a third file
Code for the ViewController 1
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var selectedCell = array[indexPath.row]
var viewController2 = ViewController2()
viewController2.textLabel1 = selectedCell.name
coord.textLabel2 = selectedCell.coordinate
}
Code for ViewController 2
#IBOutlet weak var textLabel1: UILabel!
#IBOutlet weak var textLabel2: UILabel!
Code for View Controller 2 going via 3rd file
#IBOutlet weak var textLabel1: UILabel!
#IBOutlet weak var textLabel2: UILabel!
override func viewDidLoad() {
textLabel1.text = globalVar1
textLabel2.text = globalVar2
}
Code from the 3rd File
var globalVar1: String!
var globalVar2: String!
So from the comments below I take it that in the first way the textLabels hadn't been initialised yet, so the values I assigned to them where turned into nil values. Is this correct? If so how would you do the first way correctly
If I had to guess, and I would because I cannot comment for more info yet(i get in trouble ).
It's because you are trying to assign it to an outlet.
The outlet has not been set yet which means when it is set (I think around ViewDidLoad)
the outlet will be set to nil.
The properties should however be retained if the object hasn't gone out of the heap that is.
PSedu code:
first view :
Your table view
Second View:
your map view
How to work
In you second view:
Add a NSMutableArray *valueArraytoGet in .h file,set its property
#synchronize it in .m file
Now in your first view at didSelectRowAtIndex method
create object of Second View Controller
and assign data as
SecondViewController *object=......
object.valueArraytoGet=[assign ur value array here]....
Hope it will help

Resources