Set action for subview inside a table cell (swift) - swift

When i clicked the subview,it didn't trigger subview's action. But i have selected whole cell. How to fix it?
Here is my code.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("idcell", forIndexPath: indexPath) as UITableViewCell
let lblTitle : UILabel = cell.contentView.viewWithTag(101) as! UILabel
lblTitle.text = (deptId[indexPath.row] as? String)! + " " + (deptDesc[indexPath.row] as? String)!
var height:CGFloat = 40
if(indexPath.row == departmentSelectedRow){
for i in 0...deptProfile.count-1{
let label = UILabel(frame: CGRectMake(0,height,400,30))
label.targetForAction("sadasdd", withSender: nil)
height = height+40
label.text = ("ewrewrewre")
label.backgroundColor = UIColor.redColor()
cell.addSubview(label)
}
}
return cell
}

If you want to interact with something inside a cell (rather than select the whole cell) then you should use a button or a gesture recogniser. These are properly interactive elements that you can add a target and action to.
You should also change how you're using cells, specifically:
Use custom cell classes, so you can directly reference the cell elements instead of using viewWithTag which is bad practice
Use multiple different cell classes (and thus identifiers) so you can use actually different cells for selected and unselected rows
Don't create and add subviews on the fly, this is what the different cell classes are for

Related

How to add controls to tableview cell programatically only once

override func tableView (_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {let cell = tableView.dequeueReusableCell (withIdentifier: "cell", for: indexPath)
let customerNameLabel = UILabel()
customerNameLabel.frame = CGRect (x: 10, y: 5, width: 150, height: 40)
customerNameLabel.textColor = .black
customerNameLabel.text = "Customer Name\ (indexPath.row)"
cell.contentView.addSubview(customerNameLabel)
return cell
}
While trying to add label to cell it is adding number of times even while scrolling the tableView but I need to add label only once and reuse it
You need to create a custom UITableViewCell and add your label to it.
Because in the code you provided you will be adding a UILabel() to the cell every time the cell is reused.
You need create a subclass for UITableViewCell
If you load your cell from xib file, override awakeFromNib and add your label to cell inside awakeFromNib method.
If you create your cell programmatically, override init(style: UITableViewStyle) and add your label to cell inside init(style: UITableViewStyle) method.
Due to the reusable behavior of UITableViewCell, the label is added multiple time in a single cell because the cell is being reused if you want to add a single label on the cell you have to check first if it already added.
What we are frequently used:
1) We make the .xib of a cell and reuse it:
2) We make the cell in the storyboard and give the specific identifier to cell and reuse it:
3) You can check the label is already added:
var customerNameLabel:UILable? = nil
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) {
if customerNameLabel == nil {
customerNameLabel = UILabel()
customerNameLabel.frame = CGRect(x: 10, y: 5, width: 150, height: 40)
customerNameLabel.textColor = .black
cell.contentView.addSubview(customerNameLabel)
}
customerNameLabel.text = "Customer Name\(indexPath.row)"
return cell
}
Several simple steps:
Subclass UITableViewCell.
Add the label to contentView inside awakeFromNib (override this method) if you load from nib OR init(style:reuseIdentifier:) (override this method) if you generate the cell programmatically. Alternatively you can set cell's layout in Storyboard of nib itself.
In tableView:cellForRow set the label's text to whatever you want.
That is Because TableView will call the cellForRowAt everytime you scroll or reload the tableView.
Either you subclass UITableViewCell and add a label there or you have to remove the label every time before adding it.

Dynamically add subViews to UITableViewCell

I need to add UILabels to UITableViewCell, but its dynamic, first cell can have 1 label, second can have 4 and I dont know before hand. So I tried this
func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell {
let cell: ReviewTableViewCell = reviewTableView.dequeueReusableCell(withIdentifier: "Review", for: indexPath) as! ReviewTableViewCell
var reviewObj:Review!
reviewObj = reviewArray[(indexPath as NSIndexPath).row]
let viewsAdded = commentViewsAddedDict[indexPath.row]
if(viewsAdded == nil)
{
for comment in reviewObj.commentArray
{
let label1 = UILabel()
label1.text = “text1”
label1.textColor = UIColor(hexString: "#333333")
let label2 = UILabel()
label2.text = “text2”
label2.numberOfLines = 0
label2.sizeToFit()
label2.textColor = UIColor(hexString: "#666666")
let label3 = UILabel()
label3.text = "----------------------------------------------------------------------"
label3.textColor = UIColor(hexString: "#eeeeee")
cell.stackView1.addArrangedSubview(label1)
cell.stackView1.addArrangedSubview(label2)
cell.stackView1.addArrangedSubview(label3)
}
commentViewsAddedDict[indexPath.row] = true
}
return cell
}
But what happens, the previously added views are not removed and it again tries to add new views.
So I want to know, what is the efficient way to do this.
Secondly, where I am going wrong.
Regards
Ranjit
You are using commentViewsAddedDict to figure out whether rows have been added or not. But whether these labels were added or not is not a function of the row in the table, but rather of the cell, which is reused.
So, I'd would advise:
eliminate this commentViewsAddedDict logic; and
move the logic regarding how many labels have been added to ReviewTableViewCell.
So, you might end up with:
func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell {
let cell = reviewTableView.dequeueReusableCell(withIdentifier: "Review", for: indexPath) as! ReviewTableViewCell
var reviewObject = reviewArray[(indexPath as NSIndexPath).row]
cell.updateLabels(for: reviewObject)
return cell
}
And in ReviewTableViewCell:
func updateLabels(for reviewObject: ReviewObjectType) {
// add label if needed
// update label `text` if needed
// remove any labels that need to be removed
}
It's a little hard to be specific on the logic in updateLabels as the provided code snippet in the question is unclear, but the basic idea is that the ReviewTableViewCell should keep track of whether its labels have been added or not, and on the basis of the reviewObject, decide whether it needs to add a label, update an existing label, or remove any labels not needed for this particular reviewObject. But all of this "label state" logic is a function of the cell (which can be reused), not of which row in the table to which the cell corresponds.

tableViewCell image property reset when selected - swift

I do create a custom cell with 2 UIImageView inside and a UILabel this way:
let ChildCellID = "ChildCell"
if indexPath.section < 2 {
var cell = SectionCell.loadOrDequeueWithTableView(tableView, reuseIdentifier: SectionCellID)
if cell == nil {
cell = SectionCell.viewFromNib()
}
cell.delegate = self as SectionCellDelegate
cell.avatar?.loadAvatarURL(child.avatarUrl)
cell.avatar.layer.cornerRadius = cell.avatar.frame.size.width / 2
The attribut avatar is the UIImageView I decided to round. When a cell is selected my code goes:
func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? {
let tableViewCell = tableView.cellForRowAtIndexPath(indexPath)
if let cell : SectionCell = tableViewCell as? SectionCell {
cell.selection = !cell.selection
} else if let cell : ChildCell = tableViewCell as? ChildCell {
cell.selection = !cell.selection
}
return indexPath
}
Selection is the checkbox as UIImageView. My problem is when I select a cell, the cell.avatar loses his property meaning it goes back as a square form. The cell.avatar is still loaded and I tried cell.avatar.layer.cornerRadius = cell.avatar.frame.size.width / 2in the willSelectRowAtIndexPath and didSelectRowAtIndexPath but without success.
Am I missing anything that makes my avatar loses his rounded property ?
The only thing that could possibly be the origin of this problem would be the fact that I do use the checkbox UIImageView which is really near my avatar.
I found out that the checkbox near my avatar lacked a constraints that, for some random reason and even though it did not impact the avatar view, was resetting the avatar view rounded property.

Change textLabel and imageVIew order in a cell in Swift

I'm putting an image and a text label in the same table cell. I want to make the text label followed by the image but the image comes first. Here is the code.
cell.textLabel?.text = "Text label comes here"
let image = UIImage(named: ChangeYTDArrow!)
var imageView = UIImageView(image: image!)
cell.imageView!.image = image
And here is what happens withe the code.
Thank you in advance.
You should probably use a custom tableViewCell in the interface builder, it allows you to everything you want in a tableViewCell like multiple UILabel or everything you want.
To do so, go in your storyboard, select your tableView then on the tableView property set the field Prototype Cells to 1, a new cell will appears and you will be able to design what you want.
Add an identifier to this cell then create a new class for your cell and add your #IBOutlet, here you should have multiple label & an UIImageView()
Then in your controller with textView method, at the cellForRowAtIndexPath:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let reuseIdentifier = "yourCellIdentifier"
let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) as? yourTableViewCell ?? GolfCourseTableViewCell(style: .Default, reuseIdentifier:yourCellIdentifier)
cell.yourLabel1.text = "blahblah"
cell.yourLabel2.text = "blablahbl"
let image = UIImage(named: ChangeYTDArrow!)
var imageView = UIImageView(image: image!)
cell.imageView!.image = image
return cell
}

Center text around specific word in table cell using Swift

I have a UITableView with multiple cells, each containing a sentence of attributed text. I would like to know how to centre the text in each of these cells around a specific word contained in those sentences.
The result would be a central column of the word but each cell containing different surrounding words.
I'm guessing the place to start is to centre the text in the cell array but doing so in the "cellForRowAtIndexPath" delegate method with the line:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
self.cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "cell")
if(cell.isEqual(NSNull)) {
self.cell = NSBundle.mainBundle().loadNibNamed("cell", owner: self, options: nil)[0] as! UITableViewCell;
}
self.cell.detailTextLabel?.text = self.synonymsCategories[indexPath.row]!
self.cell.textLabel?.attributedText = self.synonymsContext[indexPath.row]
self.cell.detailTextLabel?.textAlignment = .Right
self.cell.textLabel?.textAlignment = NSTextAlignment.Center
self.cell.textLabel?.backgroundColor = UIColor.greenColor()
return self.cell as UITableViewCell
}
But no changes I make to "self.cell.textLabel" produce any visual changes at run time.
Any ideas? Any help much appreciated.
Felix