UITableViewCell selection backgroundColor change not working - ios

I have a custom UITableViewCell class that looks like this:
class CustomTableViewCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.selectionStyle = .none
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
print("Selected: ", selected)
if selected {
self.backgroundColor = .red
} else {
self.backgroundColor = .white
}
}
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
super.setHighlighted(highlighted, animated: animated)
print("Highlighted: ", highlighted)
if highlighted {
self.backgroundColor = .red
} else {
self.backgroundColor = .white
}
}
And then in my UITableViewDelegate I added this code:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
// Navigate to the next screen
}
However, both print() statements are always false. And the backgroundColor never changes. Anything I'm doing wrong here?

Remove all other code just replace your UITableViewCell class with this
class CustomTableViewCell: UITableViewCell {
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
self.backgroundColor = selected ? .red : .white
}
}

I figured out the two issue in your code. Please refer below issue along with the solution.
Please use the below code to set background color of UITableViewCell
self.contentView.backgroundColor = .red
Instead of
self.backgroundColor = .red
Just replace didSelectRowAt method if want to change color permanently otherwise keep as it is.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
Refer below attached source code of the demo application. If any further help required.
Source Code

Related

How can I animate the progressBar in a custom prototype cell?

I'm trying to have the following animation in my custom UITableViewCell:
When a user checks off a task, the progressBar should go from 0.0 to 1.0 in 5 seconds
What I've tried
Doing the animation in the delegate method in the TableVC:
let cell = tableView.cellForRow(at: IndexPath(item: indexSection!, section: indexRow!)) as? TaskCell
cell?.progressBar.setProgress(1.0, animated: true)
This doesn't work because it seems like the cell doesn't exist (print(cell!) gives a fatal error)
Doing the animation in TaskCell.swift
#IBAction func checkBoxAction(_ sender: Any) {
if items![indexRow!].checked {
delegate?.changeButton(state: false, indexSection: indexSection!, indexRow: indexRow!, itemID: itemID)
UIView.self.animate(withDuration: 1.0) {
self.progressBar.setProgress(0.0, animated: true)
}
} else {
delegate?.changeButton(state: true, indexSection: indexSection!, indexRow: indexRow!, itemID: itemID)
UITableViewCell.animate(withDuration: 5.0) {
self.progressBar.setProgress(1.0, animated: true)
}
}
}
This does set the progress bar, but it doesn't animate it. The progress bar abruptly changes. This is what happens
Could anyone shine a light on what I'm doing wrong? Am I calling the animation function incorrectly or am I doing it in the wrong place?
Thanks,
Matt
I have just created a simplified example and for me the following code works:
CustomTableViewCell
class CustomTableViewCell: UITableViewCell
#IBOutlet weak var progressView: UIProgressView!
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
}
#IBAction func startButtonDidTap(_ sender: UIButton) {
UIView.animate(withDuration: 2) {
self.progressView.setProgress(0.5, animated: true)
}
}
}
ViewController
class ViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "reuseID", for: indexPath) as? CustomTableViewCell else { return UITableViewCell() }
return cell
}
}
Of course you need a proper storyboard configuration in order to run my code...

design UI of app using tablview in swift

I want UI of my app to be similar like as shown in below image.
Using tableview i'm able to get Payment,Delivery,Build Team options as shown in image but for Build Profile,Manage Menu.. how do i do it using tableview ?
If not tableview for these options then what other control i can try.
this type of UI you are looking for and you can easily get by creating different Cell classes
UI Output :
Required Code
Step 1 - Create different Xib of table cell
class viewWithArrow: UITableViewCell {
#IBOutlet weak var headerLabel: UILabel!
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
}
}
class viewWithShadow: UITableViewCell {
#IBOutlet weak var shadowView: UIView!{
didSet{
shadowView.addShadowToView(color: .black)
}
}
#IBOutlet weak var headerLabel: UILabel!
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
}
}
Adding Shadow Effect :
extension UIView {
func addShadowToView(color:UIColor)
{
self.layer.shadowColor = color.cgColor
self.layer.shadowOpacity = 0.2
self.layer.masksToBounds = false
self.clipsToBounds = false
self.layer.shadowOffset = CGSize(width: 0, height: 0)
self.layer.shadowRadius = 5
}
}
View controller
class ViewController: UIViewController
{
var dataArray : [String] = ["11","22","33","44","55","66"]
#IBOutlet weak var homeVcTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
homeVcTableView.register(UINib(nibName: "viewWithShadow", bundle: nil), forCellReuseIdentifier: "viewWithShadow")
homeVcTableView.register(UINib(nibName: "viewWithArrow", bundle: nil), forCellReuseIdentifier: "viewWithArrow")
}
override func viewWillAppear(_ animated: Bool) {
self.homeVcTableView.delegate = self
self.homeVcTableView.dataSource = self
}
}
extension ViewController : UITableViewDataSource, UITableViewDelegate
{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return dataArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.row {
case 0,1:
let cell = self.homeVcTableView.dequeueReusableCell(withIdentifier: "viewWithShadow", for: indexPath) as! viewWithShadow
cell.headerLabel.text = dataArray[indexPath.row]
return cell
default:
let cell = self.homeVcTableView.dequeueReusableCell(withIdentifier: "viewWithArrow", for: indexPath) as! viewWithArrow
cell.headerLabel.text = dataArray[indexPath.row]
return cell
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return self.homeVcTableView.frame.size.height*0.1
}
}
Working code link - https://drive.google.com/open?id=18mSlWAU_e4XElox4H-oTpqg8clD_HKwu

Change text color in tableview cell in didHighlightRowAt

I have this code:
func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
cell!.contentView.backgroundColor = .blue
cell?.textLabel?.textColor = UIColor.white
var cell2 = tableView.cellForRow(at: indexPath) as! DataTableViewCell
cell2.textLabel.textColor = UIColor.white
}
The background change works fine, but the text color change does not work.
Does anyone know why and how to fix this problem?
I think instead of writing these two lines:
cell!.textLabel?.textColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
cell?.textLabel?.textColor = UIColor.white
writing only a single line as:
cell.textLabel?.highlightedTextColor = .black
will work fine for you!
Use this function in your DataTableViewCell
func setHighlighted(_ highlighted: Bool,
animated: Bool)
See Apple Developer Documentation
Try any one of these:
// set highlighted color in `tableView cellForRowAt indexPath`
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
cell?.textLabel?.highlightedTextColor = UIColor.white
}
or try this
class CustomCell: UITableViewCell {
// As an alternate of `tableView cellForRowAt indexPath`, label text highlighted color can be set in both these methods of cell - `awakeFromNib` and `prepareForReuse`
override func awakeFromNib() {
super.awakeFromNib()
self.textLabel?.highlightedTextColor = UIColor.white
}
override func prepareForReuse() {
super.prepareForReuse()
self.textLabel?.highlightedTextColor = UIColor.white
}
// or textColor can be directly set here
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
super.setHighlighted(highlighted, animated: animated)
self.textLabel?.textColor = UIColor.white
}
}
The tableView(_:didHighlightRowAt:) function is part of the Controller domain of your app while setting colors is part of the View domain (as per Model—View—Controller pattern). To keep up a good separation of responsibilities you might want to consider changing colors outside of the controller, i. e. in the cell itself. For this to work, you would create a simple UITableViewCell subclass, like so:
class MyCell: UITableViewCell {
class var reuseIdentifier: String { return "MyCell" }
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
if selected {
textLabel?.textColor = UIColor.white
} else {
textLabel?.textColor = UIColor.black
}
}
}
This way the cell itself (instead of the controller) handles its own graphical representation which is the recommended way.
cell.textLabel.highlightedTextColor = [UIColor greencolor];
OK, this code works:
override func awakeFromNib () {
         super.awakeFromNib ()
         // Initialization code
         self.titleCell? .xtxtColor = UIColor.black
         self.titleCell? .highlightedTextColor = UIColor.white
  }
     override func setSelected (_ selected: Bool, animated: Bool) {
         super.setSelected (selected, animated: animated)
         // Configure the view for the selected state
     }
    
    
     override func prepareForReuse () {
         super.prepareForReuse ()
         self.titleCell? .highlightedTextColor = UIColor.white
     }
Thank you very much for your help :)

Swift 2 nib in uitableview loads but won't allow interaction

I first built a normal custom cell with no nib and it worked perfectly. But now I need to reuse the same cell layout in various views so I'm trying to use a nib in stead of a regular prototype cell.
The cell does display, with information inside. But I can't interact with it. For example, I can't write in the text field. When I click, it just selects the whole cell (although I turned off the selection of the cell in the tableview options).
I tried different ways to init the cell, but it either crashes or does nothing.
Here is my code:
CelluleView (the custom cell)
class CelluleView: UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
}
override func awakeFromNib() {
super.awakeFromNib()
}
}
ViewController
class PersoViewController: UITableViewController {
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(true)
}
override func viewDidLoad() {
super.viewDidLoad()
let nib = UINib(nibName: "CelluleView", bundle: nil)
tableView.registerNib(nib, forCellReuseIdentifier: "Cellule")
tableView.dataSource = self
tableView.delegate = self
self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellule = tableView.dequeueReusableCellWithIdentifier("Cellule", forIndexPath: indexPath) as! CelluleView
return cellule
}
}
One solution would be to enable selection in the table view.
Set the selection style to none
override func awakeFromNib() {
super.awakeFromNib()
selectionStyle = UITableViewCellSelectionStyle.None
}
Create an outlet for your textfield
#IBOutlet weak var textField: UITextField!
and connect it with the nib
Then in the cell respond to the selection and set the text field to become first responder
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
textField.becomeFirstResponder()
}

Assigning property of custom UITableViewCell

I am using the below custom UITableViewCell without nib file.
I have no problem in viewing it in my UITableViewController.
My problem is with assigning a text to "name" label cell.name.text = "a Name" .. noting is assigned
Can you help me?
import UIKit
class ACMenuCell: UITableViewCell {
#IBOutlet var name : UILabel!
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
name = UILabel(frame: CGRectMake(20, 10, self.bounds.size.width , 25))
name.backgroundColor = .whiteColor()
self.contentView.addSubview(name)
self.contentView.backgroundColor = .blueColor()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func layoutSubviews() {
super.layoutSubviews()
}
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
}
}
You might want to try this: Create a public function in a subclass of UITableViewCell, and inside this funxtion set the text to label.
(void)initializeCell
{
do whatever like setting the text for label which is a subview of tableViewCell
}
And from cellForRowAtIndexPAth, call this function on cell object:
// taking your code for demo
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let reuseIdentifierAC:NSString = "ACMenuCell"; var cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifierAC, forIndexPath:indexPath) as ACMenuCell cell = ACMenuCell(style: UITableViewCellStyle.Default, reuseIdentifier: reuseIdentifierAC) [cell initializeCell] return cell }
This approach has worked for me.

Resources