How do I load the initial UIViewController in an iOS app? - ios

I'm new to iOS development, and I know I'm missing something simple but I'm not sure what it is... I have a simple "Hello World" app, and I'm trying to get my initial view controller to load.
Steps taken:
I created an empty project
I added a custom view controller class that extends UIViewController:
#import "WebViewController.h"
#interface WebViewController ()
#end
#implementation WebViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
I added a Storyboard using Apple's wizard.
I added a view controller to that storyboard.
I set my custom controller as the "Custom Class" of that view controller.
I checked the "Is Initial View Controller" checkbox.
But when I run the app, my controller does not load (viewDidLoad is never called). What am I missing?
Sorry about the noob question...

Enlarge the image. Where it says "Main Interface", select the storyboard you want to launch with from this menu. You may to shake Xcode a bit before your storyboard shows up in the list. If it's now showing up, try things like saving the storyboard file as well as cleaning/building your project. Image is borrowed from raywenderlich.com.
In your - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions { method in your app delegate .m file:
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:
#"MainStoryboard" bundle:nil];
UIViewController *initViewController = [storyBoard
instantiateInitialViewController];
[self.window setRootViewController:initViewController];

in storyboard you dont need - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil; As your storyboard the WebViewController is inital view controller so you dont need any thing in appDelegate. The WebViewController will auto call

Related

How to open a UIViewController on a UITableViewCell click?

I want to apply this (https://www.paxxio.in/checkout/onepage/) functionality in my app, I don't have idea that how will I apply this logic. Please see the above url.
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#end
Did not understood your question much though, if you want to open a view controller on tableviewCell click you can use tableview delegate method
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
inside this method you can load the view controller.
Now loading view controller can be done in many ways.
In case you are using story board and segue:
you can simply call
[self performSegueWithIdentifier:#"your segue identifier" sender:your view controller instance (optional)];
If you are using story board n yet not using segue then you can instantiate a view controller from story board identifier
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"your story board" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#" identifier of view controller you want to load"];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];
If you are not using story board then instantiate view controller from xib :)
Happy coding buddy :)

Supporting multiple orientations on a single view controller

I am trying to do a pretty simple thing: support only horizontal orientation in my app, except for 1 stack of view controllers. For simplicity, lets say I have two UIViewControllers. Lets call them maskLandscapeVC and maskAllVC. Each is separately embedded in its own instance of a custom UINavigationController. Here is the code for the navigation controller.
#import "MPTLoginNav.h"
#interface MPTLoginNav ()
#end
#implementation MPTLoginNav
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark
#pragma Interface Orientaiton Methods
- (NSUInteger)supportedInterfaceOrientations
{
if (self.isMaskAllStack)
return UIInterfaceOrientationMaskAll;
return UIInterfaceOrientationMaskLandscape;
}
- (BOOL)shouldAutorotate
{
return YES;
}
#end
On maskLandscapeVC, this code works fine and only the two horizontal orientations can be used.
Users can navigate from maskLandscapeVC to maskAllVC. The following code takes care of that
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Storyboard" bundle:[NSBundle bundleForClass:[self class]]];
self.maskAllVC = [storyboard instantiateViewControllerWithIdentifier:#"maskAllVC"];
[self.navigationController pushViewController:self.maskAllVC animated:YES];
At maskAllVC, the code also works great and all four orientations are supported.
Once on maskAllVC, the user switches to VERTICAL orientation. maskLandscapeVC is a delegate of maskAllVC. While in the vertical orientation on maskAllVC, the user presses some button. The button does a call to the delegate (maskLandscapeVC), based on some conditions, maskLandscapeVC decides to dismiss maskAllVC. It uses the following code
[self.maskAllVC.navigationController popViewControllerAnimated:YES];
[self.maskAllVC.navigationController dismissViewControllerAnimated:YES completion:nil];
Now back on maskLandscapeVC, the orientation is still vertical and of course my view is completely messed up because of it.
I think because you pop it to go back it doesn't really refresh the whole ViewController like it does the first time. Using viewDidLoad instead of viewWillAppear might be the problem. viewDidLoad is only called once.
Do you do a complete layoutSubview refresh if you set breakpoints? Does it call into supportedInterfaceOrientations at all when you pop? What happens if you move your viewDidLoad code to viewWillAppear?

pushViewController does nothing when I call it

I'm trying to get my app to go to the next screen. I eneded up creating a simple test app with 2 screens
On the first vue I have a button connected to the following code to call up the next screen
- (IBAction)atest:(id)sender {
if (mHome == nil)
mHome = [[cHome alloc] initWithNibName:#"cHome" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:mHome animated:YES];
}
I put a break point to make sure the code exicutes, it does but..... the next screen does not come up.
complete code
#import <UIKit/UIKit.h>
#interface cHome : UIViewController{
}
- (IBAction)atest:(id)sender;
#end
#interface cHome ()
#end
#implementation cHome
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (IBAction)atest:(id)sender
{
[self.navigationController popToRootViewControllerAnimated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
Just like to add onto Unkn0wn and demonstrate how I presented certain views in an app.
Add a storyboard id for your view controller
click on your view controller in your storyboard hierarchy
click the identity inspector
add a storyboard id as a string in the storyboard id box
I then did something like this in my code:
[self presentViewController:[self.storyboard nstantiateViewControllerWithIdentifier:#"Paint"] animated:NO completion:nil];
obviously, your identifier would not be "Paint" but that's what I used. This was my simplist approach, hope it helps good luck!
NOTE: I did not use navigation controllers in my app.
EDIT
would like to point out, that this method kind of makes the controller appear out of nowhere with no animation (I had special animation for my controls as a transition between view controllers so I didn't need to animate the controller itself)
If you want to push a view controller, you can easily create a push segue, from your first view controller to your second view controller, and then push using
[self performSegueWithIdentifier:#"yourSegueIdentifier" sender:self];
"push segues" can be created both via code or in your storyboard file.
You have a mistake in your code:
mHome = [[cHome alloc] initWithNibName:#"cHome" bundle:[NSBundle mainBundle]];
I think it's the nib name. It should be mHome not cHome.
mHome = [[cHome alloc] initWithNibName:#"mHome" bundle:[NSBundle mainBundle]];
You basically cannot push two of the same view controller on one navigation controller.

JASidePanels Black box

Please see the image below. Keep in mind I am using xcode 4.5.2 as well. I followed the example on JASidePanels from github Example #2 and I can't seem to get rid of this black box! Otherwise the SidePanel actually works as expected. =)
image of problem
My centerViewController and leftViewController also look the same (code below). But when I tried to do it like the example said to do it, I wasn't having any such luck, so I had to subclass the JASidePanelController:
centerViewController.h:
#import "JASidePanelController.h"
#interface centerViewController : JASidePanelController
#end
centerViewController.m
#import "centerViewController.h"
#interface centerViewController ()
#end
#implementation centerViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Could I very well be missing something? I have commented out a few lines of code to remove the rightViewController on the main JASidePanelController itself, thinking that could be causing a problem and it just caused more issues. I don't have the code for the rightViewController from the example as I am just using the left and center. So I set the code back into its defaults and I am left with a black box over the app in my simulator.
Thanks in advance!
Don't inherit from JASidePanelController for your center view controller. Think of a JASidePanelController as a container view that can hold 3 view controllers. Here is an example from my AppDelegate one of my projects:
self.panelController = [[JASidePanelController alloc] init];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *centerViewController = [storyboard instantiateInitialViewController];
self.panelController.centerPanel = centerViewController;
self.panelController.delegate = centerViewController;
self.panelController.rightPanel = [[DBRightViewController alloc] init];
self.panelController.leftPanel = [[DBLeftViewController alloc] init];
Think of it this way, you need a single JASidePanelViewController, which will hold your other view controllers. This can be a subclass of JASidePanelViewController, but it is probably not needed so long as you store the reference to it somewhere. In my example I store the panelController as a property in my AppDelegate.
Then, each of your viewcontrollers will be subclasses of UIViewController.

Xcode 4 for Dummies: Why are Storyboard Settings not Being Applied When the App Runs?

SOLUTION
Make sure in the plist that the storyboard name is listed as the main storyboard file name.
I have a Storyboard with a UINavigationViewController that's connected to a NavigationViewController class and it's set as the UIWindow rootViewController. When the app runs (in the Simulator (5.1)) I get a blank black screen with the blue-ish navigation bar on the top.
The first problem is that in the storyboard, I set the navigation bar to black. I also set the status bar to translucent black. Neither styles are being honored when the app runs.
And the second problem is that the navigation controller's view is empty even though in the storyboard it has a relationship to a UITableViewController.
How can I fix both of these issues. I just started using Xcode again and had been using 4.0 before so the storyboards are throwing me off...
UPDATE
Here's the code as requested. Obviously I can't post the storyboard (can I?).
AppDelegate:
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize window = _window;
#synthesize navigationController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
navigationController = [[NavigationViewController alloc] init];
self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
- (void)applicationWillTerminate:(UIApplication *)application {
}
#end
NavigationViewController:
#import "NavigationViewController.h"
#interface NavigationViewController ()
#end
#implementation NavigationViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
The problem is that you are setting as the root controller a completely blank root controller, not the one from the story board. What you want to do is to delete that part of the code, and simply on the storyboard click the thing that says "is initial view controller"
When using storyboards you usually dont have to modify the appdelegate, because xcode sets which is the initial view that will appear and all of that based solely on how you set the storyboard. You can check this in the plist where it says which storyboard will be used as the main one.
If you want to load your navigation controller like that then you can do something like that you would have to get the viewcontroller from the storyboard itself and present it.
instantiateViewControllerWithIdentifier
but there is no need for that when using storyboards as it automatically loads whichever is set as the initial one (which can be seen as the viewcontroller with the arrow pointing at it)
Your app delegate method should look like this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
return YES;
}

Resources