Adding UIButton to the center of a UITableViewCell using Swift - uitableview

The following code only shows button in the last row of the table. Any thoughts on why?
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell = self.myTable.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
let button : UIButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
button.frame = CGRectMake(40, 60, 100, 24)
button.center = self.view.center
button.backgroundColor = UIColor.redColor()
button.addTarget(self, action: "buttonClicked:", forControlEvents:
UIControlEvents.TouchUpInside)
button.setTitle("Click Me !", forState: UIControlState.Normal)
cell.addSubview(button
}
return cell
}

Jawwad's suggestion fixed it. For documentation here is the entire working function:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
let button : UIButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
button.frame = CGRectMake(40, 60, 100, 24)
let cellHeight: CGFloat = 44.0
button.center = CGPoint(x: view.bounds.width / 2.0, y: cellHeight / 2.0)
button.backgroundColor = UIColor.redColor()
button.addTarget(self, action: "buttonClicked:", forControlEvents: UIControlEvents.TouchUpInside)
button.setTitle("Click Me !", forState: UIControlState.Normal)
cell.addSubview(button)
return cell;
}

Instead of
button.center = self.view.center
Try
let cellHeight: CGFloat = 44.0
button.center = CGPoint(x: view.bounds.width / 2.0, y: cellHeight / 2.0)
This assumes that your tableView is full width and your cellHeight is 44.0. You can't get the actual height from the cell itself just yet. If you want the actual height you'd have to get it from the tableView:willDisplayCell:forRowAtIndexPath: method or do something else.
Also instead of using self.myTable you should use the tableView variable in the method itself.

If anyone is looking for a Swift 3 conversion of the above answer, try this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: textCellIdentifier, for: indexPath)
let button : UIButton = UIButton(type:UIButtonType.custom) as UIButton
button.frame = CGRect(origin: CGPoint(x: 40,y :60), size: CGSize(width: 100, height: 24))
let cellHeight: CGFloat = 44.0
button.center = CGPoint(x: view.bounds.width / 2.0, y: cellHeight / 2.0)
button.backgroundColor = UIColor.red
button.addTarget(self, action: #selector(buttonClicked), for: UIControlEvents.touchUpInside)
button.setTitle("Click Me !", for: UIControlState.normal)
cell.addSubview(button)
return cell
}
func buttonClicked(sender : UIButton!) {
print("Clicked!")
}

Related

Don't Click button inside in TableView

I have added one Button into tableview button is not clicked. The button is not clicked on the top of TableView. What should I do to make the button clickable? I need to make the CircleMenu button clickable. The button is now on top of tableView3. Do I need to add the button to the tableView?
override func viewDidLoad() {
super.viewDidLoad()
let button = CircleMenu(
frame: CGRect(x: view.frame.width/2 - 10, y: view.frame.height - 270, width: 50, height: 50),
normalIcon:"icon_menu",
selectedIcon:"icon_close",
buttonsCount: 3,
duration: 4,
distance: 85)
button.backgroundColor = UIColor.flatSkyBlue
button.delegate = self
button.layer.cornerRadius = button.frame.size.width / 2.0
view.addSubview(button)
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == self.tableView1 {
if !chipnumber2.text!.isEmpty {
let cell:DeviceTableViewCell2 = tableView1.dequeueReusableCell(withIdentifier: cellIdNew, for: indexPath) as! DeviceTableViewCell2
let deviceItem: Device3New = itemsNew[indexPath.row]
let tap1 = UITapGestureRecognizer(target: self, action: #selector(tittleNewTapped(_:)))
let tap2 = UITapGestureRecognizer(target: self, action: #selector(tittleNewTapped2(_:)))
return cell
}
}
if tableView == self.tableView2 {
if !chipnumber.text!.isEmpty {
let cell:DeviceTableViewCell2 = tableView2.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! DeviceTableViewCell2
let deviceItem: Device3 = items[indexPath.row]
cell.backgroundColor = GradientColor(UIGradientStyle.leftToRight, frame: self.view.frame, colors: [UIColor.flatPowderBlueDark, UIColor.flatSand])
return cell
}
}
if tableView == self.tableView3 {
if !chipnumber3.text!.isEmpty {
let cell:DeviceTableViewCell2 = tableView3.dequeueReusableCell(withIdentifier: cellIdNew2, for: indexPath) as! DeviceTableViewCell2
cell.backgroundColor = GradientColor(UIGradientStyle.leftToRight, frame: self.view.frame, colors: [UIColor.flatPowderBlueDark, UIColor.flatSand])
return cell
}
}
return UITableViewCell()
}
}
Just add a target to the button:
button.addTarget(self, action: #selector(buttonClicked(_:)), for: .touchUpInside)
And then a selector method:
#objc func buttonClicked(_ sender: UIButton) {
print("clicked!")
}
(Edit: Possible duplicate?)

how to implement another level in table view?

Here I had implemented collapsible table view in which first level can be used as sections and the child class can be given as rows count and for another child class how it to be implemented in table view and I am having a expand button if I click on it need to expand and show the third level and the image is shown below libraries can anyone help me how to implement this ?
and here is my code is shown here which I had already implemented
func numberOfSections(in tableView: UITableView) -> Int {
return detailsArray.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return detailsArray[section].childern.count
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView(frame: CGRect(x: 275, y: 5, width: 30, height: 35))
headerView.backgroundColor = UIColor.white
headerView.tag = section
let headerString = UILabel(frame: CGRect(x: 10, y: 10, width: tableView.frame.size.width-10, height: 30)) as UILabel
headerString.text = detailsArray[section].name
headerView .addSubview(headerString)
let btn :UIButton = UIButton(frame: CGRect(x: UIScreen.main.bounds.size.width - 35, y: 5, width: 30, height: 35))
btn.backgroundColor = UIColor.white
if (detailsArray[section].childern.count != 0){
btn.setImage(plusImage , for: .normal)
}
else {
btn.setImage(UIImage(named: ""), for: .normal)
}
if detailsArray[section].expanded == true {
btn.setImage(minusImage, for: .normal)
}
else {
btn.setImage(plusImage, for: .normal)
}
btn.tag = section
btn.addTarget(self, action: #selector(buttonTapped(sender:)), for: .touchUpInside)
headerView.addSubview(btn)
let headerTapped = UITapGestureRecognizer (target: self, action:#selector(sectionHeaderTapped(recognizer:)))
headerView .addGestureRecognizer(headerTapped)
return headerView
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
activityIndicator.stopAnimating()
activityIndicator.hidesWhenStopped = true
tableView.isHidden = false
let cell = tableView.dequeueReusableCell(withIdentifier: "categoriescell", for: indexPath) as! CategoriesTableViewCell
let obj1 = self.detailsArray[indexPath.section].childern[indexPath.row]
cell.categoryLabel?.text = obj1.name
cell.expandButton.tag = indexPath.row
cell.expandButton.setImage(plusImage, for: .normal)
return cell
}
func sectionHeaderTapped(recognizer: UITapGestureRecognizer) {
let newViewcontroller = storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController
self.navigationController?.pushViewController(newViewcontroller, animated: true)
}
func buttonTapped(sender: UIButton) {
let section = sender.tag
detailsArray[section].expanded = !detailsArray[section].expanded
tableView.beginUpdates()
for i in 0 ..< detailsArray[section].childern.count {
tableView.reloadRows(at: [IndexPath(row: i, section: section)], with: .automatic)
}
if (detailsArray[section].childern.count != 0) {
if (sender.currentImage == plusImage){
sender.setImage(minusImage, for: .normal)
}
else {
sender.setImage(plusImage, for: .normal)
}
}
else {
sender.setImage(UIImage(named: ""), for: .normal)
}
tableView.endUpdates()
}

Swift - How to change the color of an accessoryType (disclosureIndicator)?

I have question about the accessoryType of cells. I am using a cell with an disclosureIndicator as accessoryType and I want to change it's color but I can't.
Does anyone know if this is a bug or if Apple forces me to use the grey color?
Actually I can change the colors of other accessoryType.
My code looks like this:
let cell = tableView.dequeueReusableCell(withIdentifier: "identifier", for: indexPath) as! customCell
cell.tintColor = UIColor.red
cell.accessoryType = .disclosureIndicator
And my arrow is still grey. But if I use a checkmark accessoryType it becomes red.
Is there any way to fix this or do I have to use a colored image?
You can do something like this
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.tintColor = UIColor.white
let image = UIImage(named: "Arrow.png")
let checkmark = UIImageView(frame:CGRect(x:0, y:0, width:(image?.size.width)!, height:(image?.size.height)!));
checkmark.image = image
cell.accessoryView = checkmark
let object = objects[indexPath.row] as! NSDate
cell.textLabel!.text = object.description
return cell
}
Sample Arrow Images
Output
Use SF Symbol
let image = UIImage(systemName: "chevron.right")
let accessory = UIImageView(frame:CGRect(x:0, y:0, width:(image?.size.width)!, height:(image?.size.height)!))
accessory.image = image
// set the color here
accessory.tintColor = UIColor.white
cell.accessoryView = accessory
Updated for Swift 4.2 with images attached:
cell.accessoryType = .disclosureIndicator
cell.tintColor = .black
let image = UIImage(named:"disclosureArrow")?.withRenderingMode(.alwaysTemplate)
if let width = image?.size.width, let height = image?.size.height {
let disclosureImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: width, height: height))
disclosureImageView.image = image
cell.accessoryView = disclosureImageView
}
Images you can use:
What it could look like:
Bellow Code is Swift 3.0 code, and will change the accessoryType color as per tintColor.
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = "SOME TITLE GOES HERE"
cell.accessoryType = .disclosureIndicator
cell.tintColor = UIColor.blue
let image = UIImage(named:"arrow1")?.withRenderingMode(.alwaysTemplate)
let checkmark = UIImageView(frame:CGRect(x:0, y:0, width:(image?.size.width)!, height:(image?.size.height)!));
checkmark.image = image
cell.accessoryView = checkmark
return cell
}
Swift 5. Extension style ;)
extension UITableViewCell {
func setupDisclosureIndicator() {
accessoryType = .disclosureIndicator
let imgView = UIImageView(frame: CGRect(x: 0, y: 0, width: 7, height: 12))
imgView.contentMode = .scaleAspectFit
imgView.image = UIImage(named: "your_icon_name")
accessoryView = imgView
}
}
Swift 5 & iOS 15 & Xcode 13
Here is an extension which uses SF Symbols, so you have a chevron like the default disclosure indicator one:
extension UITableViewCell {
func addCustomDisclosureIndicator(with color: UIColor) {
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 10, height: 15))
let symbolConfig = UIImage.SymbolConfiguration(pointSize: 15, weight: .regular, scale: .large)
let symbolImage = UIImage(systemName: "chevron.right",
withConfiguration: symbolConfig)
button.setImage(symbolImage?.withTintColor(color, renderingMode: .alwaysOriginal), for: .normal)
button.tintColor = color
self.accessoryView = button
}
}
You can use it like this:
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.addCustomDisclosureIndicator(with: .white) // Here your own color
return cell
}
Swift 5 & iOS 11-15
A combination of some answers
extension UITableViewCell {
func addCustomDisclosureIndicator(with color: UIColor) {
accessoryType = .disclosureIndicator
let disclosureImage = UIImage(named: "arrow_right")?.withRenderingMode(.alwaysTemplate)
let imageWidth = (disclosureImage?.size.width) ?? 7
let imageHeight = (disclosureImage?.size.height) ?? 12
let accessoryImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: imageWidth, height: imageHeight))
accessoryImageView.contentMode = .scaleAspectFit
accessoryImageView.image = disclosureImage
accessoryImageView.tintColor = color
accessoryView = accessoryImageView
}
}

Label with button addTarget event not fire

I have a label in the tableview cell . label have text end of the text has a button that button represent for user like . everything is fine but problem is hitForLike not fire .button click event not fire. do i miss anything
var titleLabel : UILabel = {
var label = UILabel()
label.font = UIFont.systemFont(ofSize: 21)
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
func hitForLike(_ sender : UIButton){
print("i miss you ....")
}
func titleWithLikeButton(title:String,isFavorite : Bool){
titleLabel.text = title
let button = UIButton(frame: CGRect(x: titleLabel.intrinsicContentSize.width, y: 0, width: 44, height: 44))
//setup your button here
button.setTitleColor(UIColor.red, for: UIControlState.normal)
let image = UIImage(named: "heart-empty.png")
button.setImage(image, for: UIControlState.normal)
button.addTarget(self, action: #selector(hitForLike(_:)), for: UIControlEvents.touchUpInside)
//Add the button to the text label
titleLabel.addSubview(button)
}
I think you need to enable user interaction on your label, like so:
titleLabel.isUserInteractionEnabled = true
So your entire function ends up looking like this:
func titleWithLikeButton(title:String,isFavorite : Bool){
titleLabel.text = title
titleLabel.isUserInteractionEnabled = true //enable userinteraction
let button = UIButton(frame: CGRect(x: titleLabel.intrinsicContentSize.width, y: 0, width: 44, height: 44))
//setup your button here
button.setTitleColor(UIColor.red, for: UIControlState.normal)
let image = UIImage(named: "heart-empty.png")
button.setImage(image, for: UIControlState.normal)
button.addTarget(self, action: #selector(hitForLike(_:)), for: UIControlEvents.touchUpInside)
//Add the button to the text label
titleLabel.addSubview(button)
}
Hope that helps.
You have to set your cell button target in func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell, like below:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableViewForPAC.dequeueReusableCell( withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell
cell.yourButton.tag = indexpath.row
cell.yourButton.addTarget(self, action: #selector(hitForLike(_:)), for: UIControlEvents.touchUpInside)
return cell
}
func hitForLike(_ sender : UIButton){
print(sender.tag)
print("i miss you ....")
}

Programmatically added buttons target action not working in custom tableviewcell

I added programmatically two buttons in custom tableviewcell, but target action not working. What can i do to solve this problem ?(swift)
This is my code of adding buttons:
override func awakeFromNib() {
super.awakeFromNib()
func createCueButton() -> UIButton{
let button = UIButton()
button.titleLabel?.textColor = UIColor.whiteColor()
button.titleLabel?.font = UIFont.boldSystemFontOfSize(16.0)
return button
}
completeButton = createCueButton()
completeButton.setTitle("Complete", forState: UIControlState.Normal)
completeButton.backgroundColor = UIColor.greenColor()
completeButton.addTarget(self, action: "buttonPressed:", forControlEvents: .TouchUpInside)
addSubview(completeButton)
deleteButton = createCueButton()
deleteButton.setTitle("Delete", forState: .Normal)
deleteButton.backgroundColor = UIColor.redColor()
deleteButton.addTarget(self, action: "buttonPressed:", forControlEvents: .TouchUpInside)
addSubview(deleteButton)
}
func buttonPressed(sender: UIButton){
var alertView = UIAlertView();
alertView.addButtonWithTitle("OK");
alertView.title = "Alert";
alertView.message = "Button Pressed!!!";
alertView.show();
}
override func layoutSubviews() {
super.layoutSubviews()
completeButton.frame = CGRect(x: 0, y: 0, width: cuesWidth, height: bounds.size.height)
deleteButton.frame = CGRect(x: bounds.size.width - cuesWidth, y: 0, width: cuesWidth, height: bounds.size.height)
}
I preferred the answer for your question, please follow the below steps
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
return 75
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let identifier = "Custom"
var cell: CustomCell! = tableView.dequeueReusableCellWithIdentifier(identifier) as? CustomCell
if cell == nil
{
tableViewCustom.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: identifier)
cell = tableViewCustom.dequeueReusableCellWithIdentifier(identifier) as? CustomCell
}
//First Button for adding in Custom Cell
let btn = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
btn.backgroundColor = UIColor.greenColor()
btn.setTitle("Complete", forState: UIControlState.Normal)
btn.frame = CGRectMake(0, 6, 80, 40)
btn.addTarget(self, action: "completeButtonTouched:", forControlEvents: UIControlEvents.TouchUpInside)
cell.contentView.addSubview(btn)
//Second Button for adding in CustomCell
let btn2 = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
btn2.backgroundColor = UIColor.greenColor()
btn2.setTitle("Delete", forState: UIControlState.Normal)
btn2.frame = CGRectMake(180, 5, 80, 40)
btn2.addTarget(self, action: "deleteButtonTouched:", forControlEvents: UIControlEvents.TouchUpInside)
cell.contentView.addSubview(btn2)
return cell
}
func completeButtonTouched(sender:UIButton!)
{
println("Complete Button Target Action Works!!!")
}
func deleteButtonTouched(sender:UIButton!)
{
println("Delete Button Target Action Works!!!")
}
Whatever when add the button to custom cell programmatically, please apply the below code
cell.contentView.addSubview(btn)

Resources