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?
Related
I have controller (news screen), and i need to detect when user leave it. I tried
- (void)viewWillDisappear:(BOOL)animated
, but the problem is, when user tap share button (share in social networks etc.) that method triggers, but after sharing user is still in news screen, therefore its not work.
I also tried
-(void)willMoveToParentViewController:(UIViewController *)parent {
, but it also trigger when user first enter controller, which is wrong (i need to detect leaving only).
How can i detect when user leave controller, but not trigger when he enter "sharing" pop screen?
These four methods can be used in a view controller's appearance callbacks to determine if it is being presented, dismissed, or added or removed as a child view controller. For example, a view controller can check if it is disappearing because it was dismissed or popped by asking itself in its viewWillDisappear:
method by checking the expression ([self isBeingDismissed] || [self isMovingFromParentViewController]).
- (BOOL)isBeingPresented NS_AVAILABLE_IOS(5_0);
- (BOOL)isBeingDismissed NS_AVAILABLE_IOS(5_0);
- (BOOL)isMovingToParentViewController NS_AVAILABLE_IOS(5_0);
- (BOOL)isMovingFromParentViewController NS_AVAILABLE_IOS(5_0);
use isMovingFromParentViewController for your scenario
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
if (self.isMovingFromParentViewController){
}
}
Check this it will help you.
UIActivityViewController *conroller=[[UIActivityViewController alloc] initWithActivityItems:#[#"Hello"] applicationActivities:nil];
You can handle the sharing thing in the completion here
[conroller setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError){
if(!activityError)
NSLog(#"Shared");
}];
The completion will tell you that the activity was presented so you can handle the activities you want to handle in the completion like this
[self presentViewController:conroller animated:YES completion:^{
NSLog(#"Activity Appeared"); //Same as viewWillDisappear
}];
Hope this helps.
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 am programming an IOS app that will use parse to login a user. Using storyboard I have the login button connected to another view controller with the push segue. Whether the username and password are correct the button selection always goes to the new view controller. I might be doing this all wrong. Any help is appreciated. Here is my code:
- (IBAction)signIn:(id)sender {
[PFUser logInWithUsernameInBackground:self.emailField.text password:self.passwordField.text block:^(PFUser *user, NSError *error) {
if (!error) {
[self performSegueWithIdentifier:#"signIn" sender:nil];
} else {
// The login failed. Check error to see why.
}
}];
}
I think the issue is that you connected the button right to the next view controller in your storyboard. Here's what you need to do:
Select the first view controller and create a segue to the second one, NOT from the button, from the first view controller.
In the inspector give the segue an identifier (i.e. "loginSegue").
Create an IBAction for your button by control-dragging the button in the storyboard to the .m file of your first view controller. In that new method you can add the login code:
[PFUser logInWithUsernameInBackground:self.emailField.text
password:self.passwordField.text block:^(PFUser *user, NSError *error)
{
if (!error) {
[self performSegueWithIdentifier:#"loginSegue" sender:nil];
} else {
// The login failed. Check error to see why.
}
}];
I am using this code from Parse:
[PFUser logInWithUsernameInBackground:namerL password:passerL
block:^(PFUser *user, NSError *error) {
if (user) {
[self performSegueWithIdentifier:#"signinToInbox" sender:self];
} else {
NSLog(#"%#",error);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Login Failed." message:#"Invalid Username and/or Password." delegate:self cancelButtonTitle:#"Okay" otherButtonTitles:nil];
[alert show];
}
}];
Whenever I click on the sign in button without typing in anything, it doesn't log any errors. I need it to count it as an error if there is no such user and or if the password is correct. But even if the account details are not correct, it is still going to the segue.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { I believe that it's calling the segue because it is still in didSelectRowAtIndexPath. I just don't know how to stop it from calling the segue that's connected it (by default).
Maybe this problem isn't about parse login at all. From the comments, it seems to be about segues attached to table view cells.
If you want to perform a segue conditionally, it shouldn't be attached directly to the table view cell. Instead draw the segue between view controllers in IB (ctrl-drag from the view controller's status bar to the destination vc). Give that segue a name, like "goodLogin", then perform it manually upon a condition.
So if you only want to segue when a login succeeds ...
// parse login
if (!error) {
[self performSegueWithIdentifier:#"goodLogin"];
} else {
// don't perform a segue. Stay here and change ui to indicate an error
}
This is the code I use:
[PFUser logInWithUsernameInBackground:username password:password block:^(PFUser *user, NSError *error) {
if(!error){
[self loggedInSuccessfully];
} else {
[self loginFailedWithError:error];
}
}];
When doing any API call, I would always check the error variable because if it exists then you know the method failed.
EDIT
From our discussion it appears that you are having problems with your UITableView performing the segue when you click on a cell.
It is possible to disable a segue by returning NO from the shouldPerformSegueWithIdentifier method
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
if([identifier isEqualToString:#"signinToInbox"]){
return YES;
}
return NO;
}
This will disable all segues on the UIViewController apart from your signinToInbox
However, I believe you may have your UIStoyboard set up incorrectly, there shouldn't be the default segue enabled. You should only need to perform the segue in the code after you have called the login function. Therefore in the storyboard you should be using the custom segue option.
If you have a segue set up already on the UIStoryboard you should be able to click on it and in the Attributes inspector panel change the drop down from model to custom
It seems you have problems with your segues and table views. Try the following in Xcode 6.
First delete your current segue.
Ctrl + drag as shown:
After that, choose the action segue you want (push, modal or custom). Then make sure the identifier matches the one in the code.
Now simply make the following changes in the code
[PFUser logInWithUsernameInBackground:namerL password:passerL block:^(PFUser *user, NSError *error) {
if (!error) {
[self performSegueWithIdentifier:#"signinToInbox" sender:self];
} else {
NSLog(#"Error logging in: %#",error);
[[[UIAlertView alloc] initWithTitle:#"Login Failed" message:#"In valid username and/or password" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil] show];
}
}];
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.