swift detailTextLabel not showing up - swift

Ive checked around stackOverFlow for a solution but it seemed like it still didnt work for my code.. my detailTextLabel still does not show up :(
Wondering what I am doing wrong, here's my code
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell()
// display our ranked data
cell.textLabel?.text = "\(championListInGame[indexPath.row])"
if let url = NSURL(string: "http://ddragon.leagueoflegends.com/cdn/img/champion/loading/\(championListInGame[indexPath.row])_0.jpg"){
if let urlData = NSData(contentsOfURL: url){
cell.imageView?.contentMode = UIViewContentMode.ScaleAspectFit
cell.imageView?.image = UIImage(data: urlData)
}
}
if victory[indexPath.row] == true {
cell.backgroundColor = UIColor.blueColor()
cell.detailTextLabel?.text = " "+"victory!"
} else {
cell.backgroundColor = UIColor.redColor()
cell.detailTextLabel?.text = " "+"defeat!"
}
return cell
}
my victory nor defeat showed up in my table cells however, the color, image, and text all showed up just as the way I wanted.
On the side note, can someone teach me how do I choose colors like baby blue or baby red ? the default red and blue is too strong for my app :(
Thanks for the help guys!

The default cell style doesn't have a detailTextLabel. You need to use .Value1 or .Subtitle as the UITableViewCellStyle:
var cell = UITableViewCell(style: .Value1, reuseIdentifier: nil)
You can use the UIColor:red:green:blue:alpha: constructor to make custom colors. The values all vary from 0.0 to 1.0. You can look on the web for colors. If they are specified with values in the 0 to 255 range, you can convert them by dividing the values by 255.0:
let babyRed = UIColor(red: 1.0, green: 0.6, blue: 0.6, alpha: 1.0)
let babyBlue = UIColor(red:128.0/255.0, green: 178.0/255.0, blue: 255.0/255.0, alpha: 1.0)

Related

UICollection Cells are mixed in swift

I'm trying to generate cells and put labels inside of it. However, when i scroll down labels got mixed between cells. Here is my code and i'm trying to solve it.
let lblTitle = UILabel()
let lblMetro = UILabel()
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
var cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MenuCell", for: indexPath) as? UICustomCollectionViewCell
if indexPath.row == 0 {
lblTitle.frame = CGRect(x: 0, y: 0, width: 195, height: 40)
lblTitle.font = UIFont.systemFont(ofSize: 14)
lblTitle.textColor = UIColor.white
lblTitle.backgroundColor = colorLiteral(red: 0.2122299671, green: 0.4379466176, blue: 0.8993332386, alpha: 1)
lblTitle.text = " 1”
cell?.contentView.addSubview(lblTitle)
}
if indexPath.row == 1 {
lblMetro.frame = CGRect(x: 55, y: 290, width: 100, height: 20)
lblMetro.font = UIFont.boldSystemFont(ofSize: 17)
lblMetro.textColor = colorLiteral(red: 0, green: 0.3117707968, blue: 0.5609284043, alpha: 1)
lblMetro.text = “2”
cell?.contentView.addSubview(lblMetro)
}
return cell ?? UICollectionViewCell()
}
}
Here cells are dequeued
var cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MenuCell", for: indexPath) as? UICustomCollectionViewCell
so you might get a 1 with previously added label , you need to clear them after dequeue , it would be messy but it's better to isolate the vc's labels from the cells 1 so add them inisde the cell configure or make them an outlets , to remove give them a tag and after the above line do
cell.contentView.subviews.forEach {
if $0.tag == 200 {
$0.removeFromSuperview()
}
}
Not optimised but this might solve it, remove the subview from superview before adding it:
cell?.contentView.lblTitle.removeFromSuperview()
cell?.contentView.addSubview(lblTitle)
And:
cell?.contentView.lblMetro.removeFromSuperview()
cell?.contentView.addSubview(lblMetro)
I suggest using a very rarely used method of UICollectionViewCell or UITableViewCell prepareForReuse.
In definition of UICustomCollectionViewCell insert the function:
class UICustomCollectionViewCell: UICollectionViewCell {
func prepareForReuse() {
// This method is immediately called when a cell is about to be dequeued.
super.prepareForReuse()
if let view = contentView.viewWithTag(100) {
view.removeFromSuperView()
}
if let view = contentView.viewWithTag(101) {
view.removeFromSuperView()
}
}
}
Then give tags to the labels
lblMetro.tag = 100
lblTitle.tag = 101
This solution is efficient if you only use a limited labels and cells. For a more generic approach create labels dynamically and share the tag. In the prepareForReuse() just remove subview with that tag.

Cannot unselect the checkmark when scroll the tableView

I'm trying to do checkmark button in tableViewCell. The checkmark image will be hide/showing when user tap on the checkmark button. The problem I'm facing right now is checkmark button acting weird when I scroll the table view which is I need to double tap to unselect the checkmark.
When I do not scroll the tableView it's working great. Below are the video and code. Thanks in advance.
https://youtu.be/cQBIuIXJlRY
func tableView(_ tableView: UITableView, cellForRowAt
indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "dtvc") as! DeviceTableViewCell
let scannedDevice = devices[indexPath.row]
// Set the tag & addTarget for addButton
cell.addButton.addTarget(self, action: #selector(addButtonTapped), for: .touchUpInside)
cell.addButton.isEnabled = true
cell.addButton.tag = indexPath.row
cell.configureCell(with: scannedDevice)
cell.isSelected = checked[indexPath.row] ?? false
print("cell isSelected at \(indexPath.row) cellForRow \(cell.isSelected)")
print("checked value at \(indexPath.row) is \(checked[indexPath.row])")
if checked[indexPath.row] == true {
cell.deviceMake.textColor = UIColor.white
cell.backgroundColor = UIColor(red: 233/255, green: 72/255, blue: 85/255, alpha: 1)
cell.addButton.setImage(UIImage(named: "Checkmark"), for: .normal)
cell.addButton.bgColor = UIColor.green
} else {
cell.deviceMake.textColor = UIColor.gray
cell.backgroundColor = UIColor.clear
cell.addButton.setImage(nil, for: .normal)
cell.addButton.bgColor = UIColor(red: 233/255, green: 72/255, blue: 85/255, alpha: 1)
}
return cell
}
#objc func addButtonTapped(_ sender: UIButton) {
let indexPath = IndexPath(row: sender.tag, section: 0)
let scannedDevice = devices[sender.tag]
let cell = tableView.cellForRow(at: indexPath) as! DeviceTableViewCell
cell.isSelected = !cell.isSelected
print("cell.isSelected is at button \(sender.tag) tapped is \(cell.isSelected)")
if cell.isSelected == true {
// Main color RGB is 233,72,85 ... hex is E94855
cell.deviceMake.textColor = UIColor.white
cell.backgroundColor = UIColor(red: 233/255, green: 72/255, blue: 85/255, alpha: 1)
cell.addButton.setImage(UIImage(named: "Checkmark"), for: .normal)
cell.addButton.bgColor = UIColor.green
checked[sender.tag] = cell.isSelected
print("Checked 1 at tag \(sender.tag) is \(checked[sender.tag])")
//show selectedDeviceView
if selectedDeviceView.isHidden {
UIView.animate(withDuration: 2.5, delay: 0.7, options: .curveEaseInOut, animations: {
self.tableViewHeightConstraint.constant = self.tableViewHeightConstraint.constant - self.selectedDeviceViewTopConstraint.constant - self.selectedDeviceView.frame.height
self.selectedDeviceViewTopConstraint.constant = 0
self.selectedDeviceView.isHidden = false
}, completion: nil)
}
}
else {
cell.deviceMake.textColor = UIColor.gray
cell.backgroundColor = UIColor.clear
cell.addButton.setImage(nil, for: .normal)
cell.addButton.bgColor = UIColor(red: 233/255, green: 72/255, blue: 85/255, alpha: 1)
checked[sender.tag] = cell.isSelected
print("Checked 2 at tag \(sender.tag) is \(checked[sender.tag])")
}
}
First of all put the selected state into the devices class/struct rather than using an extra array
class Device {
var isSelected = false
...
Second of all don't think in terms of the view think in terms of the model. That means toggle isSelected in the model and reload the row. The benefit is that the view is manipulated reliably only in cellForRow.
For example
#objc func addButtonTapped(_ sender: UIButton) {
let indexPath = IndexPath(row: sender.tag, section: 0)
devices[indexPath.row].isSelected.toggle()
self.tableView.reloadRows(at: [indexPath], with: .none)
if devices[indexPath.row].isSelected && selectedDeviceView.isHidden {
UIView.animate(withDuration: 2.5, delay: 0.7, options: .curveEaseInOut, animations: {
self.tableViewHeightConstraint.constant = self.tableViewHeightConstraint.constant - self.selectedDeviceViewTopConstraint.constant - self.selectedDeviceView.frame.height
self.selectedDeviceViewTopConstraint.constant = 0
self.selectedDeviceView.isHidden = false
}, completion: nil)
}
}
And in cellForRow change
cell.isSelected = scannedDevice.isSelected

Table View Lag (even after removing gesture recognizers)

Currently, I have a table view that lags when there are multiple cells. When there is only one cell, it performs smoothly; however, when multiple cells are populated, the table view has a slow feeling, sometimes stutters, and is not as smooth. I removed the gesture recognizers and instead changed it to didSelectRowAt, however there is still lag within the cells. Here is the code for the when the cells are loaded :
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if queryComplete == true {
if displayConvo == true {
let cell = tableView.dequeueReusableCell(withIdentifier: "messageCell", for: indexPath as IndexPath) as! messageTableViewCell
cell.profileImage.image = nil
cell.selectionStyle = UITableViewCell.SelectionStyle.none
var convoContent: messagesViewController.Convo
convoContent = convoList[indexPath.row]
convoContent.itemHeroID = "\(String(describing: convoContent.convoID))"
cell.name.heroID = "\(String(describing: convoContent.convoID))"
cell.lastMessage.text = convoContent.lastMessage
cell.backgroundColor = UIColor.clear
cell.postText.text = convoContent.postContent
if convoContent.revealedBool == true {
cell.profileImage.isHidden = false
cell.profileImage.heroID = "\(String(describing: convoContent.convoID))"
cell.name.text = convoContent.name
cell.timer.isHidden = true
if convoContent.profileImage == "nil" || convoContent.profileImage == nil {
let url = URL(string:"https://firebasestorage.googleapis.comasdjfjaisfdji")
let processor = RoundCornerImageProcessor(cornerRadius: cell.profileImage.frame.size.width / 2)
cell.profileImage.kf.setImage(with: url, placeholder: nil, options: [.processor(processor)])
}
else {
let url = URL(string: convoContent.profileImage!)
let processor = RoundCornerImageProcessor(cornerRadius: cell.profileImage.frame.size.width / 2)
cell.profileImage.kf.setImage(with: url, placeholder: nil, options: [.processor(processor)])
}
}
else {
cell.profileImage.isHidden = true
cell.timer.isHidden = false
cell.timer.isUserInteractionEnabled = false
cell.timer.heroID = "\(String(describing: convoContent.convoID))"
let postDuration = convoContent.timeOfDeletion! - Int(convoContent.time!)
let currentTime = Date().timeIntervalSince1970 * 1000
let difference = Int(round(Double(convoContent.timeOfDeletion! - Int(currentTime))))
let date = Date(timeIntervalSinceNow: TimeInterval(difference / 1000))
cell.name.text = String(timeToDelete(date: date as NSDate, numericDates: false))
let amountOfCircleCovered = (Double(((convoContent.timeOfDeletion!) - Int(currentTime))) / Double(postDuration)) * 100
var timerColor: UIColor?
switch amountOfCircleCovered {
case 0..<30:
timerColor = UIColor (red: 252/255, green: 110/255, blue: 81/255, alpha: 1)
case 30..<60:
timerColor = UIColor (red: 255/255, green: 215/255, blue: 0/255, alpha: 1)
case 60..<100:
timerColor = UIColor(red: 26/255, green: 152/255, blue: 252/255, alpha: 1.0)
default:
timerColor = UIColor(red: 26/255, green: 152/255, blue: 252/255, alpha: 1.0)
}
print(amountOfCircleCovered)
cell.timer.models = [ PieSliceModel(value: Double(100 - amountOfCircleCovered), color: UIColor(red: 220/255, green: 220/255, blue: 220/255, alpha: 1)),
PieSliceModel(value: Double(amountOfCircleCovered), color: timerColor!),
]
}
let lastMessageDate = Date(timeIntervalSince1970: TimeInterval(convoContent.timeOfLastMessage! / 1000))
cell.timeOfLastMessage.text = String(timeAgo(date: lastMessageDate as NSDate, numericDates: false))
return cell
}
else {
let cell = tableView.dequeueReusableCell(withIdentifier: "messageCell", for: indexPath as IndexPath) as! messageTableViewCell
cell.lastMessage.text = "No new messages"
return cell
}
}
else {
let cell = tableView.dequeueReusableCell(withIdentifier: "messageCell", for: indexPath as IndexPath) as! messageTableViewCell
print ("loading")
return cell
}
}
Additionally, I have tried moving some of the aspects of the cell so they can be reset each time by putting them in the cell file:
override func awakeFromNib() {
super.awakeFromNib()
profileImage.cornerRadius = profileImage.frame.size.width / 2
profileImage.clipsToBounds = true
profileImage.layer.borderColor = UIColor.white.cgColor
profileImage.layer.borderWidth = 1
timer.innerRadius = 0
timer.outerRadius = timer.frame.width / 2
timer.animDuration = 0.0
timer.referenceAngle = 270
timer.backgroundColor = UIColor.white
postText.layer.zPosition = 1
if !UIAccessibility.isReduceTransparencyEnabled {
glossyView.backgroundColor = .clear
let blurEffect = UIBlurEffect(style: .regular)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
//always fill the view
blurEffectView.frame = self.glossyView.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
glossyView.addSubview(blurEffectView) //if you have more UIViews, use an insertSubview API to place it where needed
} else {
glossyView.backgroundColor = .black
}
timer.selectedOffset = 0
glossyView.clipsToBounds = true
glossyView.cornerRadius = 12.0
glossyView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
messageBackground.clipsToBounds = true
messageBackground.cornerRadius = 12.0
messageBackground.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
// glossyView.roundCornersView(corners: [.topLeft, .topRight], radius: 12.0)
// messageBackground.roundCornersView(corners: [.bottomLeft,.bottomRight], radius: 12.0)
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
override func prepareForReuse() {
profileImage.image = nil
timer.isHidden = true
timer.models = []
}
}
And yet, when multiple cells are loaded, the table view still lags. I made sure there are no gesture recognizers as this link suggests and also the images are being loaded using a library so I am not sure why the cells still lag.
Essentially, the UI was dramatically slowing down the performance. I switched out the pie time CA Layer for png images of circles partially filled, and removed all Hero animations. As a result, both the app and tableview became much smoother.

custom TableViewCell out of order?

ive been having a lot of issues with my tableview getting out of order or losing a custom image in the tableview cell. I have been doing a lot of research and found a few helpful things on it but none seem to resolve my issue. It seems to be an issue with the reuse cell. I also have an if statement to change an images background on the custom cell depending on what button you press. Any help would be awesome thanks.
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! expenseTableViewCell
let expense = expenses[indexPath.row]
cell.expenseName.text = expenses[indexPath.row].ename
cell.expenseCost.text = "$" + expenses[indexPath.row].ecost!
cell.expenseDue.text = expenses[indexPath.row].edue
//CHANGE BACKGROUND VIEW COLOR
if expense.picture == "1"{
cell.picture.backgroundColor = UIColor(red: 255/255, green: 116/255, blue: 115/255, alpha:1)
}
if expense.picture == "2"{
cell.picture.backgroundColor = UIColor(red: 30/255, green: 192/255, blue: 255/255, alpha:1)
}
return cell
}
Try this instead:
if expense.picture == "1"{
cell.picture.backgroundColor = UIColor(red: 255/255, green: 116/255, blue: 115/255, alpha:1)
} else if expense.picture == "2"{
cell.picture.backgroundColor = UIColor(red: 30/255, green: 192/255, blue: 255/255, alpha:1)
}
Because you are reusing cells, you can't have if statements the way you are writing them. You have to use else if otherwise the cells that stay in memory mess things up.

Remove highlighted text from a cell in TableView

Depending on the status of each pin in the map, each cell in the TableView displays a different color. For changing each color I've not used UIColor.someColor() method, in fact I've used:
UIColor(red: 28/255, green: 198/255, blue: 25/255, alpha: 0.4) //Light red
I would like to remove that highlighted color that is appearing inside each cell. Don't k now if this is a code issue or is something that is inside the TableView/Cell atributes.
I am setting the colors inside the ViewController:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? UITableViewCell
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Value2, reuseIdentifier: cellIdentifier)
}
cell!.textLabel!.text = myFeed.objectAtIndex(indexPath.row).objectForKey("NOMBRE") as? String
var aux: String = "BLIBRES"
var aux2: String = "ALIBRES"
var estado: String = "ESTADO"
cell!.detailTextLabel!.text = "Anclajes Libres: \(myFeed.objectAtIndex(indexPath.row).objectForKey(aux2)!) | Bicicletas Libres: \(myFeed.objectAtIndex(indexPath.row).objectForKey(aux)!)"
if myFeed.objectAtIndex(indexPath.row).objectForKey(estado)! as! String == "NO COMUNICA" {
cell?.backgroundColor = UIColor(red: 28/255, green: 198/255, blue: 25/255, alpha: 0.4)
} else if myFeed.objectAtIndex(indexPath.row).objectForKey(estado)! as! String == "COMUNICA" {
cell?.backgroundColor = UIColor(red: 218/255, green: 71/355, blue: 71/255, alpha: 0.4)
} else if myFeed.objectAtIndex(indexPath.row).objectForKey(estado)! as! String == "ALARMAS" {
cell?.backgroundColor = UIColor(red: 248/255, green: 155/255, blue: 18/255, alpha: 0.4)
}
return cell!
}
Solved!
I did not know that apart from setting a background color to the cell itself, you can set a background color to the text (and also detailText) of the cell. Inside the func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { } method add the following:
cell?.textLabel?.backgroundColor = UIColor.clearColor()
cell?.detailTextLabel?.backgroundColor = UIColor.clearColor()
And then the text is displayed correctly without the borders that looked like a highlighted text when setting a custom background color to a cell.