when i implement either proposed fix the app crashes when run. When i compile/run the app without the recommended fix the app runs as expected.
the original method is as follows:
func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell {
//this let statement is my original line of code prior to swift 3 conversion and it worked fine
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier:"Cell")
//i've tried using the statement below instead but still getting same error
//let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = userSummaryArray[(indexPath as NSIndexPath).row] as String
cell.textLabel!.font = UIFont(name:"Helvetica Neue", size:17)
cell.accessoryType = .disclosureIndicator
userSummaryTable.rowHeight = 25
return cell
}
after converting to swift 3 in Xcode8 i'm now getting a warning on this method that reads:
Instance method 'tableView(_:cellForIndexPath:)' nearly matches optional requirement 'tableView(_:heightForRowAt:)' of protocol 'UITableViewDelegate'
There are two options recommended to "fix" the warning:
Make 'tableView(_:cellForIndexPath:)' private to silence this warning
OR
Add '#nonobjc' to silence this warning
Both of these "fixes" crash the app. the original code works fine in the new swift and worked fine in the older version of swift. what are these recommendations?
Any help is very much appreciated.
Make that
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
instead of
func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell {
Xcode is trying to help you but does not recognize that
I had the same issue. Along with Lu_s answer, make sure you add UITableViewDataSource to the class.
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { }
Related
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = companyTableView.dequeueReusableCell(withIdentifier: "cell")
}
I get this Error: "Initialization of immutable value 'cell' was never used; consider replacing with assignment to '_' or removing it."
I used "cell" as identifier for my TableViewCell. How can I fix it?
The error message really says it all: you're assigning a value to the constant cell but never use that value.
Also, the function tableView(:cellForRowAt:) is declared as returning a UITableViewCell instance, which you never do.
Fixing both problems leads to this code:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
// do stuff with the cell
return cell
}
I want to use https://github.com/intuit/AnimatedFormFieldTableViewCell in my project but I can’t get my head around the steps for setting it up. So far, I’ve dragged the files from the folder and followed the steps as:
In order to use AnimatedFormFieldTableViewCell, all you have to do is:
1) Register the AnimatedFormFieldTableViewCell nib on the ViewController on which you are implementing your UITableView for your reuse identifier.
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.registerCellNib(AnimatedFormFieldTableViewCell)
tableView.reloadData()
}
2) Dequeue your cell on CellForRowAtIndexPath as a AnimatedFormFieldTableViewCell.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! AnimatedFormFieldTableViewCell
return cell
}
3) Change the placeholder's label text by calling setLabelText on the cell itself.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! AnimatedFormFieldTableViewCell
cell.setLabelText("Enter title")
return cell
}
Notes:
1) You can still implement UITextFieldDelegate the same way you would implement on a regular UITextField, you just need to define the AnimatedFormFieldTableViewCell's delegate (there is no need to directly define the delegate for the embedded UITextField).
2) In order to access the embedded UITextField you can simply call the cell's cellTextField property.
I don’t get these last two steps.
If I run my app, I get the unexpectedly found nil on self.cellTextfield.delegate = self in the AnimatedFormFieldTableViewCell class.
What am I missing?
Hi waseefakhtar your code does not miss anything. just the only problem is you registered the nib with the wrong way that's why you got the unexpectedly found nil error on self.cellTextfield.delegate = self.
try this code:
let myNib = UINib.init(nibName: "AnimatedFormFieldTableViewCell", bundle: nil)
self.tableView.registerNib(myNib, forCellReuseIdentifier: "cell")
PS: just be aware that registerNib method syntax can differ depending on the swift version
My code is here, I don't know where you clerical error, but you can check my code to find out:
import UIKit
class ViewController2: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// register a nib like below
let nib:UINib = UINib.init(nibName: "AnimatedFormFieldTableViewCell", bundle: nil)
self.tableView.register(nib, forCellReuseIdentifier: "AnimatedFormFieldTableViewCell")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 88.0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "AnimatedFormFieldTableViewCell", for: indexPath as IndexPath) as! AnimatedFormFieldTableViewCell
cell.setLabelText("Enter title")
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
}
The result:
So, just check the steps, where you go wrong.
The documentation notes this:
There is no need to directly define the delegate for the embedded UITextField
The instruction is to do the following:
You just need to define the AnimatedFormFieldTableViewCell's delegate
You'll want to set the AnimatedFormFieldTableViewCell's delegate rather than the cellTextField's delegate, so:
self.delegate = yourUITextViewDelegate
rather than self.cellTextField.delegate = yourUITextViewDelegate (this is wrong)
This is what the documentation describes
Edit: OP clarified that the delegate assignment code is not in their class; it's in the pod's class. I'm considering deleting this answer as I don't think it is solving the problem.
I am coming to you for a little issue I have, that might actually not be that complicated but that i have struggled about for now about an hour...
I defined a TableViewCell in a TableViewController. This TableViewCell has three UIImage and two textLabels. I implemented the following methods :
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return fruits.count
}
(which in my sense defines the number of rows)
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "friendListCell")
cellOutlet.nameTextLabel.text = fruits[indexPath.row]
return cell!
}
On this second method, the "cellOutlet" is an instance of the class that defines my cell, in which I modify one of the textLabel's text.
"fruits" is a simple array of Strings that are supposed to be displayed in every cell of my app one by one.
Compilation goes fine, but when accessing the page in question, the app crashes saying
unexpectedly found nil while unwrapping an Optional value
My question is the following :
Would you have any idea of what is done wrong in term of accessing my textLabel's text ?
Thanks in advance !
If you're using a custom TableViewCell class you have to
Set the class of the cell in Interface Builder to the custom class
Cast the cell accordingly in cellForRow... (assuming the name is MyTableViewCell)
let cell = tableView.dequeueReusableCell(withIdentifier: "friendListCell" for:indexPath) as! MyTableViewCell
Try to call
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "friendListCell")
cell.nameTextLabel.text = fruits[indexPath.row]
return cell!
}
and also check "cell" should not be nil at the time of calling cell.nameTextLabel.text = fruits[indexPath.row]
Even if your custom UITableViewCell class (e.g. FruitsCell) has some labels, the standard UITableViewCell doesn't (apart from one, which is its 'label' property). In your code, the 'cell' property is of type UITableViewCell, which has no cellOutlet or nameTextLabel property to access.
If you set up your custom cell in IB, be sure to connect all your labels from IB with the code in your Swift-File, e.g. FruitsCell.swift, that contains the FruitsCell class.
Then cast the 'cell' in your ViewControllers delegate method as e.g. FruitCell instead of UITableViewCell. Only then you can access the labels of that class that you set up in IB.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// casting to your Class
let cell = tableView.dequeueReusableCell(withIdentifier: "friendListCell") as! FruitCell
// accessing that Class' properties
cell.nameTextLabel.text = fruits[indexPath.row]
// returning cell of type FruitCell
return cell!
}
I already know the solution for my problem, but I just really don't understand what's going on here. I have a UITableViewController that takes the cell in didSelectRow and uses it for something in an other function. I pass the cell as AnyObject?. Now when I drill down into a detail VC and then back up again, repeat those steps 2 more times, my app crashes.
First I thought it's a problem somewhere else in my app, but then I created a sample project with nothing but those few lines and managed to reproduce the bug. I also already filed a radar, but I don't want to die dump (as you never hear back form those radar guys) ;) Can anybody explain to me what's going on here!
final class MasterViewController: UITableViewController {
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let cell = tableView.cellForRow(at: indexPath)
doSomethingWith(sender: cell)
}
}
extension MasterViewController {
func doSomethingWith(sender: AnyObject?) {
// I don't even use that sender!!!
// If the function would read doSomethingWith(sender: Any?) everything would be ok!
}
}
If you want you could download the whole sample at: http://www.georgbachmann.com/demo/CrashTest.zip
I'd really like to know what the swift compiler is doing there!
::EDIT::
I just noted that the crash also depends on doSomethingWith: being in an extension!
Basically, you don't "own" the reusable cells. The UITableView owns them. Since you're passing the same cell three times to the function with strong reference (you wrote, you know the solution, so I'm omitting it), you increase the ref count of the cell (in this case to be +3, but it doesn't matter). At some point the UITableView decides to release its cells, but your UIViewController has a strong reference to them. At this point the app crashes. No bug here - you should never pass objects that you don't own.
i'm making an app that needs to transfer data using segues and cells. I have two nearly identical View Controllers but one of them is getting the following error on line 3 whenever I launch it:
I know that Bad Instruction errors mean that it is finding nil, but I don't know how to fix it. This is the code that isn't working:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: InstrumentTableCell! = tableView.dequeueReusableCellWithIdentifier(identifier) as? InstrumentTableCell
cell.configurateTheCell(recipies[indexPath.row])
return cell!
}
How do I fix this?