UITableViewCell subclass: Delete and reorder button not showing - ios

I am using a UITableViewCell subclass in a highly customized UITableView. Now I want to implement a edit button. So I implemented a button, an action, setting the UITableview to editing:YES and so on. The problem is that my cells do not show the delete or move buttons or handlers. Do I need to implement something in my subclass for this?
Bests,
Philip

do like this complete implementation of edit and delete buttons in tableview, customize according to your requirement
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"Referrral RemainderCC";
referrralRemainderCC *cell = (referrralRemainderCC *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
UIViewController *c = [[UIViewController alloc] initWithNibName:#"referrralRemainderCC" bundle:nil];
cell = (referrralRemainderCC *) c.view;
}
if (dataArray.count==0) {
return 0;
}
else
{
referralDC *referral =[dataArray objectAtIndex:indexPath.row];
cell.lblDate.text = referral.referralDC_Date;
cell.lblCompanyName.text = referral.referralDC_CompanyName;
cell.lblEmail.text = referral.referralDC_EmailTelephone;
cell.lblFellowUpDate.text = referral.referralDC_FellowUpDate;
cell.lblReferralRequest.text =referral.referralDC_ReferralRequest;
cell.lblName.text = referral.referralDC_Name;
cell.edit.tag = indexPath.row;
cell.delete.tag = indexPath.row;
[cell.edit addTarget:self action:#selector(btnTapped:withEvent:) forControlEvents:UIControlEventTouchUpInside];
[cell.delete addTarget:self action:#selector(btnTapped:withEvents:) forControlEvents:UIControlEventTouchUpInside];
}
return cell;
}
- (void)btnTapped:(id)sender withEvent:(UIEvent*)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:self.tblView];
NSIndexPath *indexPath = [self.tblView indexPathForRowAtPoint:location];
referralDC *referral =[dataArray objectAtIndex:indexPath.row];
referalID = referral.referralDC_ReferralID;
txtDate.text = referral.referralDC_Date;
txtCompanyName.text = referral.referralDC_CompanyName;
txtEmail.text = referral.referralDC_EmailTelephone;
txtFolowUpDate.text = referral.referralDC_FellowUpDate;
txtviewReferralRequest.text =referral.referralDC_ReferralRequest;
txtName.text = referral.referralDC_Name;
btnEditPressed=1;
}

Related

How to identify the row index and section number of a clicked button in a custom cell inside tableview

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = #"CustomCell";
cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner: self options: nil ];
cell = [nib objectAtIndex:0];
}
//cell.lblName.text = [items objectAtIndex:indexPath.row];
NSMutableDictionary *dic = [items objectAtIndex:indexPath.row];
cell.imgface.image = [dic objectForKey:#"Image"];
cell.imgface.layer.cornerRadius = cell.imgface.frame.size.width / 2;
cell.imgface.layer.borderWidth = 3.0f;
cell.imgface.layer.borderColor = [UIColor whiteColor].CGColor;
cell.imgface.clipsToBounds = YES;
cell.lblName.text = [dic objectForKey:#"Name"];
[cell.btnPhone setTitle:[dic objectForKey:#"Phone"] forState:(UIControlStateNormal)];
cell.btnPhone.tag = indexPath.row;
cell.btnstar.tag = indexPath.row;
[cell.btnPhone addTarget:self action:#selector(dial:) forControlEvents:(UIControlEventTouchUpInside)];
[cell.btnstar addTarget:self action:#selector(toggleimage:) forControlEvents:UIControlEventTouchUpInside];
if (indexPath.section == 0)
{
star = [UIImage imageNamed:#"Star-Favorites.png"];
[cell.btnstar setBackgroundImage:star forState:UIControlStateNormal];
}
else
{
star = [UIImage imageNamed:#"keditbookmarks.png"];
[cell.btnstar setBackgroundImage:star forState:UIControlStateNormal];
}
return cell;
}
write below code in button IBAction and you will get indexpath.row and indexpath.section
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
NSLog(#"selected tableview row is %d",indexPath.row);
You have some different ways to do that:
• When you configure the cell set the tag of the cell or the button as the row and retrieve that on the IBAction (I hate tags though)
• Define a delegate for the table cell and set it when you configure it. Then call the delegate method passing the cell and find the relative index (-indexPathForCell:)
• The same as before but pass the cell through a notification instead of delegates
first of all on, button IBAction call this method
- (IBAction)btnClick:(UIButton)sender
{
UITableViewCell *cellOfcontrol=[self cellWithSubview:sender];
NSIndexPath *indexPath = [self.tableview indexPathForCell:cellOfcontrol];
}
cellWithSubview function
- (UITableViewCell *)cellWithSubview:(UIView *)subview
{
while (subview && ![subview isKindOfClass:[UITableViewCell self]])
subview = subview.superview;
return (UITableViewCell *)subview;
}

How to use swipe to change the label of specific row in tableview

In ViewDidLoad of table view controller, I first added SwipeGuesture and handler "Swipecell"
UISwipeGestureRecognizer *showExtrasSwipe = [[UISwipeGestureRecognizer alloc]
initWithTarget:self action:#selector(Swipecell:)];
showExtrasSwipe.direction = UISwipeGestureRecognizerDirectionRight|
UISwipeGestureRecognizerDirectionLeft;
[self.tableView addGestureRecognizer:showExtrasSwipe];
//Here I define the handler:
-(void)Swipecell:(UISwipeGestureRecognizer *)gesture
{
//Taking gesture location
CGPoint location = [gesture locationInView:_tableview];
//Getting IndexPath for that location in tableview
NSIndexPath *swipedIndexPath = [self.tableView indexPathForRowAtPoint:location];
UITableViewCell *swipedCell = [self.tableView cellForRowAtIndexPath:swipedIndexPath];
NSString *data = [self.dataArray objectAtIndex:swipedIndexPath.row];
//Setting the label of the cell
[swipedCell.textLabel setText:data];
}
But it is working only for one first row. Can anybody help me in this or give me better solution? Don't forget to rate, if you like the question.
Please add the swipe gesture in cellForRowAtIndexPath method , so the gesture will be added to each cell.
It works... Tested on iOS 7.1 simulator
- (void)viewDidLoad
{
_tableview = (UITableView*)self.view;
[super viewDidLoad];
UISwipeGestureRecognizer *showExtrasSwipe = [[UISwipeGestureRecognizer alloc]
initWithTarget:self action:#selector(Swipecell:)];
showExtrasSwipe.direction = UISwipeGestureRecognizerDirectionRight|
UISwipeGestureRecognizerDirectionLeft;
[self.tableView addGestureRecognizer:showExtrasSwipe];
}
-(void)Swipecell:(UISwipeGestureRecognizer *)gesture
{
CGPoint location = [gesture locationInView:_tableview];
NSIndexPath *swipedIndexPath = [self.tableView indexPathForRowAtPoint:location];
UITableViewCell *swipedCell = [self.tableView cellForRowAtIndexPath:swipedIndexPath];
swipedCell.detailTextLabel.text = [NSString stringWithFormat:#"%i", swipedIndexPath.row];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 55;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
cell.textLabel.text = [NSString stringWithFormat:#"%i", indexPath.row];
cell.detailTextLabel.text = #" ";
return cell;
}
Change [gesture locationInView:_tableview] to [gesture locationInView:self.tableview]. I was refering to tableView outlet.

Button in custom cell in dynamic table: how to know which row in action method? [duplicate]

This question already has answers here:
Select UITableView's row when clicking on UISwitch
(7 answers)
Closed 8 years ago.
I have a table of dynamic content. In the prototype cell I have a button. In that button's action method, how do I then determine which row's button was pressed?
(I know that, for example, in a segue method one can determine which row has been pressed by querying the selected path of the table view, but in this case, no row has actually been selected.)
There are of course ways of doing this using tags, or storing an indexPath in your cell etc.
I prefer to use something similar to the following, which I think is cleaner than the above. You could add this to a category UITableViewController.
- (NSIndexPath *)indexPathForCellSubview:(UIView *)subview
{
if (subview) {
UITableViewCell *cell = [self tableViewCellForCellSubview:subview];
return [self.tableView indexPathForCell:cell];
}
return nil;
}
- (UITableViewCell *)tableViewCellForCellSubview:(UIView *)subview
{
if (subview) {
UIView *superView = subview.superview;
while (true) {
if (superView) {
if ([superView isKindOfClass:[UITableViewCell class]]) {
return (UITableViewCell *)superView;
}
superView = [superView superview];
} else {
return nil;
}
}
} else {
return nil;
}
}
Edit with suggestion from #staticVoidMan:
More concise implementation:
- (UITableViewCell *)tableViewCellForCellSubview:(UIView *)subview
{
UIView *checkSuperview = subview.superview;
while (checkSuperview) {
if ([checkSuperview isKindOfClass:[UITableViewCell class]]) {
break;
} else {
checkSuperview = checkSuperview.superview;
}
}
return (UITableViewCell *)checkSuperview;
}
Best approach:
-(void)buttonMethod:(UIButton *)sender event:(UIEvent *)event
{
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint pointCurrent = [touch locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForItemAtPoint:pointCurrent];
//...
}
PS: Provided you have done something like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//...
[cell.someButton addTarget:self
action:#selector(buttonMethod:event:)
forControlEvents:UIControlEventTouchUpInside];
//...
}
You could use tags, associated objects, or superview trickery.
Here's a question that has all three answers.
Tags
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"MySpecialCell";
MySpecialCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[MySpecialCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.mySpecialTextView.delegate = self;
}
cell.mySpecialTextView.tag = indexPath.row;
return cell;
}
- (void)textViewDidChange:(UITextView *)textView
int rowOfTextViewThatJustChanged = textView.tag;
}
Associated Objects
static NSString *const kIndexPathKey = #"indexPathKey";
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"MultiSelectCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
UISwitch *switchView = [[UISwitch alloc] init];
[switchView addTarget:self action:#selector(switchValueChanged:) forControlEvents:UIControlEventValueChanged];
cell.accessoryView = switchView;
}
UISwitch *switchView = (id)cell.accessoryView;
[self setIndexPath:indexPath onSwitch:switchView];
switchView.on = [self isIndexPathSelected:indexPath];
id item = [self itemAtIndexPath:indexPath];
cell.textLabel.text = safePerformSelector(item, self.itemDescriptionSelector);
return cell;
}
- (void)switchValueChanged:(UISwitch *)sender {
NSIndexPath *indexPath = [self indexPathOfSwitch:sender];
[self setRowSelected:sender.isOn atIndexPath:indexPath];
[self.delegate didSelectItem:[self itemAtIndexPath:indexPath] atIndexPath:indexPath selected:sender.isOn sender:self];
}
- (void)setIndexPath:(NSIndexPath *)indexPath onSwitch:(UISwitch *)switchView {
[switchView setAssociatedObject:indexPath forKey:kIndexPathKey];
}
- (NSIndexPath *)indexPathOfSwitch:(UISwitch *)switchView {
return [switchView associatedObjectForKey:kIndexPathKey];
}
#implementation NSObject (AssociatedObjects)
- (void)setAssociatedObject:(id)object forKey:(NSString *const)key {
objc_setAssociatedObject(self, (__bridge const void *)(key), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (id)associatedObjectForKey:(NSString *const)key {
return objc_getAssociatedObject(self, (__bridge const void *)(key));
}
#end

Dynamically add objects to UITableView cell

![enter image description here][2]I have a table view,in which I am using my custom cell that contains user's profile picture,status label, time stamp label, username label, no of comments label and a comment button.
When no of comments i.e"4 comments" is tapped, I ha ve to show comments in the corresponding cell along with username, user profile picture etc below the original post.
How do I dynamically add these objects into cell when the app is running? or there is some else solution please tell. table for 2 posts is shown in right of image. Tapping no of comments left of the image should be shown.
Here is the code for table cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"MyCell";
TableCell *cell = (TableCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray* topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"TableCell" owner:self options:nil];
for (id currentObject in topLevelObjects) {
if ([currentObject isKindOfClass:[UITableViewCell class]]) {
cell = (TableCell *)currentObject;
break;
}
}
}
// Configure the cell.
User *user = [postTableData objectAtIndex:indexPath.row];
NSLog(#"pic:%#",user.profilePictureURL);
cell.profilePicture.image = [UIImage imageNamed:#"avatar.png"];
cell.profilePicture.layer.cornerRadius = cell.profilePicture.frame.size.height /2;
cell.profilePicture.layer.masksToBounds = YES;
cell.profilePicture.layer.borderWidth = 0;
cell.userName.text = user.name;
cell.status.text = user.status;
cell.dateForStatus.text = user.datePosted;
[cell.countComments setTitle:user.countOfComments forState:UIControlStateNormal];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
[cell.contentView.layer setBorderWidth:6.0f];
[cell.contentView.layer setBorderColor:[[UIColor alloc] initWithRed:233/255.0 green:236/255.0 blue:233/255.0 alpha:1.0].CGColor];
cell.commentButton.tag=indexPath.row;
[cell.commentButton addTarget:self action:#selector(commentButtonPressAction:) forControlEvents:UIControlEventTouchUpInside];
return cell;
![enter image description here][3]}
I guess you are trying to expand the cell.
You can call these few lines to update the cell, including the height.
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView endUpdates];
So just set a flag to show comments in cellForRowAtIndexPath.
//AFTER_YOUR_SETTING
if(showComment){
[cell loadCommentMethod];
}
And also, in heightForRowAtIndexPath
if(showComment){
return [CellClass publicMethodForCalHeight:dataAtIndexPath];
} else {
return kDefaultCellHeight;
}
Change your button action method:
- (void)onButtonTaped:(id)sender
{
UIButton *button = sender;
UILabel *newLabel = [ [ UILabel alloc] initWithFrame:CGRectMake (0, 100, 200, 50)];
newLabel.text = #"Your new text here";
[button.superview addSubview:newLabel];
}
But label will be visible only until cell will be visible on screen. When cell will be recreated label will be deleted. To keep label you still need to change
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
I'm not sure if it works but you can try this. Override touchesBegan: on your cell:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self];
CGRect rect = [noComments frame];
if (CGRectContainsPoint(rect, point))
{
UILabel *label = ... // the label you need to add.
[self addSubview:label];
}
}
You can make use of the method insertRowsAtIndexPaths:withRowAnimation: of the UITableView. You can refer this link for a tutorial. Also refer the Apple docs

Hide a label of a cell in a table view in iOS

I want to hide a label of a cell in a tableview.
(void)handleSwipeRight:(UISwipeGestureRecognizer *)gestureRecognizer
{
//Get location of the swipe
CGPoint location = [gestureRecognizer locationInView:self.tableView];
//Get the corresponding index path within the table view
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
//Check if index path is valid
if(indexPath)
{
//Get the cell out of the table view
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
//Update the cell or model
displayLabel.hidden = TRUE;
[cell setNeedsDisplay];
}
}
This code is hiding the label in the last cell as I failed to specify the code to hide the swiped cell's label.
Help to specify the swiped cell label to hide.
displayLabel.hidden = TRUE;
I need a replacement for this code.
You can try below code its working perfectly on my side:
- (void)viewDidLoad
{
UISwipeGestureRecognizer *recog = [[UISwipeGestureRecognizer alloc]initWithTarget:self
action:#selector(handleSwipeRight:)];
recog.delegate = self;
[recog setDirection:UISwipeGestureRecognizerDirectionRight];
[testTable addGestureRecognizer:recog];
// add the swipe gesture recognizer to tableview;
[super viewDidLoad];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 7;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
UILabel *aLabel = [[[UILabel alloc]init]autorelease];
aLabel.frame = CGRectMake(5, 0, 100, 40);
aLabel.text = [NSString stringWithFormat:#"aLabel %d",indexPath.row+1];
aLabel.tag = 1;//tag the labels
[cell.contentView addSubview:aLabel];
UILabel *bLabel = [[[UILabel alloc]init]autorelease];
bLabel.frame = CGRectMake(110, 0, 100, 40);
bLabel.text = [NSString stringWithFormat:#"bLabel %d",indexPath.row+1];
bLabel.tag = 2;//tag the label
[cell.contentView addSubview:bLabel];
UILabel *cLabel = [[[UILabel alloc]init]autorelease];
cLabel.frame = CGRectMake(215, 0, 100, 40);
cLabel.text = [NSString stringWithFormat:#"cLabel %d",indexPath.row+1];
cLabel.tag = 3;//tag the label
[cell.contentView addSubview:cLabel];
}
return cell;
}
-(void)handleSwipeRight:(UISwipeGestureRecognizer *)gestureRecognizer
{
//Get location of the swipe
CGPoint location = [gestureRecognizer locationInView:testTable];
//Get the corresponding index path within the table view
NSIndexPath *indexPath = [testTable indexPathForRowAtPoint:location];
//Check if index path is valid
if(indexPath)
{
//Get the cell out of the table view
UITableViewCell *cell = [testTable cellForRowAtIndexPath:indexPath];
for (id label in cell.contentView.subviews)
{
if ([label isMemberOfClass:[UILabel class]])
{
UILabel *referedLabel = (UILabel*)label;
if (referedLabel.tag == 2) //tag of bLabel;
{
referedLabel.hidden = YES;
}
}
}
}
}
I think displayLabel is pointing to label in last cell of your table. Where you are setting value to displayLabel.
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
//Update the cell or model
//You should get label from cell here. Currently displayLabel may be pointing to label in last cell, if I am correct you are assigning value to displaylabel in cellForRowAtIndexPath or in any other method.
displayLabel.hidden = TRUE;
[cell setNeedsDisplay];
Change your method to this:
-(void)handleSwipeRight:(UISwipeGestureRecognizer *)gestureRecognizer
{
//Get location of the swipe
CGPoint location = [gestureRecognizer locationInView:self.tableView];
//Get the corresponding index path within the table view
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
//Check if index path is valid
if(indexPath)
{
// If you created a custom cell with a
// displayLabel property, change the pointer
// type from UITableViewCell to that type
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.displayLabel.hidden = YES;
// Use the following three lines instead, if your cell style is "Subtitle"
// cell.textLabel.hidden = YES;
// cell.imageView.hidden = YES;
// cell.detailTextLabel.hidden = YES;
[cell setNeedsDisplay];
}
}

Resources