I want to show a video at the beginning of the application start, just like a splash. My whole app will be in Navigation. First, i add the video in a splashViewController and set it in appDelegate as rootView and then simply set the mainViewController as rootView again.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
splashViewController = [[SplashViewController alloc] init];
splashViewController = (SplashViewController *)[mainStoryboard instantiateViewControllerWithIdentifier:#"SplashViewController"];
self.window.rootViewController = splashViewController;
[NSTimer scheduledTimerWithTimeInterval:9.0 target:self selector:#selector(removeSplashScreen:) userInfo:nil repeats:NO];
return YES;
}
-(void)removeSplashScreen:(id)userInfo
{
[splashViewController removeFromParentViewController];
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
mainViewController = [[MainViewController alloc] init];
mainViewController = (MainViewController *)[mainStoryboard instantiateViewControllerWithIdentifier:#"MainViewController"];
self.window.rootViewController = mainViewController;
}
Now i want to start navigation from this mainViewController. I use storyBoard & add navigation from Editor > Embed in > Navigation Controller in mainViewController. Don't do it programmatically. But i know the way of implementing it using Nib.xib. Here i also put the arrow(The arrow which indicate the starting VC) mark besides of it. But it getting crash when i click a button from mainVC to go next VC. How can i set the navigation here?
If any one have the answer, please share with me. Thanks a lot in Advance.
The scenario of my storyboard:
happy to help you here in two steps
step 1-
your didFinishLaunchingWithOptions code is almost correct , but it does not matter if its working . so let focus on step two.
step 2- in -(void)removeSplashScreen:(id)userInfo
-first line is good , but you even dont need it because you are going to switch the root controller (leave it for now)
- second line (no need to write it)
- third line is really bad , what you doing here is trying to alloc you mainviewcontroller. really you need it with storyboard? no
- you should load you main view controller from storyboard
MainViewController* mainViewController = (MainViewController *)[mainStoryboard instantiateViewControllerWithIdentifier:#"MainViewController"];
"this line is enough to load your main view controller from storyboard"
-next line is correct
self.window.rootViewController = mainViewController;
code seems to be working now , but still you are missing navigation controller because you have loaded mainviewcontroller from storyboard, not the navigation controller.
- two solution for it
1- load navigation controller in place of mainviewcontroller(give a storyboard id to navigation controller , load it , and make it as root controller) --i will always go with it
2- make a navigation controller with allocating it & make its rootviewcontroller the mainviewcontroller
-----------------working code ---------------
Ok Despite my advice (in the comments), here is how you can achieve this:
Display splash:
//StoryBoard
UIStoryboard *mainStoryboard = [UIStoryboard
storyboardWithName:#"Main" bundle: nil];
//Splash Controller
SplashViewController *splashViewController = [mainStoryboard
instantiateViewControllerWithIdentifier:#"SplashViewController"];
//Show it
[self.window.rootViewController presentViewController:splashViewController
animated:NO completion:nil];
Remove it:
[self dismissViewControllerAnimated:YES completion:nil];
EDIT: Still not working?
Maybe you called it to quick. do this:
viewDidLoad:
[NSTimer scheduledTimerWithTimeInterval:9.0
target:self
selector:#selector(removeSplashScreen:)
userInfo:nil repeats:NO];
function to remove:
-(void)removeSplashScreen:(id)userInfo
{
[self dismissViewControllerAnimated:YES completion:nil];
}
So the solution, according to pawan's given answer is :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
splashViewController = (SplashViewController *)[mainStoryboard instantiateViewControllerWithIdentifier:#"SplashViewController"];
self.window.rootViewController = splashViewController;
[NSTimer scheduledTimerWithTimeInterval:9.0 target:self selector:#selector(removeSplashScreen:) userInfo:nil repeats:NO];
return YES;
}
-(void)removeSplashScreen:(id)userInfo
{
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
mainViewController = [[MainViewController alloc] init];
mainViewController = (MainViewController *)[mainStoryboard instantiateViewControllerWithIdentifier:#"MainViewController"];
navigationContoller = [[UINavigationController alloc] initWithRootViewController:mainViewController];
self.window.rootViewController = navigationContoller;
}
:)
Related
i'm trying to present a UITableViewController when a collectionViewCell is tapped. i've done this by using the didSelectItemAtIndexPath. When i press a collectionView Nothing happens and after i've pressed the UI is blocked and i cant do anything. No errors/log messages are shown. Why wont it present the viewController and why no error messages?
UITableViewController interfaceBuilder:
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
HomeProfileViewController *hpvc = [storyboard instantiateViewControllerWithIdentifier:#"NavProfile"];
hpvc.idString= [[homesDic objectAtIndex:indexPath.item] objectForKey:#"idString"];
hpvc.imageArray = [[NSMutableArray alloc]init];
hpvc.imageArray = [imageDic objectAtIndex:indexPath.item];
[self presentViewController:hpvc animated:YES completion:nil];
}
My best guess is that storyBoard is taking time to load. Maintain an instance level storyBoard object and do a lazy instantiation at didSelectItemAtIndexPath.
Lazy instantiation code:
- (UIStoryboard *)storyboard: {
if (!_storyboard) {
_storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
}
return _storyboard;
}
And in your didSelectItemAtIndexPath,
UIStoryboard *storyboard = [self storyboard];
Again, this is my best guess. It is only deduced from the given code.
I am trying to complete an application on IOS 5.1 with Storyboard. Basically I am doing a dropbox app. Since I am using Dropbox SDK link to Dropbox is handled in AppDelegate.m. User has the option of be able to unlink from a session and link again in different View Controllers. So every time user link and unlinked app has to switch view from Appdelegate to a view controller that is unconnected to rootviewcontroller
In original Dropbox's example Dropbox handled transition like following code
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
if ([[DBSession sharedSession] handleOpenURL:url]) {
if ([[DBSession sharedSession] isLinked]) {
[navigationController pushViewController:rootViewController.photoViewController animated:YES];
}
return YES;
}
return NO;
}
But I am using Storyboard with Navigation Controller and any of the following methods are not working I put methods in comments.
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
if ([[DBSession sharedSession] handleOpenURL:url]) {
if ([[DBSession sharedSession] isLinked]) {
NSLog(#"App linked successfully!");
// At this point you can start making API calls
/*UIViewController *viewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:NULL] instantiateViewControllerWithIdentifier:#"MeetingViewController"];
[self.navigationController pushViewController:viewController animated:YES]; */
//[self performSegueWithIdentifier:#"xxxx" sender:self];
/* LoginDropboxViewController *loginController=[[LoginDropboxViewController alloc] initWithNibName:#"LoginDropbox" bundle:nil];
[navigationController pushViewController:loginController animated:YES]; */
}
return YES;
}
// Add whatever other url handling code your app requires here
return NO;
}
Here is the storyboard of the app
So how can I switch view in AppDelegate.h ?
Note: If I add a segue and name the segue lets say goToMeeting
[self performSegueWithIdentifier:#"goToMeeting" sender:self];
error I get is : No Visible #interface for 'AppDelegate' declares the selector performSegueWithIdentifier:sender
If you consider pushing view manually rather then segueperform following code most probably will work for you
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
if ([[DBSession sharedSession] handleOpenURL:url]) {
if ([[DBSession sharedSession] isLinked]) {
NSLog(#"App linked successfully!");
// At this point you can start making API calls
//push view manually
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
LoginDropboxViewController *ivc = [storyboard instantiateViewControllerWithIdentifier:#"LoginDropbox"];
[(UINavigationController*)self.window.rootViewController pushViewController:ivc animated:NO];
}
return YES;
}
// Add whatever other url handling code your app requires here
return NO;
}
You can do it like this:
UINavigationController *navigationController = (UINavigationController*) self.window.rootViewController;
[[[navigationController viewControllers] objectAtIndex:0] performSegueWithIdentifier:#"goToMeeting" sender:self];
This will only work if the index in viewControllers array matches the one of your view controller and if it exists of course. In this case is the first one (in the array and storyboard).
The segue ("goToMeeting") must not be attached to an action. The way you do this is by control-dragging from the file owner icon at the bottom of the storyboard scene to the destination scene. A popup will appear that will ask for an option in “Manual Segue”; pick “Push” as the type. Tap on the little square and make sure you’re in the Attributes Inspector. Give it an identifier which you will use to refer to it in code.
In my case i need to go to dashboard screen from appdelegate using segue, the code as below in objective c.
if([rememberMe isEqualToString:#"YES"]){
//Goto Dashboard
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
SWRevealViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"revealVc"];
self.window.rootViewController = vc;
[self.window.rootViewController performSegueWithIdentifier:#"sw_front" sender:self];
[self.window makeKeyAndVisible];
}else{
//Goto login
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
LoginViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"LoginViewController"];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
}
Write inside your didFinishLaunchingWithOptions
Hope it helps some one.
I am working on a small app, according to the requirement the app should have a tabBarItem with 3 items. For this I have programmatically created the tabBarController in the AppDelegate.m file and added the 3 different viewControllers, instantiated them and everything is working good. I see the tabBarItems and all views are working. In one of the views lets say in SecondViewController I show a popOverController where I used a UITableView and populate it with items. When I click one of the items it should show another view lets say sendFeedback. Until there everything is working fine, but as soon as this sendFeedback is presented as the modal view, it occupies the whole app i.e it hides the tabBarItem.
I present the important pieces of code here for review:
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
viewController1.title = #"First";
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
viewController2.title = #"Second";
UITableViewController *tableView3 = [[tableViewController alloc]initWithNibName:#"tableViewController" bundle:nil];
tableView3.title = #"Third";
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, tableView3 ,nil];
self.tabBarController.delegate = self;
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
[viewController1 release];
[viewController2 release];
[tableView3 release];
return YES;
}
In my popOverViewController.m file I am checking which row is selected in the table according to that I present the view
#pragma mark - TableView Delegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
sendFeedback *sendEmailViewController = [[sendFeedback alloc]initWithNibName:#"sendFeedback" bundle:nil];
downLoad *downloadFilelViewController = [[downLoad alloc]initWithNibName:#"downLoad" bundle:nil];
if (indexPath.row == 0)
[self presentModalViewController:sendEmailViewController animated:YES];
else
[self presentModalViewController:downloadFilelViewController animated:YES];
}
Can anyone guide me how to overcome this with the multiple views. In case if anyone requires more information from my side I would be glad to provide.
NOTE: It is the same with the other view (downLoad) as well
EDIT: Here is how I am initializing my PopOverController in the AppDelegate.m file
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
if([viewController isKindOfClass:[SecondViewController class]]){
NSInteger index = [[self tabBarController] selectedIndex];
CGRect buttonFrame = [[[[[self tabBarController] tabBar] subviews] objectAtIndex:index+1] frame];
PopOverViewController *popoverView = [PopOverViewController new];
popoverView.contentSizeForViewInPopover = CGSizeMake(250, 85);
popover = [[UIPopoverController alloc]initWithContentViewController:popoverView];
NSLog(#"X:%f Y:%f",buttonFrame.origin.x,buttonFrame.origin.y);
[popover presentPopoverFromRect:buttonFrame inView:self.tabBarController.tabBar permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
}
Thanks
Modal view controllers are used to "block" your application and fulfill a task before you can proceed. So modal view controllers are not what you want to use.
Instead wrap your controllers which have to be shown in the popover in a navigation controller. In the tableView:didSelectRowAtIndexPath: method you can push the corresponding view controller to the navigation stack.
To slove your problem:
At the place where you create the popovercontroller initialize it with a new UINavigationController. And the navigation controller you have to initialize with a rootviewcontroller namely PopOverViewController.m.
PopOverController *popoverContentController = [[PopOverController alloc] init];
UINavigationController *navcon = [[UINavigationController alloc] initWithRootViewController:popoverContentController];
popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContentController];
And in PopOverController.m
if (indexPath.row == 0)
[self.navigationController pushViewController:sendEmailViewController animated:YES];
else
[self.navigationController pushViewController:downloadFilelViewController animated:YES];
I started a project in Xcode 4.2 using tab view template. In the app delegate I added a third tab by code just like first and second tabs. Then I created a third view controller class with a nib file.
When I run this app, I see all three tabs but when I click on the third tab, it crashes.
I noticed the first and second nib files have a dark bar at the bottom(probably representing the tab bar) of the view but the new third nib file that I created lacks it. Any idea how I make this third tab work?
Thanks
This is how I add the third view controller.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UIViewController *viewController1, *viewController2, *viewController3;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController_iPhone" bundle:nil];
viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController_iPhone" bundle:nil];
viewController3 = [[ThirdViewController alloc] initWithNibName:#"ThirdViewController_iPhone" bundle:nil];
} else {
viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController_iPad" bundle:nil];
viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController_iPad" bundle:nil];
}
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, viewController3, nil];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
In the tab bar controller make sure the class of the view controller for the tab is the same as the view controller class you created.
Also check the logs, it will probably have a very informative message for you as to why it crashed.
Edit:
Never mind, you are passing in an un-initialized view controller for viewController3. Set all of those initial values to nil.
I created a new window based application, and a RootViewController that sublcasses UIViewController. I created a UINavigationController in the AppDelegate and when I add the UINavigationController's view to the window, I do see the navigation bar on top. However, I cannot seem to add a button to the navigation bar - there are no compile errors, but the button (and the title) does not show up. The code is below:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
RootViewController * rootViewController = [[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
UIBarButtonItem *next = [[UIBarButtonItem alloc] initWithTitle:#"Next" style:UIBarButtonItemStyleDone target:nil action:nil];
navigationController.title = #"Foo";
navigationController.navigationItem.rightBarButtonItem = next;
[self.window addSubview:navigationController.view];
// Override point for customization after application launch.
[self.window makeKeyAndVisible];
return YES;
}
What am I doing wrong?
Change this:
navigationController.navigationItem.rightBarButtonItem = next;
to this:
rootViewController.navigationItem.rightBarButtonItem = next;
May be style:UIBarButtonItemStyleDone only used in editing mode is YES. If in Root controller or sub view controller, you may try call self.editing = YES, but in AppDelegate you can't.