I want to make a table view inside of a table view. I mean how can I make an app that clicking a cell goes to another list of cells to click to go subclass?
Convolution's answer contains a memory leak. Proper code should look like this:
MySecondViewController *secondController = [[MySecondViewController alloc]
initWithNibName: #"SecondViewController" bundle: nil];
if (secondController != nil) {
[self.navigationController pushViewController: secondController animated: YES];
[secondController release];
}
The release is essential. Otherwise you leak memory.
I don't know what you mean by a table view inside of a table view, I think what you want to do is have a hierarchy of table views. You can push another table view onto the stack within the delegate method didSelectRowAtIndexPath.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
MySecondViewController *secondController = [[MySecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[self.navigationController pushViewController:secondController animated:YES];
}
By implementing this method when you click a cell, it goes to another table view (list of cells).
Related
I'm new to iOS development. I have an app that has a UINavigationController (with an embedded UITableViewController, call it TableView1) and I need to display another UITableView (TableView2) on the tap of a UITableViewCell for TableView1.
I did some online searching and didn't really find anything super useful, but what I was able to find said that I have to present TableView2 instead of pushing it. Everything is working correctly, except that TableView2 doesn't have a back button and I have to create my own UIBarButtonItem and assign to leftBarButtonItem of the navigationItem.
This is all fine, except for the fact that I can't help but feel like I'm doing it wrong. Is there any easier way (or a more correct way) to accomplish what I'm trying to accomplish?
Code for TableView1
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewController *tableViewController = [[UITableViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:tableViewController];
[self.navigationController presentViewController:navigationController
animated:YES
completion:nil];
}
EDIT: Along with this question, if I find out I'm doing this the correct way, how do I get the normal back button to display? or can I?
Present it directly from that view controller:
[self presentViewController:navigationController animated:YES completion:nil];
Or use pushViewController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewController *tableViewController = [[UITableViewController alloc] init];
[self.navigationController pushViewController:tableViewController animated:YES];
}
Im working with table view controllers within story board.
I currently have one tableview controller embedded in navigation controller in my storyboard. This table view controller is linked to an ObjectiveC file.
Through code i can display another table view controller with the correct data using the tableView didSelectRowAtIndexPath method.
code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
WorkoutType *workoutType = (WorkoutType *)[self.fetchedResultsController objectAtIndexPath:indexPath];
WorkoutSetViewController *detailViewController = [[WorkoutSetViewController alloc] initWithWorkoutType:workoutType];
[self.navigationController pushViewController:detailViewController animated:YES];
}
But if i try to add another table view controller in storyboard, associate it with an objectiveC view controller file and connect the first TVC to it, That table view controller is not shown upon running the code.
I need to customise the second table view visually and have tried to use a segue push...as follows:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"show"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
WorkoutType *workoutType = (WorkoutType *)[self.fetchedResultsController objectAtIndexPath:indexPath];
//WorkoutSetViewController *detailViewController = [[WorkoutSetViewController alloc] initWithWorkoutType:workoutType];
WorkoutSetViewController *destViewController = segue.destinationViewController;
destViewController.workoutType = workoutType;
//[self.navigationController pushViewController:detailViewController animated:YES];
}
}
But when i run this code, the second table view controller doesn't even load although the application doesn't crash.
Whatever I am doing wrong must be simple, any help would be appreciated.
Thank You
Simple You have to navigate through below code. (No need to set storyboard when you working in same storyboard ViewController)
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexpath.row==0)//for first row click
{
WorkoutSetViewController *objWorkoutSetVC=[[WorkoutSetViewController alloc] i nitWithNibName:#"WorkoutSetViewController" bundle:nil];
[self.navigationController pushViewController:objWorkoutSetVC animated:YES];
}
else if(indexpath.row==1)//for second row click
{
//Put code in which screen you have to navigate
}
}
Do NOT Alloc init your new view controller. Use this code instead:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
WorkoutSetViewController *detailViewController = (WorkoutSetViewController *)[storyboard instantiateViewControllerWithIdentifier:#"coolID"];
[self.navigationController pushViewController:detailViewController animated:YES];
For MainStoryboard write your storyboard name and for coolID write your view controller id name which you set in your storyboard.
Basically, I have two MasterViewControllers for a splitViewController,but I am only able to run the app with one of them at a time. Both MasterViewControllers are using the same DetailViewController.
When the user push a tabbarbutton, the second masterViewController is pushed.
The splitViewController is straight forward declared like this in the AppDelegate
MasterViewControllerOne *mvc1 = [[MasterViewControllerOne alloc] initWithNibName:#"MasterViewControllerOne_iPad" bundle:nil];
UINavigationController *masterOneNavigationController = [[UINavigationController alloc] initWithRootViewController:mvc1];
DetailViewController *dvc = [[DetailViewController alloc] initWithNibName:#"DetailViewController_iPad" bundle:nil];
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:dvc];
self.splitViewController = [[UISplitViewController alloc] init];
self.splitViewController.delegate = detailViewController;
self.splitViewController.viewControllers = #[masterOneNavigationController, detailNavigationController];
self.window.rootViewController = self.splitViewController;
During runtime, I want MasterViewControllerTwo to swap with MasterViewControllerOne
Action to push the new view controller:
MasterViewControllerTwo*mvc2=[[MasterViewControllerTwo alloc]initWithNibName:#"MasterViewControllerTwo_iPad" bundle:nil];
[self.navigationController pushViewController:mvc2 animated:YES];
This swaps in the mvc2 on top of mvc1. However, tapping the rows of the tableview in mvc2 does not activate the DetailViewController.
To activate the DetailView (identical for mvc1 and mvc2) I do following
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Item *theItem =[[self.items objectAtIndex:[indexPath section]]objectAtIndex:[indexPath row]];
[self.detailViewController setLabelsForItems:theItem];
}
Works very well as long the MasterViewController is defined in the appdelegate as member of the splitviewcontrollers array. So why doesn't the mvc2 activate the DetailViewController when it is on top of the stack?
tapping the rows of the tableview in mvc2 does not activate the
DetailViewController
Well, that isn't going to happen magically all by itself. It's up to you to respond when a row of the second table view is selected. You haven't shown any code for doing that, so one assumes you have none.
In other words, a split view controller does nothing in and of itself except for containing the master and the detail. Communicating between the master and the detail is up to you. The template shows you the sort of thing you'll need to do.
I was wondering how I can load a different view into the detailView from rootview..
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
SecondViewController *svc = [[SecondViewController alloc] init];
//[self.navigationController pushViewController:svc animated:YES];
}
}
The splitviewcontroller has an array of 2 views one is root view and another one is detail view,and you can change the views in this array. If you alloc and init a view and replace it with either of these two then this view will replace the current view in the splitviewcontroller.
Use this code for loading different views for different cells of rootview. Change rootview's didSelectRowAtIndexPath method as follow:
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIViewController *localdetailViewController = nil;
if (indexPath.row==0)
{
DetailViewController *detailView=[[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
localdetailViewController=detailView;
detailView=nil;
}
if (indexPath.row==1)
{
SecondViewController *secondDetailView=[[SecondViewController alloc] initWithNibName:#"SecondDetailViewController" bundle:nil];
localdetailViewController=secondDetailView;
secondDetailView = nil;
}
UINavigationController *navController=[[UINavigationController alloc] init];
[navController pushViewController:localdetailViewController animated:YES];
YourSplitViewAppDelegate *delegate=[[UIApplication sharedApplication] delegate];
NSArray *viewControllers=[[NSArray alloc] initWithObjects:[delegate.splitViewController.viewControllers objectAtIndex:0],navController,nil];
delegate.splitViewController.viewControllers = viewControllers;
[localdetailViewController release];
[navController release];
}
My solution is using Using Xcode 7.1.1 for a universal app, using Storyboards, Auto Layout and Size Classes, building for iOS 9...
I used a version of Midhun MP's answer... within the current/original (not replacement/new/second) detail view controller's viewDidLoad method:
obviously first import the correct header file for your controller:
#import "NEW_DetailViewController.h"
then within viewDidLoad method:
- (void)viewDidLoad {
[super viewDidLoad];
<<OTHER_CODE>>
if (<<INSERT_THE_LOGIC_YOU_NEED_TO_TRIGGER_THE_REPLACEMENT_DETAIL_VC>>) {
NEW_DetailViewController *viewNewDetailVC = [[NEW_DetailViewController alloc] initWithNibName:#"NEW_DetailViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] init];
[navController pushViewController:viewNewDetailVC animated:YES];
NSArray *arraySplitViewControllers = [[NSArray alloc] initWithObjects:[self.splitViewController.viewControllers objectAtIndex:0],navController,nil];
self.splitViewController.viewControllers = arraySplitViewControllers;
}
}
NOTE I could make this code work without loading a XIB file, building the entire replacement detail VC in code, with [[UIViewController alloc] init] instead of [[NEW_DetailViewController alloc] initWithNibName:#"NEW_DetailViewController" bundle:nil], but was frustrated that I could not make the XIB file load, so I persisted...
I attempted many variations from many different SO answers in attempting to solve this problem of successfully loading a XIB file as the replacement detail view controller in a split view controller.
Finally this answer by Travis M gave me the hint I needed...
Delete all the efforts you have attempted to date to create a new XIB file and subclass of UIViewController!
Create a new file and make it a subclass of UIViewController. See screenshot:
IMPORTANT ensure you check the checkbox "Also create XIB file".
You don't need to modify the new subclass of UIViewController, unless you'd like to code up the contents of the view. I only needed to add in a UILabel for my solution and I did this using Interface Builder.
Make sure you reference the replacement view controller NEW_DetailViewController in code as per my example above.
That's it!
In your XIB file you should end up with the following:
I have an app in portrait, in my View Controller (UIViewController, not a UITableViewController) there is a table (UITableView) that only occupies half the screen.
I set the delegate and datasource of my table view to my view controller.
Now, I would like to show a detail view when i select any cell of my table. Here is what I tried but nothing appears:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"SELECTED");
//ChangeView
DetailViewController *dvController = [[DetailViewController alloc]
initWithNibName:#"DetailViewController" bundle:nil];
[self.navigationController pushViewController:dvController animated:YES];
dvController = nil;
}
Any idea? Is this solution better than a popup solution?
You Should check your tableview in nib file it datasource and delegate is connected or not?
just connect both with file owner.
and if you are using uiview controller then use present model view controller not push modelview controller.
DetailViewController *dvc=[[DetailViewController alloc]initWithNibName:#"DetailViewController" bundle:nil];
[self presentModalViewController:dvc animated:YES];
Put [NSBundle mainBundle] in place of nil. Hope it helps. Tell me what happens!
Also replace dvController=nil; with [dvController release];
EDIT:
Replace ur init function with this one:
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
return self;
}
initialize navigation controller. becauze some time it is due to ui component which has not initialized. but remember that you may have to face some other UI issues
You should check if didSelectRowAtIndexPath is really called or not when you select a table cell (of not, your delegate may not be set correctly), then if
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
returns nil or something meaningful with a debugger, trying to close in on the problem. Also, #M.A.Khan was right, you should remove
dvController = nil;
and replace it with
[dvController release];
giving up the reference in your main view.
Edit:
Your code asumes that beneath your UIViewController, there is a UINavigationController because you're using [self.navigationController pushViewController]. If there isn't, no wonder your view does not get pushed onto something that doesn't exist.
is the viewcontroller with tableview in a navigationcontroller?if not then first you have to create a navigationcontroller with the current viewcontroller as the rootviewcontroller.then try this code u are using now