How to get multiple buttons from a single tableViewcell?
If you want the indexPath
to access the questions Array
then you can try like this.
func buttonClicked(sender:UIButton) {
let center = sender.center
let point = sender.superview!.convertPoint(center, toView:self.tableView)
let indexPath = self.tableView.indexPathForRowAtPoint(point)
//Now you have tag of button check for that
if (sender.tag == 201) {
print("Option A")
}
else if (sender.tag == 202) {
print("Option B")
}
else if (sender.tag == 203) {
print("Option C")
}
else {
print("Option D")
}
print(question[indexPath.row])
}
Multiple buttons in UITableViewCell in a 'top-down' UITableView
You can add UIButton
to your UITableViewCell
and access these UIButton
via tag and add target method to these buttons as:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// create a new cell if needed or reuse an old one
let cell:UITableViewCell = self.tableVw.dequeueReusableCell(withIdentifier: "Cell") as UITableViewCell!
//Access UIButton
let button1:UIButton = cell.viewWithTag(10) as! UIButton
let button2:UIButton = cell.viewWithTag(11) as! UIButton
let button3:UIButton = cell.viewWithTag(12) as! UIButton
//Add Action Methods to UIButtons
button1.addTarget(self, action: #selector(FisrtButtonClick), for: .touchUpInside)
button2.addTarget(self, action: #selector(SecondButtonClick), for: .touchUpInside)
button3.addTarget(self, action: #selector(ThirdButtonClick), for: .touchUpInside)
return cell
}
Button Actions
// MARK: - UIButton Methods.
func FisrtButtonClick(_ sender: Any) {
//Get Button cell position.
let ButtonPosition = (sender as AnyObject).convert(CGPoint.zero, to: tableVw)
let indexPath = tableVw.indexPathForRow(at: ButtonPosition)
if indexPath != nil {
print("Cell indexPath: \(indexPath?.row)")
}
}
func SecondButtonClick(_ sender: Any) {
//Get Button cell position.
let ButtonPosition = (sender as AnyObject).convert(CGPoint.zero, to: tableVw)
let indexPath = tableVw.indexPathForRow(at: ButtonPosition)
if indexPath != nil {
print("Cell indexPath: \(indexPath?.row)")
}
}
func ThirdButtonClick(_ sender: Any) {
//Get Button cell position.
let ButtonPosition = (sender as AnyObject).convert(CGPoint.zero, to: tableVw)
let indexPath = tableVw.indexPathForRow(at: ButtonPosition)
if indexPath != nil {
print("Cell indexPath: \(indexPath?.row)")
}
}
How to identify click from multiple buttons in a UITableViewCell from a UITableView - Swift 4
implement your button action in UIviewcontroller not a UITableViewCell, create the target in inside the cellforRow as well as add the Tag for each target for identify which button was user pressed.for E.g
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let show=shows[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "ShowCell") as!
ShowCell
cell.graphButton.tag = indexPath.row
cell.buyButton.tag = indexPath.row
cell.reviewButton.tag = indexPath.row
cell.graphButton?.addTarget(self, action: #selector(self.graphButtonClicked(_:)), for: .touchUpInside)
cell.buyButton?.addTarget(self, action: #selector(self.buyButtonClicked(_:)), for: .touchUpInside)
cell.reviewButton?.addTarget(self, action: #selector(self.reviewButtonClicked(_:)), for: .touchUpInside)
cell.setShow(show: show)
return cell
}
and handle the action as like
@objc func buyButton( _ sender: UIButton) {
print("buyButton Action Found the index of \(sender.tag)")
}
@objc func graphButtonClicked( _ sender: UIButton) {
print("graphButtonClicked Action Found the index of \(sender.tag)")
}
@objc func reviewButtonClicked( _ sender: UIButton) {
print("reviewButtonClicked Action Found the index of \(sender.tag)")
}
Option 2
if you want to perform in your button action in UItableviewcell class using delegate pattern, then refer this duplicate answer
Having multiple buttons in cell that pass selected buttons set data to cell
You can pass back values in closures.
So, in your Cell
class (naming is confusing to discuss - make it something like SelectItemCell
), you could change your closure var to:
var addActionHandler: ((Int) -> Void)?
Then, in your addToCart
button action, something along these lines:
@IBAction func atcBtn(_ sender: UIButton) {
// pass back the user selected values
var i = 0
switch lastSelectedButton {
case optionBtn1:
i = 1
case optionBtn2:
i = 2
default:
i = 3
}
self.addActionHandler?(i)
}
That's rather awkward, and presumably you will be tracking actual values, but for example purposes this will work.
Now, in your VC that holds that table, in cellForRowAt
, instead of your current:
cell.addActionHandler = {
Cart.currentCart.items.append(item)
}
assign the closure like this:
cell.addActionHandler = { (option: Int) in
print("Option selected = \(option)")
// do something based on the option that was selected
// maybe item.selectedOption = option
Cart.currentCart.items.append(item)
}
If you want to pass back more than one value, add parameters:
var addActionHandler: ((Int, Int) -> Void)?
and in your button action:
self.addActionHandler?(priceVal, weightVal)
and your closure becomes:
cell.addActionHandler = { (price: Int, weight: Int) in
// use price and weight vars
// ...
}
Edit
If you don't already have a .selectedOption
property of your Items
class, you should add one (of type Int). You can use that to track the user's selection.
Change your cellForRowAt
func along these lines:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? Cell else { return UITableViewCell() }
// use var to make item mutable
var item = itemSetup[indexPath.row]
// pass item to cell to configure labels / buttons / etc
cell.configure(withItem: item)
// when the "add to cart" button in the cell is tapped
cell.addActionHandler = { (option: Int) in
// option will be 1, 2 or 3, indicating which button the user tapped
print("Option selected = \(option)")
// update the .selected property of your data
item.selectedOption = option
Cart.currentCart.items.append(item)
}
return cell
}
Now, in your CartCell
in your CartViewController
, you can fill in the labels like this:
if items.selectedOption == 1 {
lblSubTotal.text = "$\(formatter.string(for: items.price1)!)"
lblWeight.text = "\(items.weight1)"
} else if items.selectedOption == 2 {
lblSubTotal.text = "$\(formatter.string(for: items.price2)!)"
lblWeight.text = "\(items.weight2)"
} else if items.selectedOption == 3 {
lblSubTotal.text = "$\(formatter.string(for: items.price3)!)"
lblWeight.text = "\(items.weight3)"
}
How To Add Multiple Buttons To UITableViewCells Swift
You need to subclass UITableViewCell
and create your own custom implementation, you can do this by code or by IB
This is the IB way of doing it:
When you create a new Cocoa Touch Class file, choose to subclass from UITableViewCell and select the create XIB file option. After that configure the XIB's view whoever you want and set a reuse identifier in the Identity Inspector.
If you want to have the layout from your screenshot, drag a UIStackView
, set it's constraints to top, bottom, leading and trailing to the contentView of the cell, set the alignment to horizontal, then select fill equally
and drag 3 UIButton
s inside of it, the stackView will make sure to arrange them nicely
In your viewController don't forget to register the cell with the tableView, and then return that cell from cellForRowAtIndexPath
How to detect multiple buttons in tableview cell
I did like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier];
}
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(10.0, 0.0, self.tableView.frame.size.width/4, 40.0);
button.tag = 100 + indexPath.row*total_buttons_in_a_row;
[button setTitle:[NSString stringWithFormat:@"%ld",(long)button.tag] forState:UIControlStateNormal];
[button addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:button];
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button2.frame = CGRectMake(10.0+self.tableView.frame.size.width/4+10.0, 0.0, self.tableView.frame.size.width/4, 40.0);
button2.tag = 100 + indexPath.row*total_buttons_in_a_row + 1;
[button2 setTitle:[NSString stringWithFormat:@"%ld",(long)button2.tag] forState:UIControlStateNormal];
[button2 addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:button2];
UIButton *button3 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button3.frame = CGRectMake(10.0+self.tableView.frame.size.width/4*2+10.0, 0.0, self.tableView.frame.size.width/4, 40.0);
button3.tag = 100 + indexPath.row*total_buttons_in_a_row + 2;
[button3 setTitle:[NSString stringWithFormat:@"%ld",(long)button3.tag] forState:UIControlStateNormal];
[button3 addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:button3];
return cell;
}
-(void)btnClicked:(UIButton *)sender{
id selectedButton = [self.view viewWithTag:sender.tag];
if ([selectedButton backgroundColor] == [UIColor redColor]) {
[selectedButton setBackgroundColor:[UIColor clearColor]];
}else{
[selectedButton setBackgroundColor:[UIColor redColor]];
}
}
total_buttons_in_a_row
is an Int
. In your case define it in viewDidLoad
total_buttons_in_a_row=3
P.S - set the Buttons CGRectMake
according to your need.
Related Topics
iOS Swift Nsmutabledata Has No Member Appendstring
Using Static Libraries with Cocoapods 1.5 No Such Module at Import
Automatically Change Cell Height Based on Content - Swift
Swift iOS - Tag Collection View
Today Extension with Uicollectionview Different Behaviour Compared to Single View Application
How to Add Images as Text Attachment in Swift Using Nsattributedstring
How to Automatically Create an Initializer for a Swift Class
Unusernotificationcenter.Current().Getdeliverednotifications Only Ever Returns an Empty Array
Libmobilegestalt Mobilegestalt.C:890: Mgisdeviceoneoftype Is Not Supported on This Platform
Swift Lazy and Optional Properties
Swift - Using Cgcontext to Draw with Finger
Uitextfield Keyboard with Only Alphabet, No Numbers, No Caps, No Spacebar
Uitableview Inside Uitableviewcell with Dynamic Height
How to Use " Let Newswiftcolor = Uicolor(Red: 255, Green: 165, Blue: 0, Alpha: 0)
How to Completely Reload a View So That Viewdidload Gets Run Again