When I create a new UITableView, I can setup
cell.imageView. Isn't that, in theory, supposed to show an image?
Is the only way to actually show an image inside a UITableViewCell to create a custom cell subclass?
This is the code I'm using:
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = UITableViewCell (style: UITableViewCellStyle.value1, reuseIdentifier: "cell")
cell.textLabel?.text = practices[indexPath.row].name
cell.detailTextLabel?.text = practices[indexPath.row].address?.displayString()
//this doesn't show an image
cell.imageView?.clipsToBounds = true
cell.imageView?.contentMode = .scaleAspectFill
cell.imageView?.image = practices[indexPath.row].logo
return (cell)
}
You should be dequeueing a cell rather than allocating a new one each time:
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
// Configure the cell
cell.imageView?.image = practices[indexPath.row].logo
return cell
}
As suggested by others, add a test image to your xcassets to verify that the problem isn't with the logo in the practices array.
is the only way to actually show an image in a cell is to create a
costume cell ?
No that is not true. you can set it as follows also that you did :
cell.imageView?.image = some UIImage
In your code
cell.imageView?.image = practices[indexPath.row].logo
please check practices[indexPath.row].logo actually have an UIImage
Also a side-note, use dequeueReusableCell
let cell = tableView.dequeueReusableCell(withIdentifier: "someCellName", for: indexPath)
instead of allocating it every time in func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
please check:
if practices[indexPath.row].logo is UIImage {
print("My logo is not UIImage")
cell.imageView?.image = nil
} else {
print("My logo is UIImage")
cell.imageView?.image = practices[indexPath.row].logo
}
Related
I want to use Apple's given Cell Style value1 for my cells and I am not sure how this is done correctly. The only possible way to set the cell style is during the Cell's initialization, but I don't think subclassing should be necessary in this case.
What would be the correct way to set the CellType?
I tried to get it done in tableView(_:cellForRowAt:), but dequeueReusableCell(withIdentifier:for:) does not return an Optional, which is why my logic cannot work.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCellIdentifier", for: indexPath)
if cell == nil {
cell = UITableViewCell.init(style: .value1, reuseIdentifier: "myCellIdentifier")
}
// setup cell text and so on
// ...
return cell
}
Don't call tableView.register(...)
Instead, use this approach in cellForRowAt:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// try to dequeue a cell
var cv1 = tableView.dequeueReusableCell(withIdentifier: "cv1")
// if that fails, create a new one
if cv1 == nil {
cv1 = UITableViewCell(style: UITableViewCell.CellStyle.value1, reuseIdentifier: "cv1")
}
// just for sanity
guard let cell = cv1 else { fatalError("Failed to get a cell!") }
// set the cell properties as desired
cell.contentView.backgroundColor = .yellow
cell.detailTextLabel?.text = "Row \(indexPath.row)"
return cell
}
So I have this function.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as! customCell
changeCellProperty(selectedIndexPath: indexPath)
return cell;
}
func changeCellProperty(selectedIndexPath: IndexPath){
print("indexpath = \(selectedIndexPath)") . // printing [0,0] and all values
let cell = self.tableView.cellForRow(at: selectedIndexPath) as! customCell
// got nil while unwrapping error in above statement.
cell.label.text = ""
// and change other properties of cell.
}
I am not able to understand the error.
When I am getting the indexpath, then why I am not able to point a particular cell and change properties accordingly.
You cannot access a cell that has not yet been added to the tableView. That is what you are trying to do here in changeCellProperty method. So, if your dequeue works, then all you would need to do is pass the dequeued cell to that method.
func changeCellProperty(cell: customCell){
cell.label.text = ""
// and change other properties of cell.
}
Your cellForRowAt method would look like this.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as! customCell
changeCellProperty(cell: cell)
return cell
}
Note: class names should be UpperCamelCase. So your customCell should be named CustomCell.
I'm trying to add two prototype cell on my UITableView. However, I don't know how I could verify to be able to "return" the correct cells for each prototype. Can you guys give me a hand?
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if ??? {
let cell = itensTableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! tableviewCell
cell.nameCell.text = "Oculos"
return cell
}else{
let cellAdicionar = itensTableView.dequeueReusableCell(withIdentifier: "cellIdAdc", for: indexPath) as! tableviewBotaoAdicionar
cellAdicionar.botaoAdicionar.text = "Adicionar"
return cellAdicionar
}
}
Storyboard Picture
You need to set your model to answer that inside cellForRowAt
var arr = ["first","second","first"]
//
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = arr[indexPath.row]
if item == "first" {
let cell = itensTableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! tableviewCell
cell.nameCell.text = "Oculos"
return cell
} else {
let cellAdicionar = itensTableView.dequeueReusableCell(withIdentifier: "cellIdAdc", for: indexPath) as! tableviewBotaoAdicionar
cellAdicionar.botaoAdicionar.text = "Adicionar"
return cellAdicionar
}
}
Requirement:
I'm doing a sideBar navigation,using UITableView and UITableViewCell inside it.Inside UITableViewCell ,there is an UIImageView and a UILabel.i want the UIImageView to have same height and width,and i have given constraints for it.
Issue:
BUT AFTER CLICKING ON EACH CELL,THE SIZE OF IMAGEVIEW CHANGES(CONSTRAINTS MISSING) AND OVERLAPS THE LABEL.
i did all constraints in storyboard only and im doing in swift 3
please help me.
Code work:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomCell
cell.label.text = data[indexPath.row]
let iconName = images[indexPath.row]
//print("\(iconName)")
let image = UIImage(named: iconName)
// print("The loaded image: \(image)")
cell.imageViews.image = image
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
Screent Shot
for viw in cell.contentView.subviews {
if ((viw as? UIImageView) != nil) {
viw.removeFromSuperview()
}else if ((viw as? UILabel) != nil) {
viw.removeFromSuperview()
}
}
Use this code after the cell creation [from second line]. Try it.
I am trying to change an image within a cell when it is selected. Here is what I have in my view controller:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomTableViewCell
cell.bgImage.image = UIImage(named: "second_image")
}
This is where I set the image:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomTableViewCell
cell.bgImage.image = UIImage(named: "first_image")
}
When I select the cell, the image does not update. How do I get this to work?
The issue is probably that you are calling dequeueReusableCellWithIdentifier. Try using cellForRowAtIndexPath instead (documentation about it here). This will give you a reference to the current cell, rather than a reference to a new reusable cell.
So, according to your code above:
let cell = self.tableView.cellForRowAtIndexPath(indexPath) as! CustomTableViewCell
This typecast is critical because cellForRowAtIndexPath returns UITableViewCell, which will not have the bgImage member.
Also, make sure that you have a member called bgImage that is a UIImageView in your CustomTableViewCell class by adding #IBOutlet strong var bgImage: UIImageView!, and that said IBOutlet is connected in your storyboard/xib.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath) as! CustomTableViewCell
cell.bgImage.image = UIImage(named: "second_image")}
For Swift 3+:
func tableView(tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! CustomTableViewCell
cell.bgImage.image = UIImage(named: "second_image")}
Change your didSelectRowAtIndexPath to:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath)
cell.bgImage.image = UIImage(named: "second_image")
}
As per default this works to change the image
let cell = tableView.cellForRowAtIndexPath(indexPath)
cell!.imageView?.image = UIImage(named: "2")
Though it is too late. But i like to answer to participate in this world.
I was having problem with changing selected and deselected cell image of a table view. I solved it this way.
When tableview delegate method call then create instance of that cell by
let cell = self.tableView.cellForRow(at: indexPath) as! CustomeCell
instead of
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomeCell
and use your desired image into your cell imageview.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = self.tableView.cellForRow(at: indexPath) as! CustomeCell
if indexPath.row == 0
cell.btnImageView.image = UIImage.init(named: "screenr.png")
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = self.tableView.cellForRow(at: indexPath) as! CustomeCell
if indexPath.row == 0
cell.btnImageView.image = UIImage.init(named: "screen.png")
}
Can't you simply use the .hightlightedimage value for the imageView? I'm doing the following in my cellForRowAt func:
cell.imageView?.image = UIImage(named: "\(indexPath.row).png")
cell.imageView?.highlightedImage = UIImage(named: "\(indexPath.row)g.png")
And I've just named the necessary images "0.png" and "0g.png" etc to make sure the image and highlighted image match up. Of course, that's a small static array, if you were using coreData with a larger array you could simply hold the imageName and the hightlightedImageName in the data set and pull the info from there.