I'm trying to create an iPad application with a similar user interface to Apple's Mail application, i.e:
RootView controller (table view) on the left hand side of the split view for navigation with a multiple view hierarchy. When a table cell is selected a new table view is pushed on the left hand side
The new view on the left side can update the detail view.
I can accomplish both tasks, but not together.
I mean I can make a multi-level table view in the RootController.
Or I can make a single-level table view in the RootController which can update the detailViewController.
Can anyone tell me how to make a multi-level table in the RootController which can update a detailViewController?
There is more source code at the link but below is the method in which I presume I have to declare a new detailViewController (which has to be put in the UISplitViewController):
- (void)tableView:(UITableView *)TableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *dictionary = [self.tableDataSource objectAtIndex:indexPath.row];
//Get the children of the present item.
NSArray *Children = [dictionary objectForKey:#"Children"];
//
if([Children count] == 0) {
/*
Create and configure a new detail view controller appropriate for the selection.
*/
NSUInteger row = indexPath.row;
UIViewController <SubstitutableDetailViewController> *detailViewController = nil;
if (row == 0) {
FirstDetailViewController *newDetailViewController = [[FirstDetailViewController alloc]initWithNibName:#"FirstDetailView" bundle:nil];
detailViewController = newDetailViewController;
}
if (row == 1) {
SecondDetailViewController *newDetailViewController = [[SecondDetailViewController alloc]initWithNibName:#"SecondDetailView" bundle:nil];
detailViewController = newDetailViewController;
}
// Update the split view controller's view controllers array.
NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
splitViewController.viewControllers = viewControllers//nothing happens.....
[viewControllers release];//
}
else {
//Prepare to tableview.
RootViewController *rvController = [[RootViewController alloc]initWithNibName:#"RootViewController" bundle:[NSBundle mainBundle]];
//Increment the Current View
rvController.current_level += 1;
//Set the title;
rvController.current_title = [dictionary objectForKey:#"Title"];
//Push the new table view on the stack
[self.navigationController pushViewController:rvController animated:YES];
rvController.tableDataSource = Children;
[rvController.tableView reloadData]; //without this instrucion,items won't be loaded inside the second level of the table
[rvController release];
}
}
Sorry, but I cannot post my source code as it contains sensitive information. When I have more time available I will create a separate project and upload the code somewhere.
Here are extracts of how I have done it so far (I welcome any feedback).
The RootViewController - Note I have 4 sections in my root table.
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// Detail view logic
NSUInteger section = indexPath.section;
UIViewController <SubstitutableDetailViewController> *detailViewController = nil;
if (section == 2) {
ProductSearchDetailView *viewController = [[ProductSearchDetailView alloc] initWithNibName:#"ProductSearchDetailView" bundle:nil];
detailViewController = viewController;
//[viewController release];
}
else {
DetailViewController *defaultDetailViewController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
detailViewController = defaultDetailViewController;
//[defaultDetailViewController release];
}
// Navigation logic
switch (section) {
case 0:
{
break;
}
case 1:
{
break;
}
case 2:
{
// new Navigation view
ProductSearchViewController *viewController = [[ProductSearchViewController alloc] initWithNibName:#"ProductSearchViewController" bundle:nil];
viewController.navigationItem.backBarButtonItem.title = #"Back";
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];
break;
}
case 3:
{
StoreLocatorNavController *viewController = [[StoreLocatorNavController alloc] initWithNibName:#"StoreLocatorNavController" bundle:nil];
viewController.navigationItem.backBarButtonItem.title = #"Back";
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];
break;
}
}
// Update the split view controller's view controllers array.
NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
splitViewController.viewControllers = viewControllers;
[viewControllers release];
// Dismiss the popover if it's present.
if (popoverController != nil) {
[popoverController dismissPopoverAnimated:YES];
}
// Configure the new view controller's popover button (after the view has been displayed and its toolbar/navigation bar has been created).
if (rootPopoverButtonItem != nil) {
[detailViewController showRootPopoverButtonItem:self.rootPopoverButtonItem];
}
[detailViewController release];
}
NSNotificationCenter part
Add this to ProductSearchViewController:
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *itemAtIndex = (NSDictionary *)[self.productResults objectAtIndex:indexPath.row];
[[NSNotificationCenter defaultCenter] postNotificationName:#"updateProduct" object:itemAtIndex];
}
And finally, add this to ProductSearchDetailViewController:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(updateTheProductDetails:) name:#"updateProduct" object:nil];
}
- (void)updateTheProductDetails:(NSNotification *)notification {
NSDictionary *productDictionary = [NSDictionary dictionaryWithDictionary:[notification object]];
// product name
_productName.text = [productDictionary objectForKey:#"ProductDescription"];
}
Hope it helps!
Related
I am referring project from GitHub.
I am trying to modify it according to my requirement, but I am not getting and not able to understand that what code I have to write in didSelectRowAtIndexPath method.
What I want is that after clicking tableView row it can level 0 or level 1 (here level 0 means - row has no sub child and level 1 means row has subview/child rows )
When I click on any tableView row either level 0 or level 1, it has to navigate to next viewController.
In this example, row number 2 and 3 are expandable i.e it contains level 1 rows,
row 0, 1, 4 and 5 are level 1 rows they don't expand.
Here is project link (updated project link)
***** Added Code ****
the code I written in AppDelegate class,
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
userDefaults=[NSUserDefaults standardUserDefaults];
mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"loginSuccess"]) {
NSLog(#"Login Done!!!");
HomeViewController *homeVC=[mainStoryboard instantiateViewControllerWithIdentifier:#"homeId"];
SampleNavigationController *navigation = [[SampleNavigationController alloc] initWithRootViewController:homeVC];
//SWRevealViewController * vc= [[SWRevealViewController alloc]init];
//ExpandableTableViewController *sidemenu = (ExpandableTableViewController*)[mainStoryboard instantiateViewControllerWithIdentifier:#"sideMenu"];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = navigation;
[self.window makeKeyAndVisible];
}else
{
LoginViewController *loginVC=[mainStoryboard instantiateViewControllerWithIdentifier:#"LoginId"];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = loginVC;
[self.window makeKeyAndVisible];
}
return YES;
}
And in LoginViewController class, I have written code
- (IBAction)loginButtonMethod:(id)sender {
[self->userdefaults setBool:YES forKey:#"loginSuccess"];
InboxView *inboxVC=[self.storyboard instantiateViewControllerWithIdentifier:#"id1"];
[self.navigationController pushViewController:inboxVC animated:YES];
[[self navigationController] setNavigationBarHidden:NO];
}
Try this. ProductVC is your class where you want to push
NSString * storyboardName = #"Main";
NSString * viewControllerID = #"id3";
UIStoryboard * storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
ViewController3 * controller = (ViewController3 *)[storyboard instantiateViewControllerWithIdentifier:viewControllerID];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController: controller];
[navController setViewControllers: #[controller] animated: YES];
[self.revealViewController setFrontViewController:navController];
[self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
So like this you can move to any class, in didselectrowatindexpath just put validation for which row you want which class to push.
Please write your parent navigation code in following method . For child view
- (void)ftFoldingTableView:(FTFoldingTableView *)ftTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"indexPath--->%ld",(long)indexPath.row);
//Write your push next view controller code
[ftTableView deselectRowAtIndexPath:indexPath animated:YES];
}
Write parent view navigation code following method
- (void)ftFoldingTableView:(FTFoldingTableView *)ftTableView willChangeToSectionState:(FTFoldingSectionState)sectionState section:(NSInteger)section
{
NSLog(#"section-->%ld",(long)section);
// Write push level 0 or parent view move next view controller code
// NSLog(#"section: %ld is about to %#", section, sectionState == FTFoldingSectionStateFold ? #"close" : #"open");
}
Try this code working properly
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//check if the row at indexPath is a child of an expanded parent.
//At a time only one parent would be in expanded state
NSInteger indexSelected = indexPath.row;
NSDictionary *dicSelected =[self.itemsInTable objectAtIndex:indexSelected];
/**
Resolved the issue of top line separator dissapearing upon selecting a row (hackishly) by reloading the selected cell
*/
#try {
[self.menuTableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
#catch (NSException *exception) {
}
[tableView setSectionIndexBackgroundColor:[UIColor blackColor]];
//
//Collapse any other expanded cell by iterating through the table cells.
//Don't collapse if the selected cell is a child of an expanded row.
NSDictionary *dicCellToCollapse =[self.itemsInTable objectAtIndex:g_ExpandedCellIndex];
NSInteger numRowsCollapsed = 0;
NSInteger level = [[dicSelected valueForKey:#"level"] integerValue];
if(level==0 && [dicCellToCollapse valueForKey:#"SubItems"] && (g_ExpandedCellIndex != indexPath.row))
{
NSArray *arr=[dicCellToCollapse valueForKey:#"SubItems"];
BOOL isTableExpanded=NO;
for(NSDictionary *subitems in arr )
{
NSInteger index=[self.itemsInTable indexOfObjectIdenticalTo:subitems];
isTableExpanded=(index>0 && index!=NSIntegerMax);
if(isTableExpanded) break;
}
//
//Collapse the parent cell if its expanded
if(isTableExpanded)
{
[self CollapseRows:arr];
numRowsCollapsed = [arr count]-1;
}
}
//
//go about the task of expanding the cell if it has subitems
NSDictionary *dic;
if (g_ExpandedCellIndex < indexPath.row && numRowsCollapsed)
{
dic = [self.itemsInTable objectAtIndex:indexPath.row-numRowsCollapsed-1];
}
else
{
dic = [self.itemsInTable objectAtIndex:indexPath.row];
}
//
//Check if the selected cell has SubItems i.e its a Parent cell
if([dic valueForKey:#"SubItems"])
{
arr=[dic valueForKey:#"SubItems"];
BOOL isTableExpanded=NO;
for(NSDictionary *subitems in arr )
{
NSInteger index=[self.itemsInTable indexOfObjectIdenticalTo:subitems];
isTableExpanded=(index>0 && index!=NSIntegerMax);
if(isTableExpanded) break;
}
//
//Collapse the parent cell if its expanded
if(isTableExpanded)
{
[self CollapseRows:arr];
}
//
//Else expand the cell to show SubItems
else
{
// ViewController3 * vc = [self.storyboard instantiateViewControllerWithIdentifier:#"id3"];
// [self.navigationController pushViewController:vc animated:YES];
//
//store the location of the cell that is expanded
NSUInteger rowIndex;
if (g_ExpandedCellIndex < indexPath.row && numRowsCollapsed)
{
rowIndex = indexPath.row-numRowsCollapsed;//zero based index
g_ExpandedCellIndex = indexPath.row-numRowsCollapsed-1;//zero based index
}
else
{
rowIndex = indexPath.row+1;
g_ExpandedCellIndex = indexPath.row;
}
//
//Insert the SubItems
NSMutableArray *arrCells=[NSMutableArray array];
for(NSDictionary *dInner in arr )
{
[arrCells addObject:[NSIndexPath indexPathForRow:rowIndex inSection:0]];
[self.itemsInTable insertObject:dInner atIndex:rowIndex++];
ViewController3 * vc = [self.storyboard instantiateViewControllerWithIdentifier:#"id3"];
[self.navigationController pushViewController:vc animated:YES];
}
[self.menuTableView insertRowsAtIndexPaths:arrCells withRowAnimation:UITableViewRowAnimationTop];
}
}
//Else a subItem has been clicked. We need to push the relevant view into segue
else
{
NSString* strId =[dic valueForKey:#"id"];
NSDictionary *dict = arr[0];
NSString *id1=[dict objectForKey:#"id"];
NSLog(#"%#",strId);
NSLog(#"%#",id1);
if([id1 isEqualToString:#"sme_marketwatch"])
{
ViewController3 * vc = [self.storyboard instantiateViewControllerWithIdentifier:#"id3"];
[self.navigationController pushViewController:vc animated:YES];
}
ViewController3 * vc = [self.storyboard instantiateViewControllerWithIdentifier:#"id3"];
[self.navigationController pushViewController:vc animated:YES];
//
// ViewController1 * vc = [self.storyboard instantiateViewControllerWithIdentifier:#"id1"];
// [self.navigationController pushViewController:vc animated:YES];
// NSString* strId =[dic valueForKey:#"id"];
// NSLog(#"Id is %#",strId);
//
// if([strId isEqualToString:#"getquote"]) //getquote
// {
// ViewController3 * vc = [self.storyboard instantiateViewControllerWithIdentifier:#"id3"];
// [self.navigationController pushViewController:vc animated:YES];
// }
}
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ViewController3 *newView = [storyboard instantiateViewControllerWithIdentifier:#"id3"];
[self presentViewController:newView animated:YES completion:nil];
// ViewController3 * vc = [self.storyboard instantiateViewControllerWithIdentifier:#"id3"];
// [self.navigationController pushViewController:vc animated:YES];
}
I have an int pageNumber setup like so #property (nonatomic, assign) int pageNumber; which I am trying to pass between two view controllers.
It works the first time I tap a cell in the tableview, however if I tap a cell again the int does not get updated.
Any ideas? My code is below.
LeftMenuViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone"
bundle: nil];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
SoftwareCheckViewController *sc = [[SoftwareCheckViewController alloc] init];
if ([cell.textLabel.text isEqual: #"S:1 R:0"]) {
sc = [mainStoryboard instantiateViewControllerWithIdentifier: #"SoftwareCheckViewController"];
sc.pageNumber = 1;
}
else if ([cell.textLabel.text isEqual: #"S:1 R:1"]) {
sc = [mainStoryboard instantiateViewControllerWithIdentifier: #"SoftwareCheckViewController"];
sc.pageNumber = 2;
}
else if ([cell.textLabel.text isEqual: #"S:1 R:2"]) {
sc = [mainStoryboard instantiateViewControllerWithIdentifier: #"SoftwareCheckViewController"];
sc.pageNumber = 3;
}
[[NSNotificationCenter defaultCenter] postNotificationName:#"pageNumberNotification" object:self];
}
SoftwareCheckViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(pageNumberMethod) name:#"pageNumberNotification" object:nil];
}
- (void)pageNumberMethod{
NSLog(#"pageNumber: %i", pageNumber);
}
You are creating new view controllers every time you tap a cell but you aren't doing anything with them. Setting sc.pageNumber is never going to have an effect if sc isn't the controller that's listening for a notification.
Also, even if you wanted a new controller, [[SoftwareCheckViewController alloc] init] is basically a waste because you then assign something different to sc right after.
I have a view controller where the user can populate an item. Upon exiting the view that object should be saved, and loaded by the previous view which contains a list of all these objects. My NSLog shows that the object is being saved, but I can't get it to appear in the list view.
Code for both controllers is below. Thanks
List Controller
#import "ItemsViewController.h"
#import "Calculation.h"
#import "CalculationItemStore.h"
#import "CalculationDetailViewController.h"
#interface ItemsViewController()
#property UISegmentedControl *segment;
#end
#implementation ItemsViewController
- (instancetype)init
{
// Call the superclass's designated initializer
self = [super initWithStyle:UITableViewStylePlain];
if (self) {
UINavigationItem *navItem = self.navigationItem;
navItem.title = #"MACS";
// Create a new bar button item that will send
// addNewItem: to CalculationsViewController
UIBarButtonItem *bbi = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(addNewItem:)];
// Set this bar button item as the right item in the navigationItem
navItem.rightBarButtonItem = bbi;
navItem.leftBarButtonItem = self.editButtonItem;
}
return self;
}
- (instancetype)initWithStyle:(UITableViewStyle)style
{
return [self init];
}
- (void)viewDidLoad
{
self.segment = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Publication", #"About", nil]];
self.tableView.tableHeaderView = _segment;
[_segment addTarget:self action:#selector(segmentPressed:) forControlEvents:UIControlEventValueChanged];
[self.tableView registerClass:[UITableViewCell class]
forCellReuseIdentifier:#"UITableViewCell"];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.tableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[[CalculationItemStore sharedStore] allCalculations] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Get a new or recycled cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell" forIndexPath:indexPath];
// Set the text on the cell with the description of the item
// that is at the nth index of items, where n = row this cell
// will appear in on the tableview
NSArray *items = [[CalculationItemStore sharedStore] allCalculations];
Calculation *item = items[indexPath.row];
cell.textLabel.text = item.title;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
CalculationDetailViewController *detailViewController = [[CalculationDetailViewController alloc] init];
NSArray *items = [[CalculationItemStore sharedStore] allCalculations];
Calculation *selectedItem = items[indexPath.row];
// Give detail view controller a pointer to the item object in row
detailViewController.calculation = selectedItem;
// Push it onto the top of the navigation controller's stack
[self.navigationController pushViewController:detailViewController
animated:YES];
}
- (void) tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
// If the table view is asking to commit a delete command...
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSArray *items = [[CalculationItemStore sharedStore] allCalculations];
Calculation *item = items[indexPath.row];
[[CalculationItemStore sharedStore] removeItem:item];
// Also remove that row from the table view with an animation
[tableView deleteRowsAtIndexPaths:#[indexPath]
withRowAnimation:UITableViewRowAnimationFade];
}
}
- (void) tableView:(UITableView *)tableView
moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toIndexPath:(NSIndexPath *)destinationIndexPath
{
[[CalculationItemStore sharedStore] moveItemAtIndex:sourceIndexPath.row
toIndex:destinationIndexPath.row];
}
- (void)segmentPressed:(id)sender {
if (_segment.selectedSegmentIndex ==0) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"http://ferm.forestry.oregonstate.edu/facstaff/leshchinsky-ben"]];
}else if(_segment.selectedSegmentIndex ==1){
UIImageView *imageView = [[UIImageView alloc] initWithFrame: CGRectMake(0, 0, 320, 480)];
imageView.backgroundColor = [UIColor redColor];
[imageView setImage: [UIImage imageNamed:#"MACSLoad#2x.png"]];
[self.view addSubview: imageView];
sleep(5);
imageView.hidden = YES;
}
}
- (IBAction)addNewItem:(id)sender
{
// Create a new Calculation and add it to the store
Calculation *newItem = [[CalculationItemStore sharedStore] createCalculation];
CalculationDetailViewController *detailViewController = [[CalculationDetailViewController alloc]initForNewItem:YES];
detailViewController.calculation = newItem;
detailViewController.dismissBlock = ^{
[self.tableView reloadData];
};
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:detailViewController];
navController.modalPresentationStyle = UIModalPresentationFullScreen;
// [self presentViewController:navController animated:YES completion:NULL];
[self.navigationController pushViewController:detailViewController animated:YES];
}
#end
Item controller save method
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
//clear responder
[self.view endEditing:YES];
//save changes
BOOL success = [[CalculationItemStore sharedStore]saveChanges];
if(success){
NSLog(#"Saved all calcs");
}else{
NSLog(#"failure saving");
}
}
I think the issue is that by the time the table reloadData is called on the first controller, the second one is not done loading. You could notify the first VC to reload the data once the second one is done saving It can be notified using
create a delegate on the second one or
using notifications
Let me know if you need more details on how to do this!
Looks like there is also an issue with the object creation.
your calculation elements are not getting created properly. When you are ready to save.. look at the contents of self.privateItems. They values filled in are nil. You will need to instantiate the Strings properly.
engineerName needs to be alloc'd and other strings as well.
and when user hits Done, the values from the text boxes need to be set to the your data model.
Is it possible to open different view controllers depending on witch table view cell user clicks? I tried to do that with:
[self presentViewController:obj animated:YES completion:nil];
but when next view is presented, there is no navigation bar and I can't go back to table view.
EDIT:
Here is MasterViewController class that I am using
#import "MasterViewController.h"
#interface MasterViewController () {
NSArray *viewArray;
}
#end
#implementation MasterViewController
#synthesize items,itemImges;
- (void)awakeFromNib
{
if ([[[UIDevice currentDevice] systemVersion] compare:#"7" options:NSNumericSearch] != NSOrderedAscending) {
self.preferredContentSize = CGSizeMake(320.0, 480.0);
}
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
self.clearsSelectionOnViewWillAppear = NO;
}
self.title = NSLocalizedString(#"MasterTitle",#"Options:");
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
items = [NSArray arrayWithObjects:#"Media Explorer",#"Live TV",#"Settings",nil];
itemImges = [NSArray arrayWithObjects:
[UIImage imageNamed:#"listicon_guide.png"],
[UIImage imageNamed:#"listicon_livetv.png"],
[UIImage imageNamed:#"listicon_settings.png"],
nil];
// Do any additional setup after loading the view, typically from a nib.
self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
MediaExpDetailViewController *DVCA = [self.storyboard instantiateViewControllerWithIdentifier:#"MediaExpDetailViewController"];
LiveTVDetailViewController *DVCB = [self.storyboard instantiateViewControllerWithIdentifier:#"LiveTVDetailViewController"];
SettingsDetailViewController *DVCC = [self.storyboard instantiateViewControllerWithIdentifier:#"SettingsDetailViewController"];
//Create Array of views
viewArray = [NSArray arrayWithObjects:DVCA, DVCB, DVCC, nil];
}
#pragma mark - Table View
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return items.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
NSString *object = items[indexPath.row];
UIImage *image = itemImges[indexPath.row];
cell.textLabel.text = [object description];
cell.imageView.image = image;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//for iPad
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
//something goes here
}
else { //for iPhone
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
MediaExpDetailViewController *objSynergy = (MediaExpDetailViewController *)[mainStoryboard instantiateViewControllerWithIdentifier:#"MediaExpDetailViewController"];
[self.navigationController pushViewController:objSynergy animated:YES];
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
}
#end
First set Storyboard IDs for your Next View controllers in Interface Builder and then.
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Check Row and Select Next View controller
if (indexPath.row == 1)
{
// Push Selected View
UIViewController *view1 = [self.storyboard instantiateViewControllerWithIdentifier:#"StoryboardID"];
[self.navigationController pushViewController:view1 animated:YES];
}
}
That's because
[self presentViewController:obj animated:YES completion:nil];
Presents the new view controller modally (over top of the existing visible controller). If you want to push to a new view controller using your navigation controller, you'll want to use this. Of course you'll want to make sure that the view controller you're pushing from is embedded within a UINavigationController.
[self.navigationController pushViewController:obj animated:YES];
And to answer your first question, yes it absolutely is possible. Just add some condition logic to your didSelectRowAtIndexPath: UITableViewDelegate method.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (someCondition) {
[self.navigationController pushViewController:obj animated:YES];
}else{
[self.navigationController pushViewController:otherObj animated:YES];
}
}
Modally presented view controllers don't have navigation bars by default. You have to embed them in a UINavigationController, in order to have one. You should also implement how to dismiss the presented view controller by yourself, calling dismissViewControllerAnimated at the appropriate times.
However, I'd recommend to push your view controllers (with pushViewControllerAnimated), instead of presenting them modally, if you don't specifically need the modal functionality.
I am creating an iPad version of Master Detail Application using XCode 4.5 with ARC.
I have my iPadMaster.h/.m(as my master) and iPadDetailViewController.h/m(as my detail) set up.
I am trying to load different view controllers from iPadDetailViewController when users click/select the rows on iPadMaster.
I set this on iPadMaster.m at:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
iPadDetailViewController * DVC = [[iPadDetailViewController alloc]initWithNibName:nil bundle:nil];
DVC.itemNumber = indexPath.row;
}
and tried this stupid stunt on iPadDetailViewController.m on [viewDidLoad]:
switch(_itemNumber)
{
case 0:
{
//Detail row
vc1 *viewController = [[vc1 alloc] init];
[self presentViewController:viewController animated:YES completion:nil];
break;
}
case 1:
{
//Report row
vc2 *viewController = [[vc2 alloc] init];
//viewController.somePassedInData = theDataToPass;
[self presentViewController:viewController animated:YES completion:nil];
break;
}
case 2:
{
//Report row
vc3 *viewController = [[vc3 alloc] init];
//viewController.somePassedInData = theDataToPass;
[self presentViewController:viewController animated:YES completion:nil];
break;
}
...
case 9:
{
//Report row
vc9 *viewController = [[vc9 alloc] init];
//viewController.somePassedInData = theDataToPass;
[self presentViewController:viewController animated:YES completion:nil];
break;
}
default:
{
break;
}
On iPhone i would just plaster the 'switch cases' in the - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath but i'm at lost with iPad environment...
Thanx in advance...
The split view controller has a property, viewControllers. The object at index 1 is the detail controller. You should just create a mutable copy of viewControllers, replace the object at index 1 with your new controller, and set that array to be the split view's arrayControllers.
NextController *next = [[NextController alloc] init..... // or however you get your new controller
NSMutableArray *mut = [self.splitViewController.viewControllers mutableCopy];
[mut replaceObjectAtIndex:1 withObject:next];
self.splitViewController.viewControllers = mut;