Detect when a custom cell is selected from within the cell itself?
What you could do is listen for didSelectRowAtIndexPath
on the UITableView, and then call a function in the cell. Here's an example:
class MyCustomCell: UITableViewCell {
func didSelect(indexPath: NSIndexPath) {
// perform some actions here
}
}
Then, in your didSelectRowAtIndexPath
:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? MyCustomCell {
cell.didSelect(indexPath: indexPath)
}
}
How to find out which of the two custom cells is selected?
If there are two custom cells then there must be two Classes of UITableViewCell, you can simply differentiate the cell based on that .
See the code below :
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? MyCustomCell1 {
//Perform action here
} else if let cell = tableView.cellForRow(at: indexPath) as? MyCustomCell2 {
//Perform action here
}
}
UITableView Custom Cell button selects other buttons out of the main view?
Each cell has its own button but it is as if using dequeReusableCell is causing the system to behave this way.
Wrong. UITableViewCells are reusable, so if your tableView has 8 cells visible, when loading the 9th, the cell nr 1 will be reused.
Solution: You need to keep track of the state of your cells. When the method cellForRowAtIndexPath
is called, you need to configure the cell from scratch.
You could have in your ViewController an small array containing the state of the cells:
var cellsState: [CellState]
and store there the selected state for each indexPath. Then in the cellForRowAtIndexPath, you configure the cell with the state.
cell.selected = self.cellsState[indexPath.row].selected
So, an overview of I would do is:
1 - On the cellForRowAtIndexPath
, I would set
cell.button.tag = indexPath.row
cell.selected = cellsState[indexPath.row].selected
2 - Move the IBAction to your ViewController or TableViewController
3 - When the click method is called, update the selected state of the cell
self.cellsState[sender.tag].selected = true
Remember to always configure the whole cell at cellForRowAtIndexPath
Edit:
import UIKit
struct CellState {
var selected:Bool
init(){
selected = false
}
}
class MyCell: UITableViewCell {
@IBOutlet weak var button: UIButton!
override func awakeFromNib() {
self.button.setTitleColor(.red, for: .selected)
self.button.setTitleColor(.black, for: .normal)
}
}
class ViewController: UIViewController, UITableViewDataSource {
var cellsState:[CellState] = []
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
//Add state for 5 cells.
for _ in 0...5 {
self.cellsState.append(CellState())
}
}
@IBAction func didClick(_ sender: UIButton) {
self.cellsState[sender.tag].selected = true
self.tableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cellsState.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! MyCell
cell.button.isSelected = self.cellsState[indexPath.row].selected
cell.button.tag = indexPath.row
return cell
}
}
Programmatically select itself inside UITableViewCell
Well, I found a solution for this, though I don't know if it's the best one.
First, I added a UITapGestureRecognizer
to the UICollectionView
inside my UITableViewCell
, to override the component's one.
-(void)awakeFromNib
{
...
UITapGestureRecognizer *v_CollectionViewTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onClickCollectionView)];
[self.m_CollectionView addGestureRecognizer:v_CollectionViewTap];
...
}
Second I created a block property to hold the code for the programatic selection of a row and created a method that calls this block, setting it as the action for the previously created UIGestureRecognizer
.
typedef void (^OnClickTableViewCellBlock)();
@property (nonatomic, copy) OnClickTableViewCellBlock m_OnClickBlock;
Last, when I'm creating the UITableViewCell
, in the tableView:cellForRowAtIndexPath:
method, I pass a block that calls the tableview:didSelectRowAtIndexPath:
one.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
v_Cell.m_OnClickBlock = ^void()
{
[tableView.delegate tableView:tableView didSelectRowAtIndexPath:indexPath];
};
...
}
Trying to get index of active cell from textField inside custom cell of UITableView in iOS
The way this is usually done, is to give the text field a tag equal to the indexPath.row, or if you have multiple sections, some mathematical combination of the section and row (like 1000*indexPathSection + indexPath.row).
Tableview selection hides my button within the tableview cell
Here is a solution. Give a tag number to the button.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell
// here is the redbutton
var redBtn = UIButton()
redBtn = UIButton(frame: CGRectMake(0, 0, 40, 40))
redBtn.backgroundColor = UIColor.redColor()
cell.contentView.addSubview(redBtn)
redBtn.tag = 101
//label text just added from an array
cell.textLabel?.textAlignment = NSTextAlignment.Center
cell.textLabel?.text = items[indexPath.row]
return cell
}
Now in didSelectRowAtIndex method add this.
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
var selectedCell = tableView.cellForRowAtIndexPath(indexPath) as UITableViewCell!
for subViews in selectedCell.contentView.subviews {
if subViews is UIButton && subViews.tag == 101 {
let button = subViews as! UIButton
selectedCell.bringSubviewToFront(button)
button.backgroundColor = UIColor.redColor()
}
}
}
Get the UITableViewCell indexPath using custom cells
since u are using the custom cell i think u need to handle selection also, because u are touching the button inside the custom cell not the cell itself therefore tableview delegate methods are not fired, better as i said in ur custom cell put a delegate method for example in ur custom cells
in your CellTypeOne.h
add this
//@class CellTypeOne; //if u want t pass cell to controller
@protocol TouchDelegateForCell1 <NSObject> //this delegate is fired each time you clicked the cell
- (void)touchedTheCell:(UIButton *)button;
//- (void) touchedTheCell:(CellTypeOne *)cell; //if u want t send entire cell this may give error add `@class CellTypeOne;` at the beginning
@end
@interface CellTypeOne : UITableViewCell
{
}
@property(nonatomic, assign)id<TouchDelegateForCell1> delegate; //defining the delegate
- (IBAction)actionForFirstButton:(id)sender;
- (IBAction)actionForSecondButton:(id)sender;
- (IBAction)actionForThirdButton:(id)sender;
- (IBAction)actionForFourthButton:(id)sender;
in your CellTypeOne.m
file
@synthesize delegate; //synthesize the delegate
- (IBAction)actionForFirstButton:(UIButton *)sender
{
//add this condition to all the actions becz u need to get the index path of tapped cell contains the button
if([self.delegate respondsToSelector:@selector(touchedTheCell:)])
{
[self.delegate touchedTheCell:sender];
//or u can send the whole cell itself
//for example for passing the cell itself
//[self.delegate touchedTheCell:self]; //while at the defining the delegate u must change the sender type to - (void)touchedTheCell:(CellTypeOne *)myCell; if it shows any error in the defining of the delegate add "@class CellTypeOne;" above the defying the delegate
}
}
and in your ViewContainingMyTableView.h
@interface ViewContainingMyTableView : UIViewController <UITableViewDelegate, UITableViewDataSource ,TouchDelegateForCell1> //confirms to custom delegate like table delegates
{
UITableView *myTBV;
}
@property (retain, nonatomic) IBOutlet UITableView *myTBV;
@end
and in the ViewContainingMyTableView.m
file
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//during the creating the custom cell
CellTypeOne *cell1 = [self.aTableView dequeueReusableCellWithIdentifier:@"cell"];
if(cell1 == nil)
{
cell1 = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
}
cell.delegate = self; //should set the delegate to self otherwise delegate methods does not called this step is important
}
//now implement the delegate method , in this method u can get the indexpath of selected cell
- (void)touchedTheCell:(UIButton *)button
{
NSIndexPath *indexPath = [self.aTableView indexPathForCell:(UITableViewCell *)button.superview];
NSLog(@"%@",indexPath.description);
}
/* if u pass the cell itself then the delegate method would be like below
- (void)touchedTheCell:(CellTypeOne *)myCell
{
NSIndexPath *indexPath = [self.aTableView indexPathForCell:myCell];//directly get the cell's index path
//now by using the tag or properties, whatever u can access the contents of the cell
UIButton *myButton = [myCell.contentView viewWithTag:1000]; //get the button
//... u can access all the contents in cell
}
*/
in your case, this is for first button in the cell, add the delegate methods for each buttons having different functions, repeat above procedure for another buttons in the cell
hope u get this :) hapy coding
Related Topics
A Concise Way to Not Execute a Loop Now That C-Style for Loops Are Going to Be Removed from Swift 3
Uisearchcontroller Searchbar Misaligns While Active During Rotation
How to Get The Coordinates of The Point on a Line That Has The Smallest Distance from Another Point
Swift: How to Add a Class Method in 'string" Extension
Uimarkuptextprintformatter and MAC Catalyst
Count Number of Instances of a Class Swift
How to Print Http Request to Console
"Ambiguous Use" on Generic Method After Migration to Swift 4
Xcode Failed to Resolve Dependency Firebase - Googleappmeasurement Does Not Match Requirement
Protocol Associated Type Typealias Assignment Compile Error
Parametrized Unit Tests in Swift
How to Get Wkwebview to Work in Swift and for an Macos App
Nsjsonserialization Error. Code=3840 "Invalid Value Around Character 0
Can't Load Images on MAC Screensaver Release Build (It Works on Xcode Debug Build)
How to Find The Nth Root of a Value
How to Compare Two Dates (Nsdate) in Swift 3 and Get The Days Between Them