Call View controller within Master-Detail template - ios

I'm having trouble calling a newly created view controller within the storyboard. I have created an app using the default master-detail template. The only simple thing I'd like to do is call a new View Controller window when a specific check is valid/invalid (depending on requirement) (I refuse to use the term "Login" :-) ).
What is the best location to do this? In here (appDelegate)?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
splitViewController.delegate = (id)navigationController.topViewController;
UINavigationController *masterNavigationController = splitViewController.viewControllers[0];
MasterViewController *controller = (MasterViewController *)masterNavigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
} else {
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
MasterViewController *controller = (MasterViewController *)navigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
}
//Should I call the new view controller object from my storyboard at this location? (i.e. myView)
return YES;
}
I'm even considering starting all over without using the template of Xcode.

Do you need to use different controllers depending on check result?
If yes than there are few suggestions. You can cover your view with some activity view which covers all screen, wait for checking and than remove activity view.
Another thing you can try is making another view controller in storyboard and move starting arrow to it. You can try to login and after it perform correct segue.
And at least i can suggest to create root view controller programmatically.
something like this.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
levelViewController = [[LevelViewController alloc] init];
window.rootViewController = levelViewController;
[window makeKeyAndVisible];
}

Related

Setting UINavigationController (from storyboard) as rootViewController in AppDelegate.m

I'm using parse and I'm trying to get the login screen to show if the user isn't the "current" user. I'm having issues with my NavigationController (from my storyboard) and using it as the rootViewController even though it's already set as initial View Controller in my storyboard. Using this line of code I select the NavigationController (from my storyboard) and initialize it in my app delegate.
UINavigationController *navVC = (UINavigationController *)self.window.rootViewController;
I then decide whether or not to display the loginVC then finally I set the NavigationController as the rootViewController here:
self.window.rootViewController = navVC; [self.window makeKeyAndVisible];
Except someone I don't. I get this error when I try to build my app. "Application windows are expected to have a root view controller at the end of application launch" Anyone have any ideas what's going wrong?
Here's the code all together.
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
UINavigationController *navVC = (UINavigationController *)self.window.rootViewController;
// Initialize Parse.
[User registerSubclass];
[Question registerSubclass];
[Parse setApplicationId:#"HI"
clientKey:#"HI"];
// Determine whether or not to show the login screen
if (![PFUser currentUser]) {
LogInViewController *loginVC = [[LogInViewController alloc] init];
[navVC setViewControllers:#[loginVC] animated:YES];
} else {
QuestionsTableViewController *questionsVC = [[QuestionsTableViewController alloc] init];
[navVC setViewControllers:#[questionsVC] animated:YES];
}
self.window.rootViewController = navVC; [self.window makeKeyAndVisible];
return YES;
}
If you're starting with a storyboard you need to have it set as your Main Interface in the Deployment Info in your app's General settings. You should also remove the line:
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
..as it's initialising a new window in the place of the one created from the previous step.
I used these two lines of code to fix the issue. I got answer from here:
Programmatically set the initial view controller using Storyboards
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UINavigationController *navVC = [storyboard instantiateViewControllerWithIdentifier:#"QuestionsView"];
I removed this line:
UINavigationController *navVC = (UINavigationController *)self.window.rootViewController;
There don't get the error anymore.

UISplitViewController: Does not show up when setting it up pragmatically

I am trying to setup a splitviewcontroller using storyboards. The code below is what I have so far. However, it is showing a black screen. I have a storyboard name Main. I have two viewcontrollers in the storyboard. I read how to do this from an article, but can't get it to work. I must be missing something small. Any help is appreciated.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Main"
bundle:nil];
ViewController *firstVC = [sb instantiateViewControllerWithIdentifier:#"ViewController"];
ViewController1 *secondVC = [sb instantiateViewControllerWithIdentifier:#"ViewController1"];
CGRect frameFirstVC = firstVC.view.frame;
frameFirstVC.size.width = 100;
CGRect frameSecondVC = secondVC.view.frame;
frameSecondVC.size.width = 100;
UISplitViewController* splitVC = [[UISplitViewController alloc] init];
splitVC.viewControllers = [NSArray arrayWithObjects:firstVC, secondVC, nil];
[self.window addSubview:splitVC.view];
[self.window makeKeyAndVisible];
return YES; }
You shouldn't add the split view controller's view as a subview of your window directly. Instead, set the window's rootViewController property:
self.window.rootViewController = splitVC;
In addition to configuring the view hierarchy, this sets up additional state and layout information for the app to properly display and use the split view controller.
(I should point out that instead of writing any of this code, you could put the split view controller in your storyboard, mark it the initial view controller, then use that storyboard as your app's main interface file. That's a bit of a bigger change, though.)

Switch between different Views with a Navigation Controller

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;
}

UISplitViewController and CoreData

I am working on a project that uses CoreData one-to-many relationship between folder and files. To show this I am using UISplitViewController, Folders are shown on MasterView and on click of each folder the files are shown on DetailView.Both folders and files are added dynamically.
I have programatically created UISPlitViewController this way
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
FolderViewController = [[FolderViewController alloc] initWithNibName:#"FolderViewController_iPad" bundle:nil];
UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:FolderViewController];
FolderViewController.managedObjectContext = self.managedObjectContext;
fileViewController = [[fileViewController alloc] initWithNibName:#"fileViewController_iPad" bundle:nil];
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController: fileViewController];
FolderViewController.fileViewController = fileViewController;
self.splitViewController = [[UISplitViewController alloc]init];
self.splitViewController.delegate = fileViewController;
self.splitViewController.viewControllers = #[masterNavigationController, detailNavigationController];
self.window.rootViewController = self.splitViewController;
}
This splits my ipad in to two. Leftside is FolderViewController and rightside is FileViewController.
My master View never hides, in any Orientation.
I have a button on both Master and DetailView which opens common EditViewController modally through splitViewController this way
- (void)Buttonclick
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
testViewController = [[EditViewController alloc] initWithNibName:#"EditViewController" bundle:nil];
m_editViewController.modalPresentationStyle = UIModalPresentationFormSheet;
[appDelegate.splitViewController presentModalViewController:m_editViewController animated:YES];
}
and when I dismiss this View, I add folders or files accordingly.
I dismiss this view this way
[self dismissModalViewControllerAnimated:YES];
I have few doubts here
1) When I launch the app, all imp(main) functions from Both View Controller gets called.is that ok?
2) When I dismiss this ModalView when opened from DetailView, the delegate functions of NSFetchResultsController get called, which are in MasterView . is that ok?
3) As those functions are getting called, my logic fails in some situations.
Regards
Ranjit

SimpleDrillDown example with TabBarController

I have been experimenting with the SimpleDrillDown example from Apple and attempted to put it into a tab bar. The problem is the view now doesn't show, and I know it is the following code in the App Delegate that is causing it. I am struggling with changing it to fit with the tabbar and would appreciate some pointers.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Create the data controller and pass it to the root view controller.
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
RootViewController *rootViewController = (RootViewController *)[[navigationController viewControllers]objectAtIndex:0];
DataController *controller = [[DataController alloc] init];
rootViewController.dataController = controller;
self.dataController = controller;
}
I have replaced it with the following but this line EatCatTVC *rootViewController = (RootViewController *)[[navigationController viewControllers]objectAtIndex:0]; throws an error
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UITabBarController *tabBar = (UITabBarController *)self.window.rootViewController;
// Create the data controller and pass it to the root view controller.
EatCatTVC *rootViewController = (RootViewController *)[[navigationController viewControllers]objectAtIndex:0];
DataController *controller = [[DataController alloc] init];
rootViewController.dataController = controller;
self.dataController = controller;
return YES;
}
Your code is failing because you are accessing non-existent object
EatCatTVC *rootViewController = (RootViewController *)[[navigationController viewControllers]objectAtIndex:0];
on this line navigationController doesn't exist in your "modified" version.
Make sure that "rootController" is set to UITabBarController class (I assume that you did setup this in Interface Builder).
And then use setViewControllers:animated: to provide the UITabBarController' instance with (for instance)UIViewController` instances that are meant to be present.

Resources