I have a Web Service application and it has alogin view. I want to make my application's login view come when the first time app is loaded(installed) and after that it must allways start with a second view. How can i make it? In this link there are some solutions but i think this isn't what i'm looking for. Since mine is a web servise, mean the content of the second view(which i want to be pushed allways) is fetched from a server(i use NSJSONSerialization class for this work)
I would do the login view as a modal view which is only presented when needed.
Edit:
This is VERY brief: (I assume that you are using ARC.)
In AppDelegate:
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController: mySecondViewController];
if (![self isUserLoggedIn]) {
MyLogInViewController *logInViewController = [[MyLogInViewController alloc] init];
[self presentModalViewController: MyLogInViewController animated: YES];
}
[[self window] setRootViewController: [self navigationController]];
and in logInViewController:
- (void)logInSuccessful {
[self dismissModalViewControllerAnimated: YES];
}
Related
I have been trying everything to work this out. I get a notification when the app is closed with 2 custom items, a type and an id. The type is supposed to tell me which view to load, and the id is supposed to tell the app which row to get from the database. I am going through hell trying to figure this out.
I need to click on the notification and have it take me to the relevant record. So far I have been almost successful with two different methods that I'll outline below.
I should also point out that I know the payload is working correctly from APNS as I've debugged it to death :)
The first thing I tried was as follows:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSString *itemType = [[userInfo objectForKey:#"T"] description];
NSString *itemId = [[userInfo objectForKey:#"ID"] description];
self.window=[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// type 1 = call, type 2 = contact
if ([itemType isEqual: #"1"]) {
Leads_CallsDetailViewController *callView = [[Leads_CallsDetailViewController alloc] init];
[callView displayItem:itemId];
[self.window addSubview:callView.view];
[self.window makeKeyAndVisible];
} else if([itemType isEqual: #"2"]) {
Leads_ContactsDetailViewController *contactView = [[Leads_ContactsDetailViewController alloc] init];
[contactView displayItem:itemId];
[self.window addSubview:contactView.view];
[self.window makeKeyAndVisible];
}
}
With this one, I have a method on the detail views called displayItem that I was going to use to get the data from the api and then display it. This did something, but it looked like the view never really loaded. I have a scrollview and various buttons on the page, but all that ever got loaded from addSubview was a background image. Nothing ever really happened to fully load the view. I wasn't sure how to handle that.
The second thing I tried was to go directly to the view like this:
NSString *storyboardId = #"Leads_Calls_SB";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *initViewController = [storyboard instantiateViewControllerWithIdentifier:storyboardId];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = initViewController;
[self.window makeKeyAndVisible];
This one seems to load the view functioning and nice looking with two major caveats. 1. I'm not sure how to pass data to it, and 2. It didn't like it when I tried to pop back and it also got angry when I tried to segue pushes from there, almost as if there was no navigation controller for the view, even though the entire application is embedded in a navigation controller.
Thanks so much for your help. If anyone can help me figure this out I'll be indebted to you.
Normally for this requirement I would do this..
Use NSNotificationCenter and post a notification from didReceiveRemoteNotification.
[[NSNotificationCenter defaultCenter] postNotificationName:#"notificationReceived" object:self userInfo:userInfo];
Subscribe to it from the VC from where you can open your details view to show the message.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(notificationReceived:) name:#"notificationReceived" object:nil];
If you are instantiating the VC yourself and not using segue. you can do this..
UIStoryboard* storyBoard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
detailVC = [storyBoard instantiateViewControllerWithIdentifier:#"detailVC"];
detailVC.delegate = self;
detailVC.userInfo = #"YOUR DATA";
[self presentViewController:detailVC animated:YES completion:nil];
To return you can do this in your detail VC..
[self dismissViewControllerAnimated:YES completion:nil];
I am trying to open a modalview from a view like that,
SignupViewController *signUpView = [[SignupViewController alloc] initWithNibName:#"SignupViewController" bundle:nil];
[signUpView setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
self.parentViewController.view.transform = CGAffineTransformMakeScale(1.3, 1.3);
self.parentViewController.view.alpha = 0;
[UIView animateWithDuration:.35 animations:^{self.parentViewController.view.alpha = 1.0; self.parentViewController.view.transform = CGAffineTransformMakeScale(1, 1);}];
[self presentModalViewController:signUpView animated:YES];
After login i am closing the modalview and redirecting to anther view, but the parentview is still there,
[self dismissViewControllerAnimated:YES completion:^{
ToolsViewController *gototoolpage = [[ToolsViewController alloc] initWithNibName:#"ToolsViewController" bundle:nil];
[self.navigationController pushViewController:gototoolpage animated:YES];
}
How to dismiss the parentview also. Any idea
You code looks a little confused. What do you intend by references to parentViewController? Check the docs - it is the containing viewController, not the previous or presenting viewController. In a NavigationController context this would be the UINavigationController. In a modal view context there is no parentViewController, but there is a presenting ViewController. I am not sure what you intend by all of those calls to self.parentViewController.
In any case you should really be sending the dismiss request back to your presenting viewController via a delegate so that it is completely clear where the pushViewController message is being passed from and to.
In the header file of your signUpViewController declare a protocol:
#protocol SignUpViewControllerDelegate
- (void) dissmissSignUpVC;
#end
then in your presentingViewController, after
SignupViewController *signUpView = [[SignupViewController alloc] initWithNibName:#"SignupViewController" bundle:nil];
add
[signUpView setDelegate:self];
and implement the delegate method with the same code you now have in your completion block:
- (void) dissmissSignUpVC {
ToolsViewController *gototoolpage = [[ToolsViewController alloc]
initWithNibName:#"ToolsViewController" bundle:nil];
[self.navigationController pushViewController:gototoolpage animated:YES];
}
In signUpView invoke the delegate's method to dismiss:
[[self delegate] dissmissSignUpVC];
Watch out for those stacked animations, I suspect that only the first will be performed (i.e. gototollpage animated:YES might as well be gototoolpage animated:NO)
Perhaps anyway you should reconsider your logic. I imagine the user might have a confusing experience if you do this under-the-hood manipulation of viewControllers. Better that there is a UI control for the user to navigate to toolsViewController so they understand where they are?
I am properly pushing viewController B from A using navigationController. However, I would like to do it once uiwebview from viewController B finishes its load and not immediately. I tried firstly init B and push A when load ends but with no success, controller is not viewed. How can it be done? thank you.
from controllerA,
self.controllerB = [[BViewController alloc] initWithNibName:#"BViewController" bundle:nil anUser:self.idUser aLang:self.lang];
//[[self navigationController] pushViewController:controllerB animated:NO]; working if pushed directly here
[self.controllerB view];
then, controllerB is initialized, viewDidLoad triggered and when webviewDidFinishLoad, B must be pushed now or viewed at front.
- (void)webViewDidFinishLoad:(UIWebView*)theWebView
{
AViewController *theInstance = [[AViewController alloc] init];
[theInstance pushBcontroller]; }
on AViewController,
-(void)pushBcontroller{
[[self navigationController] pushViewController:self.controllerB animated:NO];
}
not working...
The line AViewController *theInstance = [[AViewController alloc] init]; creates a new instance of a AViewController. Since it's new it isn't part of the view controller hierarchy and is therefore not connected to the navigation controller.
Give your BViewController a reference to the previous controller and use that instead of creating a different one. Or, perhaps better, send a notification when loading is done that the original AViewController uses to know when to change the display.
I got multiple viewcontrollers in my project. The first viewcontroller is called when the application starts and it presents a login screen. When the credentials are correct and the user logs in, the modalview is dismissed. and another viewcontroller is instantiated like this:
[self dismissModalViewControllerAnimated:NO];
Form *formcontroller = [[Form alloc] init];
[self presentModalViewController:formcontroller animated:YES];
When my other viewcontroller is presented the old one disappears. On the top of my secondviewcontroller i got an logout button, wich does exactly the same, so it dismisses the current viewcontroller and calls another like this:
-(IBAction)logOut:(id)sender{
[self dissmissModalViewControllerAnimated:NO];
}
And in my viewdiddisappear:
-(void)viewDidDisappear:(BOOL)animated{
Postform3ViewController *logincontroller = [[Postform3ViewController alloc] init];
[self presentModalViewController:logincontroller animated:YES];
}
The problem is:
When i push the logout button, and i return back to the logincontroller. The Credentials are still filled in. So my conclusion is that the first viewcontroller stays in memory. What am i doing wrong?
Edit:
I did find my own solution. I was profiling my application, and couldn't find any memory leaks. So i decided everything is released. Then i thought that i was able to set everything to empty myself. I did that in the viewDidAppear method like this:
-(void)viewDidAppear:(BOOL)animated {
gebruikersnaam.text = #"";
wachtwoord.text = #"";
[self.activeTextField resignFirstResponder];
[super viewDidAppear:animated];
}
Well first of all when you are using presentModalViewController and pushViewController the VC is retained so you should always release it after you have presented or pushed it.
Secondly in the third block of code it looks like you are creating a logincontroller but presenting a formcontroller. Perhaps you want to be presenting the VC you had just created:
[self presentModalViewController:logincontroller animated:animated];
Edit 0: For your code, in the first block, release like this:
Form *formcontroller = [[Form alloc] init];
[self presentModalViewController:formcontroller animated:YES];
...
[self dismissModalViewController:formcontroller animated:YES];
[formcontroller release];
How would I make this code animate in the SplashView NIB instead of just making it appear (e.g. the UIModalTransitionStyleFlipHorizontal style)? I am using a UITabBarController type project.
- (IBAction)showSplash:(id)sender {
// Hide toolbar
self.tabBarController.tabBar.hidden = YES;
// Splash
[[NSBundle mainBundle] loadNibNamed: #"SplashView" owner: self options: nil];
[self.view addSubview: splashView];
[window makeKeyAndVisible];
}
Bit hard to tell your context with this small bit of code. Basically, if you want to push a viewController modally, in your -(IBAction)showSplash method (you don't need to send the sender if you're not using it, BTW), I would use some code similar to this:
SplashViewController *svc = [[SplashViewController alloc] init]; (assuming nib is same name)
self.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:svc animated:YES];
[svc release];
Then in your SplashViewController you would have an IBAction that calls:
[self dismissModalViewController animated:YES];
You don't actually have to hide the tabBar when you are presenting a modalViewController. It won't be there. The idea of a modalViewController is that it blocks all user interaction with the app except for the modal view, until it is dealt with.
Hope this helps.