didDeSelectRowAtIndexPath not being called when selectionStyle none - ios

Instead of the default selectionStyle where the background view changes color I'm trying to just change the color of a UIView which I've added to the guideViewCell. However, when deselecting the cell or pressing another cell it doesn't seem to apply the clearColor on the previous indicatorImage. I've tried to set the selectedBackgroundView to clearColor however this will hide my custom border. What can I do in order to solve this issue?
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("GuideCell", forIndexPath: indexPath) as! GuideViewCell
cell.selectionStyle = UITableViewCellSelectionStyle.None
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var cell = tableView.cellForRowAtIndexPath(indexPath) as! GuideViewCell
cell.indicatorImage.backgroundColor = UIColor.blackColor()
}
func tableView(tableView: UITableView, didDeSelectRowAtIndexPath indexPath: NSIndexPath) {
var cell = tableView.cellForRowAtIndexPath(indexPath) as! GuideViewCell
cell.indicatorImage.backgroundColor = UIColor.clearColor()
}

My solution was just to create new variable and save the indexPath
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var cell = tableView.cellForRowAtIndexPath(indexPath) as! GuideViewCell
if (lastSelectedCell != nil) {
var oldCell = tableView.cellForRowAtIndexPath(lastSelectedCell!) as! GuideViewCell
oldCell.indicatorImage.backgroundColor = UIColor.clearColor()
}
lastSelectedCell = indexPath
cell.indicatorImage.backgroundColor = UIColor.blackColor()
}

You need to be sure the tableView delegate is set and the tableView allowsSelection or allowsMultipleSelection is set true.

Related

UITableView : Strange checkmark accessory type behavior

A gif to introduce my problem :
In my UITableView I set a checkmark accessory type but a white background appears instead of displaying the checkmark of the cell. The checkmark is here, but why do I have this white background ?
The tint color of my cell is set to white, changing it just change the color of the checkmark and the background is still here.
My code :
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? CheckTableViewCell {
if cell.titleLabel.text != "" {
cell.accessoryType = .checkmark
}
}
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .none
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? CheckTableViewCell {
cell.setUp(withTitle: dataSource[indexPath.row].title)
return cell
}
return CheckTableViewCell()
}
func setUp(withTitle title : String){
self.titleLabel.text = title
}
Any idea ?
I had to set both cell content's View and UITableView background color to pink in StoryBoard to make it works.

Programmatically highlighting UITableViewCell in Swift

How do I programmatically highlight a table view cell?
I am using:
tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
tableView.delegate?.tableView!(self.ordersTableView, didSelectRowAt: indexPath)
The problem I am having is that the cell IS being selected (all the actions specified in my didSelectRowAt are being performed) but the cell does now highlight. It doesn't appear selected.
What I am trying to achieve is like the Settings app on the iPad. You launch the app and see the "general" cell already selected and highlighted.
The cells highlight properly when touched by the user.
I have even tried overwriting the isSelected variable in my subclass of UITableViewCell.
Ok turns out it was a problem with background tasks. The cells were loaded again after I selected them and that's why the selection wasn't visible.
Note: Your question title says, you have a query with cell highlight and your question description says, you have a problem with cell selection. Both are different events.
Here is an answer, how you can manage (set color) on tableview row (cell) selection:
// make sure your tableview row selection is enabled
yourTableViewInstance.allowsSelection = true
// handle highlighted background in data source method also
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "textview") as! YourTableViewCell
cell.contentView.backgroundColor = cell.isSelected ? UIColor.red : UIColor.gray
return cell
}
// didSelectRowAtIndexPath - change background color
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? YourTableViewCell {
cell.contentView.backgroundColor = UIColor.red
}
}
// didDeselectRowAtIndexPath - change background color
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? YourTableViewCell {
cell.contentView.backgroundColor = UIColor.gray
}
}
Try this:-
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
var selectedCell:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
selectedCell.contentView.backgroundColor = UIColor.redColor()
}
Here is another option to handle cell background selection
class YourTableViewCell: UITableViewCell {
// override cell selection
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
if self.selectedBackgroundView == nil {
let bgView = UIView()
self.selectedBackgroundView = bgView
}
self.selectedBackgroundView?.backgroundColor = selected ? UIColor.red : UIColor.gray
}
}
// enable row/cell selection
yourTableViewInstance.allowsSelection = true
// handle highlighted background in data source method also
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "textview") as! YourTableViewCell
if self.selectedBackgroundView == nil {
let bgView = UIView()
self.selectedBackgroundView = bgView
}
self.selectedBackgroundView?.backgroundColor = selected ? UIColor.red : UIColor.gray
return cell
}

I can't restore attributes the previous cell that I deselected

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.

how to avoid reusable custom cell from overwriting data when scrolling?

This is the code I am using and it works fine until I scroll in the table view, the cells overwrite each others and all the repostedFromLabel are hidden.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("FeedsTableViewCell", forIndexPath: indexPath) as? FeedsTableViewCell
if (arrayofPostsFeed[indexPath.row].postedByUser!.nickName!) != arrayofPostsFeed[indexPath.row].ownedByUser!.nickName! {
cell!.repostedFromLabel.text! = "Reposted From \(self.arrayofPostsFeed[indexPath.row].postedByUser!.nickName!)"
} else {
cell!.repostedFromLabel.hidden = true
}
}
how should I prevent reusable cells to override each others?
You can implement the prepareForReuse function in your FeedsTableViewCell to reset the hidden property of the repostedFromLabel. Something like this:
override func prepareForReuse() {
self.repostedFromLabel.hidden = false
}
At the moment you are not resetting that value, so it will get mixed up when reusing the cells.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("FeedsTableViewCell", forIndexPath: indexPath) as? FeedsTableViewCell
if (arrayofPostsFeed[indexPath.row].postedByUser!.nickName!) != arrayofPostsFeed[indexPath.row].ownedByUser!.nickName! {
cell!.repostedFromLabel.text! = "Reposted From \(self.arrayofPostsFeed[indexPath.row].postedByUser!.nickName!)"
cell!.repostedFromLabel.hidden = false
}else {
cell!.repostedFromLabel.hidden = true
}

Change image on select within tableview cell - Swift

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.

Resources