How to get indexPath in a tableview from a button action in a cell? - xcode

I have a tableview with two actions in it, for the first on i use the delegate didSelectRowAtIndexPath, for the second one i would like to use an action on a button on my cell to do something else. My problem is that i don't succeed to get the indexpath ? What is the best practice to do that.

If you have added the button to the cell as,
[cell.contentView addSubview:button];
then, you can get the index path as,
- (void)onButtonTapped:(UIButton *)button {
UITableViewCell *cell = (UITableViewCell *)button.superview.superview;
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
// Go ahead
}

I'm using this solution -- getting index path of cell using points
CGPoint center= [sender center];
CGPoint rootViewPoint = [[sender superview] convertPoint:center toView:_tableView1];
NSIndexPath *indexPath = [_tableView1 indexPathForRowAtPoint:rootViewPoint];
NSLog(#"%#",indexPath);
Its work perfectly

here is the full code for a custom button:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
CustomCellFilter *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {cell = [[CustomCellFilter alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];}
//configure your cell here
cell.titleLabel.text = #"some title";
//add button
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
resetButton.frame = CGRectMake(40, 10, 18, 18);
[resetButton addTarget:self action:#selector(onButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[resetButton setImage:[UIImage imageNamed:#"someimage.png"] forState:UIControlStateNormal];
[cell.contentView addSubview:myButton];
//afterwards return the cell
return cell;
- (void)onButtonTapped:(UIButton *)button {
UITableViewCell *cell = (UITableViewCell *)button.superview.superview;
NSIndexPath *indexPath = [filterTable indexPathForCell:cell];
NSLog(#"%#", indexPath);
//use indexPath here...
}

In case you are using a collection view, you can use Yogesh method, but change indexPathForRowAtPoint for indexPathForItemAtPoint like this:
CGPoint center= [sender center];
CGPoint rootViewPoint = [[sender superview] convertPoint:center toView:_tableView1];
NSIndexPath *indexPath = [_tableView1 indexPathForRowAtPoint:rootViewPoint];
NSLog(#"%#",indexPath);

In case that your button is moved or Apple changes the view hierarchy for accessory views, this method goes up the chain to look for a UITableViewCell:
- (void)tapAccessoryButton:(UIButton *)sender {
UIView *parentView = sender.superview;
// the loop should take care of any changes in the view heirarchy, whether from
// changes we make or apple makes.
while (![parentView.class isSubclassOfClass:UITableViewCell.class])
parentView = parentView.superview;
if ([parentView.class isSubclassOfClass:UITableViewCell.class]) {
UITableViewCell *cell = (UITableViewCell *) parentView;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
[self tableView:self.tableView accessoryButtonTappedForRowWithIndexPath:indexPath];
}
}

Related

How to push new view from TableViewCell?

In my app I am trying to navigate to a new View from a TableViewCell, But i dont know how. Could you help guys? I am using Xcode 4.6. and .xib, no storyboard. I am very new to coding so please explain it as simple as possible! Here is what i have tried, please correct me:
- (void)viewDidLoad
{
tableData = [[NSArray alloc] initWithObjects:#"aaoversikt1", #"Paul", #"George", #"Ringo", nil];
[super viewDidLoad];
UILabel *nav_title1 = [[UILabel alloc] initWithFrame:CGRectMake(60, 10, 220, 25)];
nav_title1.font = [UIFont fontWithName:#"Arial-BoldMT" size:18];
nav_title1.textColor = [UIColor whiteColor];
nav_title1.adjustsFontSizeToFitWidth = NO;
nav_title1.textAlignment = NSTextAlignmentCenter;
nav_title1.text = #"Ă…lesund";
nav_title1.backgroundColor = [UIColor clearColor];
self.navigationItem.titleView = nav_title1;
}
#pragma mark - TableView Data Source methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section;
{
return [tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *cell = nil;
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
#pragma mark - TableView Delegate methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
AAOversiktViewController *aaoversikt1 = [[AAOversiktViewController alloc] initWithNibName:#"AAOversiktViewController" bundle:nil];
[self.navigationController pushViewController:aaoversikt1 animated:YES];
}
Thank You!
From first glance I would say that the problem lies within your [self.navigationController pushViewController] method. Have you initiated a navigation controller in your app either in the app delegate or root view controller?
If not i would recommend:
[self presentViewController:aaoversik1 animated:YES completion:NULL];
If you are wanting to push through the navigation stack so that you have a back button then I would look at implementing a UINaviationController.
Otherwise you can create a custom back button and use the same method in this post to present the root view controller (not totally recomended as using UINavigationController is much cleaner).
Let me know if this has been of any help, T

Xcode didSelectRowAtIndexPath on tableview not called

I have been looking until 6 o'clock this morning, but I can't figure out why the didSelectRowAtIndexPath method is not being called. I am getting quite desparate on this one.
The tableview is shown properly, but I cannot succeed to enable the selection of a cell.
In the header file , I added:
#interface AlertsTable : UIViewController<UITableViewDelegate, UITableViewDataSource, CMPopTipViewDelegate>{
UITableView *TableView;
}
#property (nonatomic, retain) UITableView *TableView;
In the implementation file:
#synthesize TableView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
//Set the title
//Format Alerts table
//self.view.backgroundColor = [UIColor redColor];
CGFloat sideMargin = 10;
CGFloat topBottomMargin = 44;
CGFloat originX = sideMargin;
// compute width based on view size
CGFloat sizeWidth = (self.view.bounds.size.width - (sideMargin * 2));
CGFloat originY = topBottomMargin;
// compute height based on view size
CGFloat sizeHeight = (self.view.bounds.size.height - (topBottomMargin * 2));
//self.view.frame = CGRectMake(originX, originY, sizeWidth, sizeHeight);
self.TableView = [[UITableView alloc] initWithFrame:CGRectMake(originX, originY, sizeWidth, sizeHeight) style:UITableViewStylePlain];
//Initialize the array.
AlertsItems = [[NSMutableArray alloc] initWithObjects: #"Alert 1", #"Alert 2", #"Alert 3" , #"Alert 4", #"Alert 5", #"Alert 6", nil];
[self.TableView setDelegate:self];
[self.TableView setDataSource:self];
[self.view addSubview:TableView];
TableView.userInteractionEnabled = YES;
TableView.allowsSelection = YES;
TableView.allowsSelectionDuringEditing = YES;
NSLog(#"delegate:%# dataSource:%#", self.TableView.delegate, self.TableView.dataSource);
}
The delegate and datasource are both not nil on the check.
Note that the "Alertstable" inherits from a UIViewController, not a UITableViewController.
This is necessary due to the implementation I chose: the tableview is shown on a popupwindow shown on the screen (using another class that I took from the internet).
This is the didSelectRowAtIndexPath method:
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *alertString = [NSString stringWithFormat:#"Clicked on row #%d", [indexPath row]];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:alertString message:#"" delegate:self cancelButtonTitle:#"Done" otherButtonTitles:nil];
[alert show];
}
The methods:
[super touchesBegan:...];
[super touchesEnded:...];
[super touchesMoved:...];
are not implemented.
I added the AlertTable from another ViewController
AlertsTable *AlertTable = [[AlertsTable alloc] WithButton:sender withArray:self.PopTipViews];
[self.view addSubview:AlertTable.view];
I also implemented:
- (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];
}
// Set up the cell...
[[cell textLabel] setText:[AlertsItems objectAtIndex:indexPath.row]];
NSLog (#"%#",[AlertsItems objectAtIndex:indexPath.row]);
return cell;
}
Do you have any idea what the problem could be?
I'm not very experienced in Xcode and I'm really stuck.
Edit:
I know that it is not custom, but the link to the project can be found here (perhaps I'm overlooking something:
https://www.bilbu.be/BarConnect_v2.zip
The LoginViewController.xib is not properly linked (it is available in the en.lproj subfolder) so you may need to link first (I noticed too late and I had the file uploaded by a friend before - I cannot re-upload it myself unfortunately).
ViewController VC class calls the AlertsTable VC class. There is more in the project that I suppose you can ignore...
Note that the purpose of this project is only to serve as visual interface prototype. It is not meant to be the best optimized application (this is what other developers will do). If this doesn't work, I will use Photoshop to create the interfaces, but I guess that's not gonna be as convincing...
I successfully compiled your project. The problem is that you're going against the MVC pattern. The controller (AlertsTable) is inside of a view (CMPopTipView). I'd suggest you to rethink the hierarchy of the controllers and views. Hope this will help you.
Try changing
TableView.userInteractionEnabled = YES;
TableView.allowsSelection = YES;
TableView.allowsSelectionDuringEditing = YES;
to
self.TableView.userInteractionEnabled = YES;
self.TableView.allowsSelection = YES;
self.TableView.allowsSelectionDuringEditing = YES;
and are you allocating self.TableView? Something like...
self.TableView = [[UITableView alloc] init];//[[UITableView alloc] initWithStyle:UITableViewStylePlain];

Xcode: Why does my UITextField act slow in my UITableViewCell?

I have an app where I load a UIViewController with an UITableView. In the UITableViewCells I have a UITextField. Which I have added in the cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
if ([indexPath section] == 0) {
// Setting the cell textLabel.
[[cell textLabel] setText:[Customize objectAtIndex:indexPath.row]];
if ([indexPath row] == 0) { // Text
// Adding and customizing UITextField.
TextFieldText = [[UITextField alloc] initWithFrame:CGRectMake(160, 10, 140, 30)];
TextFieldText.placeholder = #"Random";
TextFieldText.autocorrectionType = UITextAutocorrectionTypeNo;
TextFieldText.autocapitalizationType = UITextAutocapitalizationTypeNone;
TextFieldText.returnKeyType = UIReturnKeyDone;
[cell addSubview:TextFieldText];
and so on.
The problem is that when you type in it, it is a little slow. When a letter/symbol is typed it appears in the UITextField and for a very short second the marker is still on the left side of the letter/symbol and slide across the letter/symbol. The keyboard also appears kind of slow.
Any thoughts?
Thanks in advance :)

How to change it back from activity indicator to disclosure in UITableViewCell after pushViewController

How to change it back from activity indicator to disclosure ??
the problem is:
When i didSelectRow, i made disclosure to activity indicator because it will load some picture for the next view controller and It's worked, but i dont have any luck to change it back to disclosure after pushViewController. i already tried to reload the table from the 2ndViewController but it's crashed.
So anybody have a solution for this problem..
Thanks in advance
This is my code in didSelectRow :
-(void)threadStartAnimating:(id)data
{
[activityView startAnimating];
[self.navigationController pushViewController:bdvController animated:YES];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[cell setAccessoryView:activityView];
[NSThread detachNewThreadSelector:#selector(threadStartAnimating:) toTarget:self withObject:nil];
// Navigation logic -- create and push a new view controller
if(bdvController == nil)
bdvController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:[NSBundle mainBundle]];
AppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
bdvController.appsRecord = appRecord;
bdvController.HeaderText.text = appRecord.appName;
bdvController.title = appRecord.artist;
[bdvController.tableView reloadData];
}
The best way is to set pointer nil to the accessoryView, example:
cell.accessoryView = nil;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
cell.selectionStyle = UITableViewCellSelectionStyleGray;
In my code these operations work fine.

xcode uitableview cell image align

I'm sure this is very simple but i can't find any documentation about it..
in my uitableview i have the text labels aligned to the right (my app is in heberw which is rtl)
i'm trying to add an image to the cell to the RIGHT of the text label, no luck, so far the image is aligned to the left and i can't find a way to align it to the right side of the cell.
here's my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
cell.imageView.image = [UIImage imageNamed:#"tableicon.png"];
NSString *cellValue = [[stories objectAtIndex:indexPath.row] objectForKey:#"ArticleTitle"];
cell.textLabel.text = cellValue;
cell.textLabel.textAlignment = UITextAlignmentRight;
cell.textLabel.font = [UIFont systemFontOfSize:17];
cell.textLabel.numberOfLines = 2;
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 50;
}
Instead of adding the image as a subview of your UITableViewCell, add a container with right aligned subviews.
UIImageView *pic = myImageView;
UIView *picContainer = [[UIView alloc] initWithFrame:cell.frame];
picContainer.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
picContainer.contentMode = UIViewContentModeRight;
pic.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
pic.center = CGPointMake(picContainer.frame.size.width-70, picContainer.frame.size.height/2);
[picContainer addSubview:pic];
[cell.contentView addSubview:picContainer];
This has the added benefit of automatically readjusting when the orientation changes.
try this one
cell.accessoryView=[UIImage imageNamed:#"tableicon.png"];

Resources