sorry if this is kind of a duplicate question but I have looked at many questions and haven't found the right answer.
Basically if the app is on first launch, a UIViewController with a How To screen should be loaded. If it is not first launch, it loads a Tab Bar Controller.
To do this, I have a UIViewController as the initial view controller, and then modal segues to the tab bar and uiviewcontroller
The two modal segues are called pushTabBar and pushHowToUse.
Here is the code for "firstviewcontroller"
#implementation FirstViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self isFirstRun];
// Do any additional setup after loading the view.
}
- (BOOL) isFirstRun
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"isFirstRun"])
{
[self performSegueWithIdentifier: #"pushTabBar" sender: self];
return NO;
}
[defaults setObject:[NSDate date] forKey:#"isFirstRun"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"right before");
[self performSegueWithIdentifier: #"pushHowToUse" sender: self];
return YES;
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"pushTabBar"]) {
GetInfoViewController *getInfoViewController = segue.destinationViewController;
NSLog(#"loadtabbar");
}
if ([segue.identifier isEqualToString:#"pushHowToUse"]) {
TutorialViewController *tutorialViewController = segue.destinationViewController;
NSLog(#"loadhowto");
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I am not sure what to push/load for the tab bar controller:
GetInfoViewController *getInfoViewController = segue.destinationViewController;
is the viewcontroller for the first tab bar I want to load.
Am I doing this correctly? Should I be using a navigation root controller?
Thanks in advance
There's no need for the FirstViewController if its only purpose is to decide which other controller to present (BTW, calling a modal segue pushToTabBar is a confusing name -- you're doing a presentation not a push). You can do the logic in the viewDidAppear method of the controller in the first tab of the tab bar controller. If it's the first launch, present the TutorialViewController modally with no animation so it will be the first thing the user sees. When the user is done with the tutorial, dismiss that controller, and you be back to that first tab view controller. You should hookup a segue from that controller at index 0 of the tab bar controller to the TutorialViewController.
You're better off doing the segue from the Tab Bar controller. That way, you can just dismiss the modal presentation and when the tutorial segue goes away, you're already at the tab bar.
Related
i created three scenes, each of them has a button and a label as shown in image-1. Scene1 is linked to Scene2 through "Show Segue called scene1To2"
,Scene2 is linked to scene3 through "Show Segue called scene2To3" and finally Scene3 is linked to scene1 through "Show Segue called scene3To1".
I am trying to to call "prepareForSegue" when the button in scene1 is clicked, so I wrote the code shown in code1 section below..
but when i run the code the NSLog message "NSLog(#"transiting from scene1To2");" does not show up
please let me know why the NSLog message doesn't show
code1:
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a
//nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)from1To2:(id)sender {
NSLog(#"Hi");
[self performSegueWithIdentifier:#"scene1To2" sender:self];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue
{
if ([segue.identifier isEqualToString:#"scene1To2"])
{
NSLog(#"transiting from scene1To2");
}
}
#end
Your method signature is wrong. See if this does the trick:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"scene1To2"])
{
NSLog(#"transiting from scene1To2");
}
}
In your Segue links on the storyboard have you added the segue name to the segue identifier?
You can use something like this, you import the scene1To2 controller.
scene1To2 *view = [[UIStoryboard storyboardWithName:#"YOUR_STORYBOARD" bundle:nil] instantiateViewControllerWithIdentifier:#"scene1To2"];
[self presentViewController:view animated:YES completion:nil];
then you go to the other view controller
I'm currently working on a project that is tab bar based and out of my four tabs three display just table data or images. My problem is stemming from trying to use a tab to display a PDF file with vfr. I can click the tab when the program first loads and everything appears to be working as it should. When I click done the Reader view controller is dismissed but the underlying controller is still sitting there empty. Since the view is still in place clicking back and forth through my tabs never allows vfr to reload its view since viewDidLoad is whats I'm using to call it. How do I dismiss the underlying controller? Or is there a better method to call vfr in a story board tab based app?
my controller code that calls vfr
#implementation testViewController
- (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.
NSString *file = [[NSBundle mainBundle] pathForResource:#"emsformulary" ofType:#"pdf"];
ReaderDocument *document = [ReaderDocument withDocumentFilePath:file password:nil];
if (document != nil) {
ReaderViewController *readerViewController =[[ReaderViewController alloc] initWithReaderDocument:document];
readerViewController.delegate = self;
readerViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
readerViewController.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:readerViewController animated:YES completion:nil];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)dismissReaderViewController:(ReaderViewController *)viewController
{
[self dismissViewControllerAnimated:NO completion:nil];
}
#end
dismissReaderViewController is called by the done button in vfr. Once called vfr pdf view is gone but a blank view remains.
Figured it out, I was calling my controller code with viewDidLoad. Once I dismissed it, it was never called again. Moving the code to viewWillAppear fixed my controller presentation issue. As for the not dismissing the underlying view, I found the method to call a view by its tabbarcontroller array index when I pressed the done button inside vfr.
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.
I am pretty new to iOS. I have a UIViewController with an embedded UINavigationController and I am hiding the bar on the first View by adding this code to the viewDidLoad method:
if (self) {
self.navigationController.navigationBarHidden = YES;
self.navigationItem.title = #"";
}
Then I connected this View to another UIViewController with a seque (triggered by a button on the first View) and added this code to it's viewDidLoad method:
if (self) self.navigationController.navigationBarHidden = NO;
Everything works fine at first. When I load the app the navbar is gone, when I navigate to the second (child) view, the bar is there. Then when I hit the back button, it goes back to the first (parent) view but the NavBar is back.
I tried adding naming the seque "BackToMain" and adding a prepareSeque method which I placed in the second view:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"BackToMain"]) {
UINavigationController *parentNavigationController = segue.destinationViewController;
parentNavigationController.navigationController.navigationBarHidden = YES;
}
}
But it never gets called.
Ideally I would put a method in the parent view to simply hide the NavBar every time it gets displayed. Something like:
- (void)processIncomingSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if (self) self.navigationController.navigationBarHidden = NO;
}
But I really don't know if that is possible.
Put the following code in your view controller which should not have a UINavigationBar.
- (void)viewWillAppear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:YES animated:animated];
[super viewWillAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:NO animated:animated];
[super viewWillDisappear:animated];
}
I have a storyboard with a UINavigationController. The root view controller of the navigation controllers is called rootViewController.
I am trying to programmatically change the view controller (depending on other conditions) to another view controller called loginViewController.
I am trying to do this in the viewDidLoad from the rootViewController like this:
- (void)viewDidLoad
{
[super viewDidLoad];
loginViewController *viewController = [[loginViewController alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
}
I am not getting any errors but it's not working.
It just loads the navigation controller with the top nav back button but the rest of the screen is black. It's like it's not loading any view controller.
I am trying to figure out what I am doing wrong.
Any help with this would be great.
Thanks
First add loginViewController class in storyboard and and connect ViewController class to loginViewController class and give identifier name as "identifier_Name".
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSegueWithIdentifier:#"identifier_Name" sender:nil];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier] isEqualToString:#"identifier_Name"])
{
loginViewController *viewController = [segue destinationViewController];
}
}
If you're using storyboard, create your login view in the storyboard, link your rootVC to the loginVC with a segue, choose an identifier (for example: "goToLogin"). and then to go in the login view, and use:
[self performSegueWithIdentifier:#"goToLogin" sender:self];