Can't get my UIButton in TableViewCell to fire - ios

I have a subclassed UITableViewCell with a "Start" and "Done" button on each cell. The "Done" button gets created after you press "Start". If I have my button press logic in my subclassed UITableViewCell file, it triggers just fine.
But I realize I actually want the button press to trigger the editing mode in the table view, so I want to have some logic in my cellForRowAtIndexPath instead of the subclassed file. But then I can't get the button to fire :(
What am I doing wrong or not understanding?
My TableViewCell.m
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self.startButton = [[UIButton alloc] initWithFrame:CGRectMake(250 + 0.60 * self.screenWidth, 65, 150, 30)];
[self.startButton addTarget:self action:#selector(onStartButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
self.startButton.backgroundColor = [UIColor colorWithRed:0.16 green:0.65 blue:0.19 alpha:1.0];
btnLayer = [self.startButton layer];
[btnLayer setMasksToBounds:YES];
[btnLayer setCornerRadius:5.0f];
[self.startButton setTag:1];
[self addSubview:self.startButton];
}
- (void)onStartButtonPressed:(id)sender {
if (self.countdown)
{
[self beginDoneButton];
}
}
-(void)beginDoneButton {
self.startButton.enabled = NO;
self.startButton.hidden = YES;
self.doneButton = [[UIButton alloc] initWithFrame:CGRectMake(250 + 0.60 * self.screenWidth, 65, 150, 30)];
self.doneButton.backgroundColor = [UIColor colorWithRed:0.16 green:0.65 blue:0.19 alpha:1.0];
CALayer *btnLayer = [self.doneButton layer];
[btnLayer setMasksToBounds:YES];
[btnLayer setCornerRadius:5.0f];
[self.doneButton setTitle:#"Done "forState:UIControlStateNormal];
[self addSubview:self.doneButton];
}
My TableViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// get index of Data
int index = (int) indexPath.row;
id order = [orders objectAtIndex:index];
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"orderCell"];
cell = [[OrderTableViewCell alloc] initWithStyle:UITableViewCellSelectionStyleNone reuseIdentifier:#"orderCell"];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
cell.customerNameLabel.text = [order objectForKey:#"first_name"];
cell.orderLabel.text = [NSString stringWithFormat: #"Order #%#", [order objectForKey:#"order_id"]];
[cell.customerImageView sd_setImageWithURL:[NSURL URLWithString: [order objectForKey:#"profile_image"]]
placeholderImage:[UIImage imageNamed:#"stub"]
];
[cell.messageButton setTitle:#"Message" forState:UIControlStateNormal];
// This doesn't work
[cell.doneButton addTarget:self action:#selector(onDoneButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
// This doesn't get fired
- (IBAction)onDoneButtonPressed:(id)sender {
NSLog(#"pressed");
UITableViewCell *cell = (UITableViewCell *)[sender superview];
NSIndexPath *pathToCell = [self.tv indexPathForCell:cell];
}

How about this:
In your custom table view cell, create your buttons but don't add target/actions to them Just connect them to an IBOutlet in your cell's class.
Then in your cellForRowAtIndexPath, cast your cell pointer to your custom cell class, and use cell.button1Outlet outlet to set the target/action on the buttons with the view controller as the target. Now your cell buttons will invoke a method in the view controller, not in the cell, even though the outlets belong to the cells.

Related

iOS - Custom AccessoryView not showing in UITableViewCell

I have tried to show a custom view with an accept button and decline button (as subviews) in a table view cell. I have the following code implemented:
tableView: cellForRowAtIndexPath: method
...
if ([status isEqualToString:#"pending"] || [status isEqualToString:#"declined"]){
cell.accessoryView = [self setAccessoryViewForCell:cell];
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
...
- (UIView *)setAccessoryViewForCell:(UITableViewCell *)cell
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(192, 0, 128, 44)];
UIButton *acceptButton = [[UIButton alloc] initWithFrame:CGRectMake(2, 5, 60, 34)];
UIButton *declineButton = [[UIButton alloc] initWithFrame:CGRectMake(66, 5, 60, 34)];
[acceptButton setTitle:#"A" forState:UIControlStateNormal];
[declineButton setTitle:#"D" forState:UIControlStateNormal];
[acceptButton addTarget:self action:#selector(acceptButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[declineButton addTarget:self action:#selector(declineButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[view addSubview:acceptButton];
[view addSubview:declineButton];
return view;
}
I have tried to debug it, but the methods are called appropriately.
Finally, the problem was not in the cellForRowAtIndexPath: method, but in the setAccessoryViewForCell: method. When creating a view for containing two buttons as subviews I really should not have used literal values for the frames. Instead of setting a view for accessoryView property, I rewrote the whole cellForRowAtIndexPath: method and added a subview to the cell's contentView.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"notificationsCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
}
PFObject *user = [self.objects objectAtIndex:indexPath.row];
NSString *firstName = [user objectForKey:#"firstName"];
NSString *lastName = [user objectForKey:#"lastName"];
cell.textLabel.text = [NSString stringWithFormat:#"%# %#", firstName, lastName];
UIView *view = [UIView new];
view.frame = CGRectMake(230, 2, 80, 40);
view.backgroundColor = [UIColor whiteColor];
UIButton *acceptButton = [UIButton buttonwithType:UIButtonTypeCustom];
UIButton *declineButton = [UIButton buttonWithType:UIButtonTypeCustom];
[acceptButton setTitle:#"" forState:UIControlStateNormal];
[declineButton setTitle:#"" forState:UIControlStateNormal];
[acceptButton setImage:[UIImage imageNamed:#"Ok.png"] forState:UIControlStateNormal];
[declineButton setImage:[UIImage imageNamed:#"Close.png"] forState:UIControlStateNormal];
[acceptButton addTarget:self action:#selector(acceptButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[declineButton addTarget:self action:#selector(declineButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
acceptButton.frame = CGRectMake(CGRectGetMinX(view.bounds), CGRectGetMinY(view.bounds), CGRectGetWidth(view.bounds)/2, CGRectGetHeight(view.bounds));
declineButton.frame = CGRectMake(CGRectGetMidX(view.bounds), CGRectGetMinY(view.bounds), CGRectGetWidth(view.bounds)/2, CGRectGetHeight(view.bounds));
[view addSubview:acceptButton];
[view addSubview:declineButton];
[cell.contentView addSubview:view];
return cell;
}
The main difference was that when setting the frames for each button, I used literal values (not a good practice) and now I used the CGRect functions CGRectGetMinX(CGRect rect), CGRectGetMinY(CGRect rect), CGRectGetWidth(CGRect rect), CGRectGetMidX(CGRect rect) and CGRectGetHeight(CGRect rect) to get more accurate values for setting each button's frame. This was a misunderstanding of how a UIView's frames work, I recommend always to use these functions to get the origin and size of subviews and not to use literal values.
The problem appeared to be you are not returning the UIView from setAccessoryViewForCell method.
return view;
Please return the view from the mentioned method, it might solve your problem.

Adding UIButtons to uiimage of a UICollectionView cells programmatically

I have a UIViewController with a UICollectionView image gallery created inside it programmatically. I want to add a button to the on each uiimage of UICollectionView cell: The code in CMFViewController.h.m file for adding button to imageview is:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CMFGalleryCell *cell = (CMFGalleryCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
NSString *imageName = [self.dataArray objectAtIndex:indexPath.row];
[cell setImageName:imageName];
// [[cell myButton] addTarget:self action:#selector(myClickEvent:event) forControlEvents:UIControlEventTouchUpInside];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(80.0, 210.0, 100.0, 20.0);
[button addTarget:self action:#selector(show) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:#"ShowView" forState:UIControlStateNormal];
// NSMutableArray *buttonArray = [NSMutableArray arrayWithCapacity:100];
// for (int i = 0; i < 4; i++) {
// NSUInteger index = arc4random() % 4;
// newButton.frame = CGRectMake( 5, 5, 10, 10); // Whatever position and size you need...
// UIImage *buttonImage = [UIImage imageNamed:[self.dataArray objectAtIndex:indexPath.row]];
//[newButton setBackgroundImage:buttonImage forState:UIControlStateNormal];
// [buttonArray addObject:newButton];
// }
// newButton = buttonArray; // Where myButtons is a NSArray property of your class, to store references to the buttons.
// [newButton addTarget:self action:#selector(loadImages:) forControlEvents:UIControlEventTouchUpInside];
//[newButton addTarget:self action:#selector(updateCell) forControlEvents:UIControlEventTouchUpInside];
[cell updateCell];
return cell;
}
I have tied to get help from codes at following links
adding-a-uibutton-to-a-uicollectionview
UIButton in cell in collection view not receiving touch up inside event
Please give my your suggestion and help me on this issue.
from this link u can download source code in Creating a Paged Photo Gallery With a UICollectionView: their i want to place next and previous buttons on middle lines of each image of the screen
For implementing next and previous buttons, don't added it on each image, better u add it on collection view, what chinttu-maddy-ramani told in his answer is correct, but he is doing in xib file, but programatically u can do it like below,
just add this code
Edit for requirement updating the buttons
in CMFViewController.h file make two button properties
replace by below code
#import <UIKit/UIKit.h>
#interface CMFViewController : UIViewController <UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>
#property (nonatomic, strong) UIButton *nextButton;
#property (nonatomic, strong) UIButton *prevButton;
#end
in CMFViewController.m file
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self loadImages];
[self setupCollectionView];
[self addNextAndPreviousButtons];//add a method to add previous and next buttons
}
//hear u are adding previous and next images, but i didn't added the constraints u add it if u want t work in both orientation
- (void)addNextAndPreviousButtons
{
_nextButton = [UIButton buttonWithType:UIButtonTypeSystem];
_nextButton.frame =CGRectMake(self.view.bounds.size.width - 40, self.view.bounds.size.height/2, 50, 30);
[_nextButton setTitle:#"Next" forState:UIControlStateNormal];
[_nextButton addTarget:self action:#selector(nextButtonAction:) forControlEvents:UIControlEventTouchUpInside];
_prevButton = [UIButton buttonWithType:UIButtonTypeSystem];
_prevButton.frame = CGRectMake(self.view.bounds.origin.x, self.view.bounds.size.height/2, 50, 30);
[_prevButton setTitle:#"Prev" forState:UIControlStateNormal];
[_prevButton addTarget:self action:#selector(previousButtonAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_nextButton];
[self.view addSubview:_prevButton];
}
//previous button action
- (void)previousButtonAction:(id)sender
{
NSArray *visibleCell = [_collectionView visibleCells];
if(visibleCell)
{
NSIndexPath *path = [_collectionView indexPathForCell:[visibleCell lastObject]];
if(!path.row == 0)
{
NSIndexPath *nextPath = [NSIndexPath indexPathForItem:(path.row - 1) inSection:0];
[_collectionView scrollToItemAtIndexPath:nextPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
}
}
}
//next button action
- (void)nextButtonAction:(id)sender
{
NSArray *visibleCell = [_collectionView visibleCells];
if(visibleCell)
{
NSIndexPath *path = [_collectionView indexPathForCell:[visibleCell lastObject]];
if(path.row < [_dataArray count] - 1)
{
NSIndexPath *nextPath = [NSIndexPath indexPathForItem:(path.row + 1) inSection:0];
[_collectionView scrollToItemAtIndexPath:nextPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
}
}
}
//edited the method addNextAndPreviousButtons please replace it by this edited answer
//for all cases even when u are swiping
//this is to handle buttons either by tapping or navigation through swiping the collection view
- (void)updateButtons:(NSInteger)row
{
//at the beginning
if(row == 0)
{
_prevButton.hidden = YES;
_nextButton.hidden = NO;
return;
}
else if(row == ([_dataArray count] -1))
{
_nextButton.hidden = YES;
_prevButton.hidden = NO;
}
else
{
_nextButton.hidden = NO;
_prevButton.hidden = NO;
}
}
//finally u have to call updateButtons method this method
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CMFGalleryCell *cell = (CMFGalleryCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
NSString *imageName = [self.dataArray objectAtIndex:indexPath.row];
[cell setImageName:imageName];
[cell updateCell];
[self updateButtons:indexPath.row]; //update the buttons
return cell;
}
you can add button in you cell to direct drag & drop button in CMFGalleryCell.xib please check attach screenshot. and add button constraint to center horizontally and center vertically with your cell.
for suggestion only if you want next-previous functionality then you can also add button in main xib in CMFViewController.xib as per below screenshot.

When UIPickerView Value changed then table row changed in ios

In my UIview I have UITextField when textfield clicked then I use UIPickerView. Then I select value this value goes in textField.
Now I want when textfield value changed then table row value change.
I have used following code
- (void)viewDidLoad:
{
[super viewDidLoad];
[self loadCriteria];
UILabel * projectDetailLable = [[UILabel alloc] initWithFrame:CGRectMake(0,[topBar bottom],320, 30)];
projectDetailLable.textColor = [UIColor whiteColor];
projectDetailLable.backgroundColor = UIColorFromRGB(0x28a0d8);
projectDetailLable.font = [UIFont boldSystemFontOfSize:16];
projectDetailLable.text = #"Choose Criteria Category:";
projectDetailLable.textAlignment = NSTextAlignmentLeft;
[self.view addSubview:projectDetailLable];
criteriaTextField = [[UITextField alloc] initWithFrame:CGRectMake(2, [projectDetailLable bottom]+2, 316, 30)];
criteriaTextField.borderStyle = UITextBorderStyleLine;
// criteriaTextField.text = #"Health & Well being";
criteriaTextField.font = [UIFont systemFontOfSize:13];
[self.view addSubview:criteriaTextField];
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = criteriaTextField.frame;
[button addTarget:self action:#selector(launchCriteriaPicker) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
caseStudyTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, [criteriaTextField bottom]+5, 320, self.view.frame.size.height )];
if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0")){
[caseStudyTableView setSeparatorInset:UIEdgeInsetsZero];
}
caseStudyTableView.delegate = self;
caseStudyTableView.dataSource = self;
caseStudyTableView.rowHeight = 40;
caseStudyHeaderView.backgroundColor = [UIColor clearColor];
[self.view addSubview:caseStudyTableView];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
[ cell.textLabel setFont:[UIFont boldSystemFontOfSize:13]];
[ cell.textLabel setTextAlignment:NSTextAlignmentLeft];
cell.textLabel.numberOfLines=0;
[ cell.textLabel setTextColor:[UIColor blackColor]];
cell.textLabel.backgroundColor = UIColorFromRGB(0xc8f898);
cell.contentView.backgroundColor = UIColorFromRGB(0xc8f898);
NSLog(#"%#",criteriaNameArray);
cell.textLabel.text = [criteriaNameArray objectAtIndex:indexPath.row];
return cell;
}
how to change table value in IOS.
Use the UITextField Delegate method :
- (void)textFieldDidEndEditing:(UITextField *)textField{
// [criteriaNameArray replaceObjectAtIndex:atIndexToReplace withObject:textField.text];
[self.tableView reloadData]; // Handle the DataSource accordingly in the cellForRowAtIndexPath
}
Try [tableView reloadData]; in pickerview didselect method.
//in view did load listen for text changed notification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(textFieldChanged:)
name:UITextFieldTextDidChangeNotification
object:yourTextField]
//Reload the table view Whenever the text field changes the text
-(void)textFieldChanged:(id)sender{
[yourTableView reloadData];
}

Objective-c custom table cell buttons

I'm trying to implement a table view where all rows have 2 buttons which then do something with the data at the index row they are on.
here is what I have so far:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"NotificationCell";
NotificationCell *cell = (NotificationCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[NotificationCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NotificationObject *notification = nil;
notification = [_notificationArray objectAtIndex:indexPath.row];
cell.profileImage.image = notification.profileImage;
cell.profileImage.layer.cornerRadius = cell.profileImage.frame.size.height /2;
cell.profileImage.layer.masksToBounds = YES;
cell.profileImage.layer.borderWidth = 0;
cell.detailTextView.text = notification.action;
UIButton *denyButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
UIButton *acceptButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//set the position of the button
denyButton.frame = CGRectMake(cell.frame.origin.x + 285, cell.frame.origin.y + 20, 23, 23);
[denyButton setBackgroundImage:[UIImage imageNamed:#"DenyRequest.png"] forState:UIControlStateNormal];
[denyButton addTarget:self action:#selector(denyButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
denyButton.backgroundColor= [UIColor clearColor];
[cell.contentView addSubview:denyButton];
acceptButton.frame = CGRectMake(cell.frame.origin.x + 240, cell.frame.origin.y + 20, 23, 23);
[acceptButton setBackgroundImage:[UIImage imageNamed:#"AcceptRequest.png"] forState:UIControlStateNormal];
[acceptButton addTarget:self action:#selector(AcceptButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
acceptButton.backgroundColor= [UIColor clearColor];
[cell.contentView addSubview:acceptButton];
return cell;
}
-(void)denyButtonPressed:(id)sender{
NSLog(#"buttonPressedDeny");
}
-(void)AcceptButtonPressed:(id)sender{
NSLog(#"buttonPressedAccept");
}
However I am not sure how to find out which index row the selected button was pressed so that I can get the relevant data.
The simplest solution is to assign a tag to each button. For example:
denyButton.tag = 1000 + indexPath.row;
Then on denyButtonPressed:
-(void)denyButtonPressed:(id)sender{
UIButton *b = (UIButton *)sender;
NSInteger row = b.tag - 1000;
NSLog(#"buttonPressedDeny: %d", row);
}
The variable row will hold the index path row where the button was pressed. The addition of 1000 is to avoid collision with other views you may already have.
Let me emphasize that this is the SIMPLEST solution but not the most friendly from a design/architecture point of view.
A more elaborate solution could be to have the buttons as part of NotificationCell, have NotificationCell be the delegate for those buttons, and create a protocol that allows your view controller to be the delegate of each NotificationCell. Then when the button is pressed, it will be handled by NotificationCell, which will pass whatever object is needed to your view controller.
For example, create the following protocol in NotificationCell.h
#protocol NotificationCellDelegate
- (void)denyActionForNotificationObject:(NotificationObject *)notificationObject;
- (void)acceptActionForNotificationObject:(NotificationObject *)notificationObject;
#end
Also add NotificationCell add a property to hold a notification and a delegate:
#property (nonatomic, strong) NotificationObject *notificationObject;
#property (nonatomic, strong) id<NotificationCellDelegate> delegate;
Create a method awakeFromNib (if you are using storyboards)
- (void)awakeFromNib {
[super awakeFromNib];
UIButton *denyButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
UIButton *acceptButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//set the position of the button
denyButton.frame = CGRectMake(self.contentView.frame.origin.x + 285, self.contentView.frame.origin.y + 20, 23, 23);
[denyButton setBackgroundImage:[UIImage imageNamed:#"DenyRequest.png"] forState:UIControlStateNormal];
[denyButton addTarget:self action:#selector(denyButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
denyButton.backgroundColor= [UIColor clearColor];
[self.contentView addSubview:denyButton];
acceptButton.frame = CGRectMake(self.contentView.frame.origin.x + 240, self.contentView.frame.origin.y + 20, 23, 23);
[acceptButton setBackgroundImage:[UIImage imageNamed:#"AcceptRequest.png"] forState:UIControlStateNormal];
[acceptButton addTarget:self action:#selector(AcceptButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
acceptButton.backgroundColor= [UIColor clearColor];
[cell.contentView addSubview:acceptButton];
}
Implement the selectors you declared:
- (void)denyButtonPressed:(id)sender {
if (_delegate) {
[_delegate denyActionForNotificationObject:_notificationObject];
}
}
- (void)AcceptButtonPressed:(id)sender {
if (_delegate) {
[_delegate acceptActionForNotificationObject:_notificationObject];
}
}
Then in your cellForRowAtIndexPath in your view controller add:
cell.notificationObject = notificationObject;
cell.delegate = self;
Also in your view controller, implement the protocol:
- (void)denyActionForNotificationObject:(NotificationObject *)notificationObject {
// Do something with the notification object
}
- (void)acceptActionForNotificationObject:(NotificationObject *)notificationObject {
// Do something with the notification object
}
I have not tested this in XCode, my apologies if it doesn't compile
Why not work backwards through the view hierarchy and check the button's superview, which should be the content view of the table view cell. Whose superview should be the cell?
-(void)denyButtonPressed:(id)sender{
UIButton *button = (UIButton *)sender;
UIView *contentView = button.superview;
UITableViewCell *cell = contentView.superview;
NSIndexPath * indexPath = self.tableView indexPathForCell:cell];
NSLog(#"row containing button: %d", indexPath.row);
}

UITableViewCell using QuickDialog : handle touch event on all the cell's surface

I use custom cell on UITableView using QuickDialog
In this custom cell I have several UILabel, UIImageView and a button which has the cell size and display on the top of the others subviews.
I want this button handle touch envent and call a selector. But even though the button is at the top position, the touch event does not trigger when I touch a subview.
- (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller
{
UITableViewCell *cell = [super getCellForTableView:tableView controller:controller];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = cell.frame;
[btn setEnabled:YES];
[btn setExclusiveTouch:YES];
[btn setBackgroundColor:[UIColor blueColor]]; // To check if the button is at the top position
[btn setStringTag:labelIdText];
[btn addTarget:self action:#selector(handleTap:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:label1];
[cell addSubview:label2];
[cell addSubview:image1];
[cell addSubview:image2];
[cell addSubview:btn];
cell.userInteractionEnabled = YES;
return cell;
}
The selector :
- (IBAction)handleTap:(id)sender
{
NSLog(#"CELL TAPPED : \n");
}
Thanks a lot.
EDIT :
New version of the code :
- (UITableViewCell *)getCellForTableView:(QuickDialogTableView *)tableView controller:(QuickDialogController *)controller
{
UITableViewCell *cell = [super getCellForTableView:tableView controller:controller];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIView *top = [[UIView alloc] initWithFrame:CGRectMake(0, 0, cell.frame.size.width, cell.frame.size.height)];
UITapGestureRecognizer *singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
[top setStringTag:labelIdText];
[top addGestureRecognizer:singleFingerTap];
[cell.contentView addSubview:label_1];
[cell.contentView addSubview:label_2];
[cell.contentView addSubview:image_1];
[cell.contentView addSubview:image_2];
[cell.contentView addSubview:top];
cell.userInteractionEnabled = YES;
image_1.userInteractionEnabled = YES;
image_2.userInteractionEnabled = YES;
return cell;
}
The selector :
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
NSLog(#"CELL TAPPED : \n");
}
The event is handle when I touch the text containing in the UILabel.
But it's still don't work with the UIImageView despite userInteractionEnabled setted to YES for the images.
Thanks again.
It seams you are assigning to the button the cell frame and then add it to the cell itself. In this way the position of the button is not the one you expect, and even though you can see the button it will not respond to touch because it resides outside the cell bounds.
Try to change this:
btn.frame = cell.frame;
to this:
btn.frame = cell.bounds;
Also when working with UItableViewCell remember to add subviews to its contentView and not the cell itself:
[cell.contentView addSubview:aCustomView];

Resources