I'm creating a table view and custom view for my UITableView. Basically I have FirstViewController with table view and CustomTableViewCell. In custom cell, I had link all the controls to header and implements in the file which superclass with UITableViewCell. I'm creating a button, and want to programatically using "instantiateViewControllerWithIdentifier" for more flexibility in future. Here's come a problem :
Button being initialized
[self.playButton addTarget:self action:#selector(NavigationMethod) forControlEvents:UIControlEventTouchUpInside];
NavigateMethod
UIViewController *secondViewController = [[UIStoryboard storyboardWithName:#"Main" bundle:nil]instantiateViewControllerWithIdentifier:#"SecondViewController"];
[(FirstViewController*) presentViewController:secondViewController animated:YES completion:nil];
Because everything is in UITableViewCell instead of UIViewController.
You're breaking Model View Controller methodology here... In FirstViewController you should have
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
MYCustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
cell = [[MYCustomTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; // might not be UITableViewCellStyleDefault
[cell.playButton addTarget:self action:#selector(navigationMethod) forControlEvents:UIControlEventTouchUpInside];
}
// all indexPath based tableViewCell changes here
return cell;
}
Now -(void)navigationMethod can go in your FirstViewController class also. Which will allow you to call
[self presentViewController:secondViewController animated:YES completion:nil];
or
[self.navigationController presentViewController:secondViewController animated:YES completion:nil];
Just to add in as well.. unrecognised selector sent to instance means in this case the method NavigationMethod is not found in your UITableViewCell subclass
Related
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
I have a UITableView whose cellForRowAtIndexPath is printed below. When I call reloadData on the tableView, the application crashes, and there is no clear EXC_BAD_ACCESS or anything - it simply returns to main. The problem has arisen since I added the label subview, which leads me to think there may be some problem with releasing the subview/reusing the cell.
Can anyone see what's causing the problem?
Thanks in advance,
Ed
Here's the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MyCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//---
for(UIView *eachView in [cell subviews])
[eachView removeFromSuperview];
//Initialize cell label
UILabel *myLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 290, 25)];
[myLabel setFont:[UIFont fontWithName:#"HelveticaNeue" size:14.0]];
[myLabel setTextColor:[UIColor darkGrayColor]];
myLabel.text =#"Label";
[cell addSubview:myLabel];
[myLabel release];
return cell;
}
I am trying to implement programmatically a UITableView.
I have a UIView (named IndexView). Here is the constructor :
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
MyTableViewController* favorite_table_view_controller = [[MyTableViewController alloc] init];
UITableView* theTableView = [[UITableView alloc] initWithFrame:CGRectMake(20, 65, 280, 350) style:UITableViewStylePlain];
theTableView.delegate = favorite_table_view_controller;
theTableView.dataSource = favorite_table_view_controller;
[self addSubview:theTableView];
}
return self;
}
MyTableViewController is defined this way :
#interface MyTableViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
And implements the two necessary functions :
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return data.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"Cell"];
[cell.textLabel setText:[data objectAtIndex:indexPath.row]];
return cell;
}
And I get this error :
[__NSMallocBlock__ tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x6897de0
2012-07-18 12:07:24.607 ButtonsTest[22854:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSMallocBlock__ tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x6897de0'
I think there is a problem when I'm binding the controller to the view. But I can't find where.
Any idea where does the problem come from ?
You should not construct your viewcontroller from a view. It should be done the other way around.(construct views from UIVIewControllers)
make a ViewController that subclasses UIViewController and then let it implement the UITableViewDelegate and UITableViewDataSource. If you still need to control the UITableView from a another controller class setup this connection in the parent UIViewController, never from the View itself. That is the basic premise of the MVC used intensively in iOS
I just started using xcode and OBJ-c this year.
I am using mwfeedparser for a app I'm making but would like to change the look of the detailview.
right now i'm using the demo app that came with mwfeedparser to change the detail view.
i would like the detail view to have labels instead of being a tableview
i have changed this code
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewController *detail = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
detail.item = (MWFeedItem *)[itemsToDisplay objectAtIndex:indexPath.row];
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detail animated:YES];
// Deselect
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
when i run the code the detailview doesn't even come up. am I doing something wrong?
thanks for your help.
btw when i do get this done I'll put it up on github incase anybody else needs it
enter code hereself.parsedItems = [[NSMutableArray alloc] init];
- (void)feedParser:(MWFeedParser *)parser didParseFeedItem:(MWFeedItem *)item{
if (item) {
[self.parsedItems addObject:item];
}
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailViewController *detail = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
detail.item = [self.parsedItems objectAtIndex:indexPath.row];
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detail animated:YES];
}
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];
}
}