I have been working on this problem for a few days, and it´s driving me totally crazy. I´m using Storyboards.
I have viewcontroller1 with a webview. The webview populates a html login form, through a textField (username) another textField (password) and then a button (submit) which work perfect: once pushing the button, the html form is populated with my textFields input. Once the form is filled and submitted, I want the user to be sent to a new viewcontroller (viewController2) which has a webview, that I want to populate with some of the stuff from the website. I cant, for the world, find out how to send the user to the next view.
Another detail is that the login html form has a user type select. Hence, the adress the submit button sends me can be different. If its a teacher filling out the form the returned address is going to be something like "myschool/jsp/teacher/right_teacher_lesson_status.jsp" and if its a student something else, and if its from another school, something else.
This is the code Ive tried to send the user to the next view containing UIwebview2:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:
(UIWebViewNavigationType)navigationType
{
if (navigationType == UIWebViewNavigationTypeFormSubmitted) {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
ViewController2 *vc = [storyboard instantiateViewControllerWithIdentifier:#"webview2"];
NSLog(#"Allow navigation to request = %#", request);
[self.navigationController pushViewController:vc animated:YES];
return YES;
}
The NSLog tells me
"Allow navigation to request: /myschool/jsp/teacher/right_teacher_lesson_status.jsp"
So if I tell the webview2 the address it will surely pick it up. But since I cant know which school or usertype it is, I want the webview2 to recieve that from the above code. Please help me. How can i pass the info to the next view?
I recommend creating a view with two text fields and a picker menu. This is much nicer than a a web view. If you cannot display the resulting content in a pretty way, you can use a web view, but you should optimize the user experience with custom views whenever possible.
Once you have UIKit elements to capture the data, passing it to the next view controller will be trivial.
That being said:
Maybe this is really a problem of the HTML coding. Your "Submit" button could include the arguments in the URL (GET instead of POST). You can then simply pass the URL on to your next view controller.
vc2.urlToLoad = request;
As you are not showing the URL, the get variables will not be exposed to the user anyway. As your server can interpret the arguments, you do not even have to parse them in the second view controller (although you could if you need them for other purposes).
Related
Ok so I'm linked to a server and I know for a fact that I have all the code there correct. But something seems to be wrong with this code:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString* responseString = [[NSString alloc] initWithData:_responseData encoding:NSUTF8StringEncoding];
/*Succesful Login*/
if([responseString isEqualToString:#"success"]){
[self performSegueWithIdentifier:#"LoginHomeToMain" sender:self];
NSLog(#"Succesful login.");
}
/*Deactivated Account*/
else if([responseString isEqualToString:#"disabled account"]){
}
/*Incorrect username and password.*/
else if([responseString isEqualToString:#"incorrect"]){
NSLog(#"Incorrect username and (or) password.");
}
/*GET request*/
else if([responseString isEqualToString:#"get"]){
}
}
So I think you can ignore the 2nd and 4th else if's but here's the problem:
When I try a user and pass that I know does not exist in the server, it still segues me to the main tab bar view. Am I supposed to reload the login page's view for the "incorrect" logic, or is my segue wrong? P.S. The segue is simply linked from a login button to the main tab bar view, and is modal.
Also, I keep getting this error message in the debugger:
"Unbalanced calls to begin/end appearance transitions for ."
Any help is greatly appreciated, Thanks!
If you want to perform a segue conditionally, you need to link the segue from the origin view controller to the destination view controller.
Do not link the segue from a UI element such as a button. (if you want to only perform the segue conditionally, that is)
Changing your segue's origin connection from the button to the view controller will fix your problem without changing a line of code.
Personally, I've just started always linking from view controller. It's easy enough to write the one line of code to perform the segue, and you never know when you'll have to write some sort of conditional logic around it later. So it's probably good to just get into the habit of doing it this way.
I'm adding TabBarItem (Email) dynamically. When I finish with my email, I'm calling 'dismissModalViewControllerAnimated' but it's simply dismissing mail view. How do I unload the view controller?
in my email view controller I'm doing following:
- (void)viewDidLoad => I would like to unload this view controller
{
[super viewDidLoad];
[self showEMail:nil]; => this display and dismisses email (I'm not calling present.. and dismiss... in a row. I'm using delegate methods to present and dismiss, which is fine.)
[self presentModalViewController:picker animated:YES];
[self dismissModalViewControllerAnimated:YES];
}
after selecting my tab bar item, it's loading view controller(Lets say 'ABC View controller') which is presenting my mail modal controller. mail modal controller is being dismissed properly. but I would like to come back to previously selected tab item after unloading the 'ABC view controller'. is it possible? or am i doing something wrong here?
Thanks in advance
Rama
Rama, your question is hard to understand. maybe you need to use delegation for the view controller you are presenting.
In your code, calling [self presentModalViewController...] and [self dismissModalViewController...] in a row doesn't make sense.
You shall call the [self presentModalViewController...] in the first place, make the presenting view controller as the delegate (picker.delegate = self, for instance)
let the modal view controller do its business including exiting (like user hits cancel, close or whatever), then call the delegation method (something like [delegate didFinish...] or [delegate didCancel...]
now it's the presenting view controller's turn to response to the delegation method calling, you can do the modal view controller dismissing here
Note: many UIKit classes practice this pattern, such as UIAlertView, UIActionSheetView, MPMoviePlayerViewController, etc. You shall check them and make your own
I've solved problem by using ViewWiilAppear method to display mail modal presenter.
and i'm selecting the index of tab bar controller after dismissing mail modal presenter.
self.tabBarController.selectedIndex =0;
This solved my problem.
Cheers
I have multiple nib (xib) files and I want the user to see a different one when they tap a button. What I am looking for:
- (IBAction)buttonTap {
//Code for showing a different nib goes here
}
I can't figure out how to do this. I can show a different view within the nib file just fine, but I can't get it to show a different nib. How do I show a different nib when the user taps a button?
Any help is appreciated! Thanks!
The way I handle switching between actual xib's, and I'm sure there are a multitude of ways to accomplish the same thing, is to have my App Delegate act as a routing center between my views.
I subscribe my App Delegate to recieve events from button presses for existing views. When it recieves a request to switch views, such as a button press, I do something like this:
- (void) showLogin
{
LoginViewController *loginViewController = [[LoginViewController alloc]
initWithNibName:#"LoginViewController" bundle:nil];
// Show
self.loginViewController = loginViewController;
[loginViewController release];
self.window.rootViewController = self.loginViewController;
}
I set my rootViewController to the view I am attempting to display. It doesn't release the old controller, but simply replaces the view being displayed. You can place more logic in to determine if it's already displayed, close out other views, etc. In most simplistic terms, this works for me.
I am trying to instruct my app to open a certain view, depending on whether the user has already created a user profile on my database.
so basically -
- (void) viewWillAppear:(BOOL)animated {
//all my ASIHTTPRequest code here
//blah blah blah
NSString *responseString = [request responseString];
if ([responseString isEqualToString:#"noexistingdata"])
{
FriendsViewController *friendsview = [[FriendsViewController alloc] initWithNibName:nil bundle:nil];
//SOMETHING NEEDS TO GO HERE TO MAKE THIS WORK!
} else if ([responseString isEqualToString:#"success"])
{
//do whatever
}
}
I just want the most basic code for changing a view... I would try using IBAction, but obviously that won't work as this is in a void for the app's launch (rather a response to a button the user presses), also thought about void in a void, which also did not work.
So basically what I need is:
Launch App > App receives response from my server > (IF RESPONSE = "THIS", LOAD VIEW "X") (IF RESPONSE = "THAT", LOAD VIEW "Y")
Anyone have a clue?
PS: would it be better to list this is applicationDidFinishLaunching?
-viewWillAppear: is called just before a view is displayed. That's probably not a great time to a) run some synchronous network request and b) load another view controller.
I'd suggest having the application delegate create a view controller who's view just displays a message, like "Connecting to server" or "Retrieving user credentials" or whatever. You might add an animated spinner to let the user know that they're supposed to wait, if that's all they're allowed to do at this point. Then, after the view is displayed, such as in that controller's -viewDidLoad method, start an asynchronous network connection to talk to the server. When you get back a response, decide which view controller to instantiate next, and do that.
Here's the scenario: if this is a user's first time logging into my web service, I present a modal login view. Upon success, the user may have multiple items in his/her account and must choose one of them before he/she can proceed with the rest of the app.
I want to put up another modal view with a picker so the user can make the choice.
All the examples I've seen of multiple modals presented are canned ones (like the email composer modal, with the people picker modal coming up over it), which is of no use because the code isn't available.
When I try putting up the login modal, then dismissing it, then presenting the picker, I get a recursion somewhere with a selector being sent to subviews being sent to subviews being sent to ....
Can anyone point me to some sample code?
I'm keeping a reference to the login view, so I figured I'd just pose the stack (well, two) modal views, then dismiss the login modal and they'd all go away (like the documentation says), but I can't seem to get this going.
Thanks in advance.
I have found that I could do this, but had to eliminate animation on the first dismiss, iff I was using animation on the 2nd presentModalViewController
ContactsViewController* controller = [[ContactsViewController alloc] ...
UINavigationController* navigationController = [[UINavigationController alloc] initWithRootViewController:controller];
[self.navigationController presentModalViewController:navigationController animated:YES];
[controller release], controller = nil;
and then in my delegate method that is being called from the initial modal view
[self.navigationController dismissModalViewControllerAnimated:NO]; // dismiss without animation
[self.navigationController presentModalViewController:anotherViewController animated:YES];
This behavior was observed on OS 3.0.1.