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.
Related
I want it to draw the data I have selected in the application. for example, I want the data in row 0 to pull the data in row 1. these data are kept as follows.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! DeviceTableViewCell
let deviceItem: Device = items[indexPath.row]
cell.deviceItem = deviceItem
cell.title.text = deviceItem.title
cell.button.isOn = deviceItem.state
return cell
}
So I want to take the device names. cell.title.text = deviceItem.title I want to draw the lines here.
Use below code to get of selected row:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let deviceItem: Device = items[indexPath.row]
print(deviceItem.title)
}
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.
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
}
in my cellForRowAt Im inflating my xib and setting its content:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: TableViewCell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! TableViewCell
cell.label.text = data[indexPath.row]
let tap = UIGestureRecognizer(target: self, action: #selector(tableCellTap(_:cell:)))
cell.addGestureRecognizer(tap)
cell.selectionStyle = .none
cell.checkBox.isUserInteractionEnabled = false
cell.checkBox.boxType = .circle
cell.checkBox.markType = .radio
cell.checkBox.cornerRadius = 0
cell.checkBox.stateChangeAnimation = .expand(.fill)
if (indexPath.row == selectedIndex){
cell.checkBox.checkState = .checked
}else{
cell.checkBox.checkState = .unchecked
}
return cell
}
Then Im setting my deselect and select values
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! TableViewCell
cell.checkBox.checkState = .checked
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! TableViewCell
cell.checkBox.checkState = .unchecked
}
I need a sense of direction in how i can make it select and deselect the same row and update my xib file checkbox?
m13checkbox is being used
when i click on the cell for the first time it selects it but when i click on the same cell again it does not call it and does nothing until a loop a completed in the checkboxes
you don't need didDeselectRowAt, you can achieve the same functionality by checking if the radio button is checked in your didSelectRowAt.
If the radio button is checked, simply uncheck it and vice versa.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! TableViewCell
if(cell.checkBox.isChecked){
cell.checkBox.checkState = .unchecked
}else{
cell.checkBox.checkState = .checked
}
}
Apple has already given very good sample code for that on its website,
you can check at:https://developer.apple.com/library/content/samplecode/TableMultiSelect/Introduction/Intro.html
I have a UIViewController in mainstoryboard, and it contains a tableview, it just shows the labels, not exciting things. And when I click one of the cells it push me to the detailVC. The problem is starting here, when I come back from detailVC, the cell that i pushed, is still looking selected. And it looks gross. I tried everything that i can. And lastly cells are custom cell.
P.s.: I have to use swift 2.3 in this project.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableVieww.dequeueReusableCellWithIdentifier("cellNew", forIndexPath: indexPath) as! AltKategoriNewCell
let data = self.katData[indexPath.row]
cell.textLabelNew?.text = data["CatogryName"] as? String
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableVieww.dequeueReusableCellWithIdentifier("cellNew", forIndexPath: indexPath) as! AltKategoriNewCell
let data = self.katData[indexPath.row]
cell.textLabelNew?.text = data["CatogryName"] as? String
cell.contentView.backgroundColor = UIColor.lightGrayColor()
cell.backgroundColor = UIColor.lightGrayColor()
cell.textLabelNew?.textColor = UIColor.blackColor()
urunlerList.altKatDic = self.katData[indexPath.row]
performSegueWithIdentifier("urunlerList", sender: nil)
}
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableVieww.dequeueReusableCellWithIdentifier("cellNew", forIndexPath: indexPath) as! AltKategoriNewCell
cell.contentView.backgroundColor = UIColor.whiteColor()
cell.backgroundColor = UIColor.whiteColor()
cell.textLabelNew?.textColor = UIColor.blackColor()
}
TableView
Attributes
First thing that is wrong is that you are dequeueing the cell in didSelectRowAtIndexPath and didDeselectRowAtIndexPath methods. UITableView does not expect you to do that there. If you need to get the cell in didSelectRowAtIndexPath, you can ask
let cell = tableView.cellForRow(at: indexPath)
UITableViewCell has selectedBackgroundView and, UILabel has highlightedTextColor. Knowing that, you can just set up appropriately your cell, and then you won't need to modify its properties on selection/deselection, like this:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cellNew", forIndexPath: indexPath) as! AltKategoriNewCell
if nil == cell.selectedBackgroundView {
cell.selectedBackgroundView = UIView()
cell.selectedBackgroundView?.backgroundColor = UIColor.lightGrayColor()
}
let data = self.katData[indexPath.row]
cell.textLabelNew?.text = data["CatogryName"] as? String
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
urunlerList.altKatDic = self.katData[indexPath.row]
performSegueWithIdentifier("urunlerList", sender: nil)
}
Having this, your implementation of didSelectRowAtIndexPath and didDeselectRowAtIndexPath can be removed.