i have a requirement to load multiple viewControllers on detailViewController on a splitView. somethingLike
when the alarm is on , so that i can push the related view controller on detailView. left side view is a uitableview.
my code is here on AppDelegate.m
#import "splitDetailViewController.h"
#import "splitTableViewController.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
splitTable=[[splitTableViewController alloc]initWithStyle:UITableViewStyleGrouped];
UINavigationController *splitTableNav=[[UINavigationController alloc]initWithRootViewController:splitTable];
splitDetails=[[splitDetailViewController alloc]initWithNibName:nil bundle:nil];
UINavigationController *splitDetailNav=[[UINavigationController alloc]initWithRootViewController:splitDetails];
self.splitViewController.delegate=splitDetails;
splitViewController=[[UISplitViewController alloc]init];
splitViewController.viewControllers=[NSArray arrayWithObjects:splitTableNav,splitDetailNav, nil];
[self.window addSubview:splitViewController.view];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
sorry, this is the first time am developing iPad apps, am little bit confused about how to use splitview. how will i call the multiple viewControllers on detail view. for timer, alarm,share , each have different view controllers.
hope i will get some help!
I was searching for the solution to a similar problem. In my case i wanted tableview to link to multiple detailviews depending on the selection. I could overlay the data on one viewcontroller but was seeking a better solution. Here is what i did. Its simple and works much better then some of the complex and outdated options i found so far.
I simply gave a storyboard ID in the identity inspector to the viewcontroller that i wanted showing up in the detailview ("second") and upon didSelectRowAtIndexPath i simply added:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
TimeDetailViewController *detail = [self.storyboard instantiateViewControllerWithIdentifier:#"second"];
[[self.splitViewController.viewControllers objectAtIndex:1] pushViewController:detail animated:YES];
}
So when someone presses a cell in the master view, the detail view is pushed.
A simple if statement can switch which view is shown:
if ([[self.selfRootMenuArray objectAtIndex:indexPath.row] isEqual: #"Second Choice"]) {
TimeDetailViewController *detail = [self.storyboard instantiateViewControllerWithIdentifier:#"second"];
[[self.splitViewController.viewControllers objectAtIndex:1] pushViewController:detail animated:YES];
} else if ([[self.selfRootMenuArray objectAtIndex:indexPath.row] isEqual: #"First Choice"]) {
TimeDetailViewController *detail = [self.storyboard instantiateViewControllerWithIdentifier:#"first"];
[[self.splitViewController.viewControllers objectAtIndex:1] pushViewController:detail animated:YES];
};
You could simply use buttons, switches or anything else instead of a table view but the point is that by adding a "Storyboard ID" in the "Identity Inspector"
and simply instantiating the view controller by referencing the "Storyboard ID" and then pushing it to the split view controller at index 1 (detail side) its simple and quick
TimeDetailViewController *detail = [self.storyboard instantiateViewControllerWithIdentifier:#"second"];
[[self.splitViewController.viewControllers objectAtIndex:1] pushViewController:detail animated:YES];
Hope it helps
okay, myself found one solution, it works fine
http://kshitizghimire.com.np/uisplitviewcontroller-multipledetailviews-with-navigation-controller/
thankyou
This is my Solution, hope it helps : https://github.com/selfdealloc/MultipleDetailViewsUsingStoryboards
Related
I am new to iOS development and need a bit of help. I have searched high and low and cannot find the answer. It's more like I don't understand what is happening. My issue is, I am trying to code a Master-Detail App without using storyboards. This helps me get a better understanding of how ViewControllers are managed and handled. I am trying to present the DetailViewController after an item is selected in a tableView in the MasterViewController on iPhone. On iPad it works well because both views are side by side.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//Pass data to detailViewController
if ([_detailDelegate respondsToSelector:#selector(item:selectedAtIndexPath:)]) {
[_detailDelegate item:[[BNRItemStore sharedStore] findItemAtIndex:indexPath.row] selectedAtIndexPath:indexPath];
}
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone ) {
// show DetailViewController
NSArray *viewControllers = self.splitViewController.viewControllers;
UINavigationController *detailNavigationViewController = [viewControllers objectAtIndex:1];
[self showDetailViewController:detailNavigationViewController sender:nil];
}
}
In a storyboard the selected ViewCell has a show detail segue to the detailViewController. How can I achieve the same thing without using storyboards?
My AppDelegate code for a better picture
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UISplitViewController *splitViewController = [[UISplitViewController alloc] init];
self.window.rootViewController = splitViewController;
UINavigationController *masterNavigationController = [[UINavigationController alloc]init];
UINavigationController *detailNavigationController = [[UINavigationController alloc]init];
MasterTableViewController *masterTableViewController = [[MasterTableViewController alloc] init];
DetailViewController *detailViewController = [[DetailViewController alloc] init];
masterTableViewController.detailDelegate = detailViewController;
detailViewController.masterDelegate = masterTableViewController;
masterNavigationController.viewControllers = #[masterTableViewController];
detailNavigationController.viewControllers = #[detailViewController];
[splitViewController setViewControllers:#[masterNavigationController,detailNavigationController]];
[self.window makeKeyAndVisible];
return YES;
}
Thanks.
I was able to solve this issue after reading this post. When the UISplitViewController detects that it is in portrait mode on an iPhone it removes the DetailViewController from its viewControllers property. When it is in landscape mode its add the DetailViewController(Secondary Controller)back to the viewControllers property.
Solution:
Added a strong reference property in the MasterViewController(Primary Controller) to store the DetailViewController.
When an item is selected in the MasterViewController table, I checked the UISplitViewController viewControllers property and if the DetailViewController was missing from the Array, I pushed the DetailViewController onto the Parent Controller(UINavigationViewController)stack.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailViewController *detailController = (DetailViewController *) self.detailViewController.viewControllers[0];
[detailController item:[[BNRItemStore sharedStore] findItemAtIndex:indexPath.row] selectedAtIndexPath:indexPath];
if (self.splitViewController.viewControllers.count == 1) {
[self.navigationController pushViewController:self.detailViewController animated:YES];
}
}
Try changing:
[self showDetailViewController:detailNavigationViewController sender:nil];
to:
[self.splitViewController showDetailViewController:detailNavigationViewController sender:nil];
I'm totally new to iOS programming. I only programmed on Android so far and Objective-C is a total different and new language for me now.
What I want to do is to not use a design that I've created with the storyboard. I want to do all programmatically, since I think it will be more dynamic if I do it like this.
The problem I'm encountering is, that I want to have 3 different views. I googled a bit, and stumbled upon some stackoverflow questions. There, people suggested using a NavigationController. Okay. Now I'm trying to implement it. What I want to have is the following
A MainViewController that has 3 different views. The first view is a loginView. The second one is displaying data and the third is displaying detailed data dependent on the click of the second view.
Is a navigationcontroller corerct for this? The problem I'm having is where I tell the app that I want to start with the MainViewController and push the LoginView in it.
I have a MainViewController.h and MainViewController.m that are subclasses of UIViewController
Now, where exactly do I do this? I have the didFinishLaunchingWithOptions method right here with the following content
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
UIViewController *viewController = [[MainViewController alloc]init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
[navigationController pushViewController:viewController animated:NO];
self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
return YES;
}
But that just crashes the app. What am I doing wrong? How do I get those three views? Am I starting completely wrong? Please help. As I said I'm new to iOS development. It's easy for me to programm on one view. I did that already, but I want thre different views! Thanks!
A MainViewController that has 3 different views. The first view is a loginView. The second one is displaying data and the third is displaying detailed data dependent on the click of the second view.
That's wrong.
You need three different view controllers, each of those will manage its own view.
Then you push one after another in the navigation controller, depending on user interaction.
Yes, Gonzalo Aune is rite, You should not push the rootviewcontroller in NavicationController.
Also , I will Suggest you to keep your first view (Login View) out of Navigation controller.
You can start with your MainViewController and based on check and conditions you can present LoginView on MainViewController using
[self presentViewController:loginViewController animated:YES completion:NULL];
And after successful login you can dismiss LoginViewController.
Remove this:
[navigationController pushViewController:viewController animated:NO];
You shouldnt push the ViewController since you told the NavigationController already that the ViewController would be the root one:
UINavigationController *navigationController = [[UINavigationController alloc]
initWithRootViewController:viewController];
use this code and if application is universion then use same code else remove the condition of ([[UIDevice currentDevice] userInterfaceIdiom]
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UINavigationController *navController;
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_iPhone" bundle:nil];
{
if(result.length>0)
{
for(var i in result)
{
var ObjResult=result[i];
var content = "<div data-role='collapsible' id='set" + i + "'>";
content+="<h3>"+ObjResult.title+"<br>";
var intDate=parseInt(ObjResult['ordered date']);
content +=timestampToDate(intDate)+"</h3>"
if(isNaN(ObjResult.med_placeorderfor))
content+="<p><a>Medicle Place order for: </a>"+result[i].med_placeorderfor+"</p>";
if(isNaN(ObjResult.pres_placeorderfor)>0)
content+="<p><a>Medicle Place order for: </a>"+result[i].placeorderfor+"</p>";
if(ObjResult['order status'].length>0)
content+="<p><a>Order status: </a>"+ObjResult['order status']+"</p>";
if(ObjResult.comments.length>0)
content+="<p><a>Comments: </a>"+ObjResult.comments+"</p>";
content+="</div>";
}
$("#id_notification_list_dashboard").append( content ).collapsibleset('refresh');
$("#id_notification_list_dashboard").trigger('create');
}
else
{
$("#id_notification_list_dashboard").append("<div style=\"text-align:center\" data-role='list-divider'><h1>No data found</h1></div>").collapsibleset('refresh');
}
$('body').removeClass('ui-loading');
loadingWithMsg("hide");
}
} else {
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_iPad" bundle:nil];
}
navController=[[UINavigationController alloc]initWithRootViewController:self.viewController];
[navController.navigationBar setTranslucent:YES];
navController.navigationBar.tintColor = [UIColor colorWithRed:161.0f/255.0f green:18.0f/255.0f blue:6.0f/255.0f alpha:1];
self.window.rootViewController =navController ;
[self.window makeKeyAndVisible];
return YES;
}
I am having problems to get my Navigation Controller to run properly! If I click in the cell of the table at the RootViewController, it appears not the next ViewController.
Error message reads
“Application tried to push a nil view controller on target
.”
So I alloc something wrong, was my guessing, I probably missing something important from the book I follow.
So the problem appears here in my RootViewController.m:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UINavigationController *navigationController= [[UINavigationController alloc]init];
switch ([indexPath row]) {
case 0:
[navigationController pushViewController:kundeViewCon animated:YES];
break;
case 1:
[navigationController pushViewController:kalenderViewCon animated:YES];
break;
case 2:
[navigationController pushViewController:wunschViewCon animated:YES];
break;
}
}
In my AppDelegate.m I am doing the following things to set a RootViewController as the NavigationController:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
// Navigation Controller
RootViewController *rootViewController = [[RootViewController alloc]init];
navigationController = [[UINavigationController alloc]initWithRootViewController:rootViewController];
self.window.backgroundColor = [UIColor whiteColor];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
So I got all my other ViewControllers that I want to push, when I click in the Cell. I just can not see my fault or what I am missing!?
Maybe someone can help me and give me a hint! That would be great!
RootViewController already has its navigation controller - you created it in the app delegate. Creating a new navigation controller when you select a cell doesn't make sense. It should probably look more like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
switch ([indexPath row]) {
case 0:
[self.navigationController pushViewController:kundeViewCon animated:YES];
break;
case 1:
[self.navigationController pushViewController:kalenderViewCon animated:YES];
break;
case 2:
[self.navigationController pushViewController:wunschViewCon animated:YES];
break;
}
}
Also, just make sure that when you call -pushViewController:animated: the view controller (i.e. kundleViewCon, kalenderViewCon & wunschViewCon) are non-nil. They look like instance variables or properies - just make sure you are alloc/initing them earlier in your code, like in -viewDidLoad.
You don't have to create a new UINavigationController. You need to get you controller from the current window.
[self.navigationController pushViewController:yourController animated:YES];
where yourController is one of your instantiated UIViewController (kundeViewCon, kalenderViewCon or wunschViewCon)
For Googlers:
This may also happen if you did not connect your ViewController to the:
"<Your Project> App Delegate"
If you don't do it then your controller des not get initialized.
You also need to rename the class of the ViewController to the corresponding .h / .m file:
Open the xib file -> select your ViewController -> go to the "Identity Inspector" -> Type in the
Textfield "Class" the name of your corresponding .h/.m files.
Connect your ViewController to the App
By right click and drag from the ...AppDelegate to your ViewController
After releasing click on the corresponding entry:
I'm building an app which's delegate has a UINavigationController (navigationController). The first view is a UITabViewController (tabView) which has a UINavigationController with a UIViewController with a UITableView which shows some contacts.
What I want to do is to push a new viewcontroller with the contact's info when tapping over a contact in the tableview (over the toppest navController)
I do the following in the appDelegate:
[self.window makeKeyAndVisible];
[self.window addSubview:[navigationController view]];
TabsView *tabsView = [[TabsView alloc] initWithNibName:nil bundle:nil];
[navigationController.view addSubview:[tabsView view]];
tabsView's first tab loads ContactsView.m which has a UINavigationController with all contacts and when someone clicks on one row, it is supposed to push the new view as this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[table deselectRowAtIndexPath:indexPath animated:YES];
ContactSecondView * varContactSecondView = [[ContactSecondView alloc] initWithNibName:nil bundle:nil];
varContactSecondView.title = [[contactsArray objectAtIndex:indexPath.row] name];
[self.navigationController pushViewController:varContactSecondView animated:YES];
[varContactMapView release];
}
But nothing happens when touching in a row.
So I have different files: Delegate with UINavigationController <- UITabViewController <- UIViewController with UINavigationController with UITableView; and I want to push a ViewController into the first navigationcontroller.
How is supposed to access to delegate's navigationController? Am I doing it right?
Edit: If this gives any clue, when I do self.navigationController.title = #"Contacts"; in ContactsView.m, it's not changing the title of the topbar.
Thanks!
Two things.
It is not recommended to embed a UITabBarController in a navigation controller. It is ok to embed a UINavigationController within a UITabBarController. I know it would be a "nice to have" to embed your UITabBarController in the UINavigationController, but you may want to rethink your design so that you follow the iOS design philosophy.
Instead of adding the subview to the window in your appDelegate, try adding which ever controller you are using to the window's rootViewController property i.e,
self.window.rootViewController=navigationController;
I may be wrong, but I think you don't use the correct way to set your view controller in your navigation controller.
You do :
[navigationController.view addSubview:[tabsView view]];
I would use :
[navigationController setViewControllers:[NSArray arrayWithObject:tabsView] animated:NO];
I have a
UIViewController-> UINavigationBar + UITableView
Just a bit more explanation
I made it through UIBuilder..
1: Created a New UIViewController with XIB-file
2: Using UIBuiler i put a UINavigationController
3: Then i put UITableView underneath the navigationBar
so it gave me..
A: UIViewController-> UINavigationBar + UITableView
Now i am loading the data in UITableView from a Webservice which is working fine.
I again made a xib with sam config which is
B: UIViewController-> UINavigationBar + UITableView
So now when i try to push view B on view A using below code...it wont at all work...
SelectSiteViewController *siteViewController = [[SelectSiteViewController alloc] initWithNibName:#"SelectSiteViewController" bundle:nil];
[self.navigationController pushViewController:siteViewController animated:YES];
When i checked the UINavigationController *nav = self.navigation
nav is 0x0 that is i assume NIL.
Can anybody tell me whats wrong in here.. why is it nil...and how can i make it work..
Thanks a Lot....I would really appreciate any help
In UIBuilder verify that UINavigationController is referenced by the File's owner.
Got it.
I changed the Architecture a little bit.
I made a New UIViewController class with its xib. And coded new UINavigationController.
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationController *navigationController
navigationController = [[UINavigationController alloc] init];
[self.view addSubview:navigationController.view];
switch (whichViewController) {
case 1:
viewController = [[xxxx alloc] init];
break;
case 2:
viewController = [[xxx1 alloc] init];
break;
default:
break;
}
[navigationController pushViewController:viewController animated:NO];
[viewController release];
}
And pushing the view in the Switch Statement....
I hope this makes sense ......
Thanks jamihash
So you are adding the tableview to the navigation controller right? This is how:
tableView = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
navigationController = [[UINavigationController alloc] init];
[navigationController pushViewController:tableView animated:NO];
The tableview gets added as the rootview to the navigation controller. And then on selecting a row if you wish to push another viewcontroller use the
self.navigationController pushViewController: newViewController animated:YES];
inside the didSelectRowAtIndex method.
NOTE: its UITableViewController *tableView and UINavigationController *navigationController by declaration. So code accordingly for your table.
why UIViewController-> UINavigationBar + UITableView ?
I suggest you another approach
->UITableViewController A -> Embedded with a Navigation Controller, then after populate tableview you can pass data to
->UITableViewController B by
[[self storyboard]instantiateViewControllerWithIdentifier:#"ControllerB"];
then, in storyboard, drop a tableView B and in Identity->storyboard Id put some id.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *sUrl= #"<#string#>";
if (indexPath.row == 0) sUrl= #"http://www.apple.com/";
if (indexPath.row == 1) sUrl= #"http://www.google.com/";
if (indexPath.row == 2) sUrl= #"http://www.times.uk/";
NSMutableArray *selectedObject = [arrayOpenMale objectAtIndex:0];
NSLog(#"%# is the selected object.",selectedObject);
SeriesAdetailVC *dvc = [[self storyboard]instantiateViewControllerWithIdentifier:#"DetailView"];
dvc.strings7 = [NSURL URLWithString:sUrl];
[self.navigationController pushViewController:dvc animated:YES];
}
hope help