I am using storyboard. It has a login VC , which on success pushes to another VC. When the user enters the credentials and clicked on login button then it hits the server. I have implemented all the logic that contains hitting with server in a separate class which has delegate. When we get response then the control goes to the delegate method implemented in login VC. In the delegate method if status is success then only the login VC must be pushed in to another VC.
In Login VC
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
Util *util = [[Util alloc]init];
util.delegate = self;
NSMutableDictionary *request = [[NSMutableDictionary alloc]init];
[request setValue:uname.text forKey:#“username”];
[request setValue:pwd.text forKey:#“password”];
[util body:request];
}
when server returns response it comes to the delegate method implemented in Login VC
- (void)response:(NSDictionary *)response
{
//here i am going to check the status if it is success i will go to new VC else in same VC
}
here i am unable to go to another VC since i am not in the shouldPerformSegueWithIdentifier: method.
Why don't you call
[self performSegueWithIdentifier:#"customerView" sender:self];
It looks like you're probably triggering your segue when the login button is tapped. You can't do this if you need to wait for a response from your web service. Instead, try connecting your button to a method when sends off your login request. When you receive your response, you can check if the user's login is valid, and then perform your segue programmatically:
- (void)response:(NSDictionary *)response
{
if (something) // check if response is valid
{
[self performSegueWithIdentifier:#"YourSegueIdentifier" sender:self];
}
else
{
// show error
}
}
This way, you won't need to implement shouldPerformSegueWithIdentifier:sender: at all.
Related
I am integrating Twitter app in my iOS app. The problem is after successful login, the segue that should take the control to the specific view controller, return back to my login page and not to the desired view controller. The segue has been performed and i can see that in my output console. Also the wired thing is when i click the tweet button on login page, the segue performed second time visually at last.
My twitter login method is as follow:
- (IBAction)tweetbutton:(id)sender {
[SCTwitter initWithConsumerKey:#"your_consumer_key" consumerSecret:#"your_consumer_secret"];
[SCTwitter loginViewControler:self callback:^(BOOL success){
NSLog(#"Login is Success - %i", success);
if (success) {
[self performSegueWithIdentifier:#"authentication" sender:self];
}
}];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
NSLog(#"prepareForSegue: %#", segue.identifier);
}
The output in console is:
2014-12-10 23:54:16.923 gems[1300:60b] Login is Success - 1
2014-12-10 23:54:16.946 gems[1300:60b] prepareForSegue: authentication
I don't understand where I am wrong and why segue is not performing automatically visually on login success. Please suggest a suitable solution so that direct automatic transition to specific view controller without getting back on Login page again and also for your knowledge I am using plain view controller and not navigation controller.
Thanks in advance. Any help would be appreciated.
Using Swift 3:
Use this in viewDidLoad():
Twitter.sharedInstance().logIn { (session, error) in
if error == nil {
performSegue(withIdentifier: "authentication", sender: self)
}
}
I found a really good walk through of how to pass string values back from a ViewController to a calling ViewController and got it working perfectly. The example is really very good.
https://www.youtube.com/watch?v=YVikeoR3gYg
That said, the technique for passing back content seems relatively straight forward now that I have seen it, even if it's not that intuitive.
The example code however only includes two controllers. When I replicated the code using a much more detailed Storyboard, the code simply doesn't work. In my test app, I even embedded the calling Controller inside a NavigationController to see whether this would have an affect, but it still continued to work fine.
In my application, the ViewController is embedded within a NavigationController that is called via a SWRevealController segue class. I don't know if this is important or relevant but I am mentioning it.
I then call a CollectionViewController to choose an icon that should be passed back to the calling ViewController.
When I select the icon, I correctly identify the icon and pop
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
selectedIcon = [placeIcons objectAtIndex:indexPath.row];
NSLog(#"In IconCollectionViewControlled - selected %#", selectedIcon);
NSString *itemToPassBack = #"12345"; // Just testing any old string here...
// [self.delegate passBackIcon:selectedIcon]; // commenting out while testing
[self.delegate passBackIcon:itemToPassBack];
[self.navigationController popViewControllerAnimated:YES];
}
I get a correct trace suggesting that the right icon is selected. I would then expect that the text '12345' would be passed back to the calling Controller.
In my calling Controller, I have the following:
- (void)passBackIcon:(NSString *)iconName {
NSLog(#"Icon to use is %#", iconName);
}
But this just isn't being called at all (or at least I'm not seeing the NSLog being shown. It's just being ignored.
The delegate is being correctly declared as far as I can tell.
Am I missing something?
assuming you are working with segues, in the method prepareSegue you should setting the delegate
for Example :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"YOUR_SEGUE_IDENTIFIER"] ) {
DestinationVc *vc = (DestinationVc *)segue.destinationViewController;
[vc setDelegate:self];
}
}
Hope it works for you
I've found this to be the easiest way to pass string and other information around using a tableView.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ViewControllerYouWantToPassToo *result = [self.storyboard instantiateViewControllerWithIdentifier:#"NameOfTheViewController"];
result.stringName = #"12345" // String Name is a NSString property you set up in the ViewController you want to pass too
[self.navigationController pushViewController:result animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
I suggest you wrapping your delegate in a check to see that it is valid and that it has adopted the respective method (if optional).
if(self.delegate && [self.delegate respondsToSelector:#selector(passBackIcon:)]){
[self.delegate passBackIcon:itemToPassBack];
}else{
NSLog(#"Your delegate is not setup correctly");
}
If it enters the else, you have not set the delegate properly..ie you likely never did
self.delegate = SomeInstanceOfAClassThatAdoptsYourDelegate;
I've been developing an iOS app that includes a login screen. This screen has two UITextField where I input the username and the password.
Now, the issue recalls in the following: I've set up an "else if" to trigger an UIAlertView if the field are in blank.
The UIAlertView DOES pop up but... in the next View Controller.
Another issue is... It check if the username and the password are right or not and it jumps into the next View Controller as well.
This is odd because I set an "if" condition to check that the text in both UITextFields must match in order to trigger the next View Controller.
I've got the hunch that another method linked to the login action might be interfering in the process.
I will post the segment of the code concerning the login:
- (void)btn_submit:(id)sender{
NSString *user = self.usuari.text;
NSString *pass = self.contrasenya.text;
NSString * urlBase = #"http://www.v2msoft.com/clientes/lasalle/curs-ios/login.php?username=lluis&password=seguro";
[JSONHTTPClient getJSONFromURLWithString:urlBase completion:^(id json,JSONModelError *err){
JsonUser * user = [[JsonUser alloc]initWithDictionary:json error:nil];
if(user.succeed){
self.user_id = user.user_id;
[self performSegueWithIdentifier:#"Login" sender:self];
}
else{
NSLog(#"error");
}
}];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if (([self.usuari.text isEqualToString:#"lluis"]) && ([self.contrasenya.text isEqualToString:#"seguro"])){
Supermarket * supermercat = segue.destinationViewController;
supermercat.user_id = self.user_id;
}
else if (_usuari.text.length == 0 || _contrasenya.text.length == 0)
{
[[[UIAlertView alloc] initWithTitle:#"Alerta!"
message:#"Camps buits!"
delegate: nil
cancelButtonTitle:#"Cancelar"
otherButtonTitles:nil
] show];
}
}
And, also, the few lines of the "JsonUser" class:
#import "JSONModel.h"
#interface JsonUser : JSONModel
#property BOOL succeed;
#property int user_id;
I think that I might be making a mistake by sending the parameters to the server through the URL and that might override the login.
I'd appreciate any help or advice regarding this matter.
It is already too late for your check within prepareForSegue. If you had the chance to stop the presentation of the segue there the method would be called shouldPresentSegue or something like that. Perform your check (the else if) before you call performSegue.
whether u connect segue from submit button to next view controller or segue from login view to nextviewcontroller. Make Sure your segue only from login screen to nextviewcontroller not from submit button.
I have a button that will segue to another View Controller. In shouldPerformSegueWithIdentifier I check the identifier and returns NO for this certain button after calling my own method nextClicked.
In nextClicked I do a HTTP Request and check some stuff, and then if everything is OK I do
dispatch_async(dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:#"getstartednext" sender:self];
});
The problem is that I get no animation now... The segue is of type modal. If I return YES in shouldPerformSegueWithIdentifier and don't to the segue programmatically later, the animation appears and everything is as it should.
You are misusing shouldPerformSegueWithIdentifier. If you want to do something special in response to the button click, use action-target and not a segue connected to the button.
I created a new project with your idea and I've got animation.
This is the action connected through IB with the next viewController and with identifier: #"getstartednext"
- (IBAction)go:(id)sender
{
}
Same code you have except sender is nil
- (void) nextClicked
{
dispatch_async(dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:#"getstartednext" sender:nil];
});
}
if sender != nil, (IBAction go:) then I'm calling nextClicked because returning NO
else the code is doing the segue because returning YES
- (BOOL) shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
if ([identifier isEqualToString:#"getstartednext"] && sender != nil)
{
[self nextClicked];
return NO;
}
return YES;
}
Works like a charm.
I am trying to trigger a segue and move to a new view based on the result of an asynchronous task.
I have setup the segue by connecting a button in my initial view and dragging to the next view. I have also setup an ibaction on the initial button that triggers the asynch task. I think these two things could possibly be in conflict.
my ibaction code looks like:
- (IBAction)buttonClicked:(id)sender {
NSLog(#"button clicked");
[user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
NSLog(#"in process");
if (!error) {
NSLog(#"succcess");
[self performSegueWithIdentifier:#"myid" sender:#"success"];
}else{
NSLog(#"failure");
}
}];
only the first button click log prints. The others do not.
My segue methods do not have any logic.
The segues fire without hitting the performSegue method above.
How can I control the segue transition methods from the button click?
How can I have the signup method be called and then have the segue fire?