Setting TableViewCell Label colour on row selection Swift 3 - ios

I have a TableView, and the table is populated from an array. The cell is of type TableViewCell.xib. I want to change the colour of the label in the cell.
Here's my TableViewController
struct cell_data {
let label1: String!
}
class TableViewController: UITableViewController {
let cellDataArray = [cell_data]([cell_data(label1: "This text is for label 1")])
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cellDataArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = Bundle.main.loadNibNamed("TableViewCell", owner: self, options: nil)?.first as! TableViewCell
cell.label_1.text = cellDataArray[indexPath.row].label1
cell.selectionStyle = .none
let whiteRoundedView : UIView = UIView(frame: CGRect(x:10, y:5, width: self.view.frame.size.width - 20, height: cell.frame.size.height - 7))
whiteRoundedView.layer.backgroundColor = UIColor.green.cgColor
whiteRoundedView.layer.masksToBounds = false
whiteRoundedView.layer.shadowOffset = CGSize(width: -1, height: 1)
whiteRoundedView.layer.shadowOpacity = 0.3
cell.contentView.addSubview(whiteRoundedView)
cell.contentView.sendSubview(toBack: whiteRoundedView)
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
}
}
What I want to do be able to do is change the colour of the label of the cell when I select a row without affecting the UIView inside the cell. That is, once I change the height of the UIView when I select a row, I have tried reloading but reloading the cell set the UIView's height to the original setting.
And once I have set the label's colour, I want to set it back to it's original colour when I deselect the row.
I hope I made it clear enough. Thanks in advance.

You don't need to reloading the cell to update the label's color. You can try by overriding method in your TableViewCell with the following code:
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
if (selected) {
//Change your label color for selected state
} else {
//Change your label color for unselected state
}
}

try this:
func tableView(tableView: UITableView, didHighlightRowAtIndexPath indexPath: NSIndexPath)
{
let cell = tableView.cellForRowAtIndexPath(indexPath)! as! customTableViewCell // name of your custom cell class
cell.label_1.backgroundColor = UIColor.whiteColor()//give your selection color
}

Try this
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as yourCell
cell.yourlable.textcolor = yourColor;
}

Related

How to make clickable table view and method didSelectRowAt

I have a drop-down list that I implemented using table view:
When choosing another floor, information in the center should be substituted.
I have extension:
extension DDList: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (Manager.shared()?.location.floor.count)!
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = Manager.shared()?.location.floor[indexPath.row].name
cell.textLabel?.textAlignment = .center
cell.textLabel?.textColor = .white
cell.textLabel?.font = font
cell.backgroundColor = UIColor.black
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let indexPath = Manager.shared()?.location.floor[indexPath.row].name
let currentCell = tableView.cellForRow(at: indexPath) as UITableViewCell
let currentItem = currentCell.textLabel!.text
}
I can’t make the functionality of selecting an item from a list in a didSelectRowAt method, please tell me how to do it? So that the selected floor is saved from the top to the middle where at the moment (1-st floor)
I would prefer to do that:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let nameOfCurrentItem = Manager.shared()?.location.floor[indexPath.row].name
//if you use a navigation bar
self.navigationBar.topItem?.title = nameOfCurrentItem
//if you use a label
myLabel.text = nameOfCurrentItem
}
If you need an animation:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let nameOfCurrentItem = Manager.shared()?.location.floor[indexPath.row].name
if let currentCell = tableView.cellForRow(at: indexPath){
UIView.animate(withDuration: 0.3, animations: {
currentCell.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
//or any other animation
//currentCell.alpha = 0.5
}) { (_) in
UIView.animate(withDuration: 0.3, animations: {
currentCell.transform = CGAffineTransform.identity
//or any other animation
//currentCell.alpha = 1.0
}) { (_) in
//if you use a navigation bar
self.navigationBar.topItem?.title = nameOfCurrentItem
//if you use a label
self.myLabel.text = nameOfCurrentItem
}
}
}
}
Also ensure that your tableViewCell and tableView itself are able to be selected in the attributes inspector:
TableView selection settings
TableViewCell selection settings

UITableViewCell from Xib, cell hight and cell selection area

I have a UITableViewController, which has a custom cell that I want to display an image and labels. screenshots can explain my problem very well, it looks like this
.
And when I select any cell it looks like
In tableviewcontroller cell is not visible in proper shape according to constraints
here is my custom cell with autolayout constraints
How I can fix this issue? ... I created this tableviewcontroller programmatically without using storyboard.
here is code sample of data source and delegates of tableviewcontroller
override func numberOfSections(in tableView: UITableView) -> Int {
var numOfSections: Int = 0
let count = conversations.count
if count > 0 {
// tableView.separatorStyle = .none
numOfSections = 1
tableView.backgroundView = nil
}
else
{
let frame = CGRect(x: 0,
y: 0,
width: tableView.bounds.size.width,
height: tableView.bounds.size.height)
let noDataLabel: UILabel = UILabel(frame: frame)
noDataLabel.text = "You don't have any messages. 🙃"
noDataLabel.textColor = UIColor.black
noDataLabel.textAlignment = .center
tableView.backgroundView = noDataLabel
tableView.separatorStyle = .none
}
return numOfSections
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return conversations.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "inboxCell", for: indexPath) as! InboxCell
cell.conversation = conversations[indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let uids = conversations[indexPath.row].conversationUseruids
for uid in uids{
if uid == Account.account.user.uid{
}
else{
User.getUser(with: uid, completion: { (user) in
self.selectedUser.append(user!)
})
}
}
tableView.deselectRow(at: indexPath, animated: true)
let index = indexPath.row as Int
messageVC.conversationIndex = index
messageVC.conversation = self.conversations[index]
navigationController?.pushViewController(messageVC, animated: true)
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}
it happen because your image not have upper lower constraint if not working than let me know

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
}

Resize cell when click on custom button in Swift 4

I have a view controller in which i have used table view controller in it. In my cell there is a button on which when user click the cell size should come to 550 and when click again it should come back to its original height. I have tried bit code after searching for it but it isn't working is their any solution that can work for me?. My code is bit this,
var indexOfCellToExpand: Int!
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.row == indexOfCellToExpand {
return 170 + expandedLabel.frame.height - 38
}
return 170
}
Use Auto layout for Expand-collapse Cell,
Attaching Demo for that case
link:https://www.dropbox.com/s/ieltq0honml35l8/TAbleDemo.zip?dl=0.
set cell button height constraint and update constraint on Value on select- deselect event and just reload data
in main viewcontroller code
self.tblView.estimatedRowHeight = 100
self.tblView.rowHeight = UITableViewAutomaticDimension
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TblCell", for: indexPath) as! TblCell
cell.btnExpandCollepse.addTarget(self, action: #selector(ViewController.expandCollapse(sender:)), for: .touchUpInside)
return cell
}
#objc func expandCollapse(sender:UIButton) {
self.tblView.reloadData()
}
Code in Cell Class
#IBOutlet var btnExpandCollepse: UIButton!
#IBOutlet var constraintBtnHeight: NSLayoutConstraint!
#IBAction func onExpandCollepse(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
if !sender.isSelected{
self.constraintBtnHeight.constant = 50
}else{
self.constraintBtnHeight.constant = 500
}
}
for constraint check below image
http://prntscr.com/hur8ym
Updated Demo for custom Content height of Lable with Autoresizing Cell
https://www.dropbox.com/s/o742kflg5yeofb8/TAbleDemo%202.zip?dl=0
https://www.dropbox.com/s/o742kflg5yeofb8/TAbleDemo%202.zip?dl=0
Swift 4.x
fileprivate var expandedIndexSet = Set<IndexPath>()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if expandedIndexSet.contains(indexPath) {
let cell = tableView.dequeueReusableCell(withIdentifier: "CELL_EXPANDED", for: indexPath) as! CellExpanded
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "CELL_COLLAPSED", for: indexPath) as! CellCollapsed
return cell
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
if expandedIndexSet.contains(indexPath) {
expandedIndexSet.remove(indexPath)
} else {
expandedIndexSet.insert(indexPath)
}
tableView.reloadRows(at: [indexPath], with: .fade)
}

Avoid Data repetition in UITableView cells when scrolling

I need an auto scrolling Image slider in top of viewcontroller followed by list of some entities(dynamic cells with image and title). To implement that I have taken a uitableview and I'm adding scrollview to my first cell, and my code is as follows
public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.row == 0{
return 200
}
else {
return 50
}
}
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if indexPath.row == 0 {
let sv = UIScrollView(frame: CGRect(x: 0, y: 0, width: cell.frame.width, height: cell.frame.height))
sv.auk.show(url: "url for image1")
sv.auk.show(url: "url for image2")
cell.addSubview(sv)
print("inside if")
}
else {
print("else")
cell.textLabel?.text = "cool"
}
return cell
}
I'm using this repository to create image slider which creates slider on a scrollview, So for first cell I have added scrollview. But as you can see in the picture the image slider reappears on multiple rows. Please tell me what is the mistake that I'm doing.In case if there is any better approaches please suggest .
Try taking a separate class for dynamic cells. Dequeue both the cells (static and dynamic cells) in the cellForRow method as follows:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return indexPath.row == 0 ? 200 : 50
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 20 }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
scrollViewWidth = cell.frame.width
scrollViewHeight = cell.frame.height
let scrollView = prepareScrollView(width: scrollViewWidth, height: scrollViewHeight)
cell.addSubview(scrollView )
print("First row")
return cell
}
else {
let myCustomCell: MyCustomTableViewCellClass = tableView.dequeueReusableCell(withIdentifier: "MyCustomTableViewCellIdentieier", for: indexPath) as! MyCustomTableViewCellClass
myCustomCell.textLabel?.text = "Cool"
print("Other dynamic rows")
return myCustomCell
}
}
func prepareScrollView(_ width: Float, height: Float) -> UIScrollView {
let scrollViewFrame = CGRect(x: 0, y: 0, width: width, height: height)
let scrollView = UIScrollView(frame: scrollViewFrame)
scrollView.auk.show(url: "url for image1")
scrollView.auk.show(url: "url for image2")
return scrollView
}
Take a separate class as MyCustomTableViewCellClass of type UITableViewCell and subclass your dynamic cell with this class. Don't forget to give cell identifier as "MyCustomTableViewCellIdentieier"
After this, your static cell will dequeue only once and no chances od repeating UI elements
You can try this code in your table view cell class -
override func prepareForReuse() {
//set your lable and image view to nil
}
SideMenuTVCell is a my custom UITableViewCell class -
Hope like this you have your own class within this class you add prepareForReuse() method -
class SideMenuTVCell: UITableViewCell {
#IBOutlet weak var iconIView: UIImageView!
#IBOutlet weak var lblTitle: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
super.setHighlighted(highlighted, animated: animated)
}
override func prepareForReuse() {
//set your lable and image view to nil
self.iconIView.image = nil
self.lblTitle.text = nil
}
}

Resources