A button which navigates to different view controllers depending on the condition - ios

I am new to IOS. I am making a login view controller in IOS with one button which is sign in. I have two possible view-controllers that might be shown when the user click on the sign-in button. I am using Storyboard but I can only assign one segue to one button. I don't know how to perform the condition since I seem not to have 100% control over the segue.
Here is my code:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *stringreponse=[[NSString alloc] initWithData:_responseData encoding:NSUTF8StringEncoding];
// NSLog(#"Split response %#", [splitresponse objectAtIndex:0]);
if([stringreponse isEqualToString:#"0"])
{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"Wrong username or password" message:#"Wrong username or password" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
else
{
NSArray *splitresponse=[stringreponse componentsSeparatedByString:#"#"];
if([[splitresponse objectAtIndex:0] isEqualToString:#"Parent"])
{
if([[splitresponse objectAtIndex:2] isEqualToString:#"yes"])
{
//seguechoice=#"showParentRegistration";
//[self performSegueWithIdentifier:#"showParentRegistration" sender:self ];
}else{
//seguechoice=#"showSohoDashboard";
}
}
}
}

you can assign one segue to one UI control but you can assign many to a viewContoller. Simply add all of them to the viewController, give each a different id and then call those id's
if([[splitresponse objectAtIndex:2] isEqualToString:#"yes"])
{
[self performSegueWithIdentifier:#"showParentRegistration" sender:self ];
}
else
{
[self performSegueWithIdentifier:#"showSohoDashboard" sender:self ];
}

Create 2 connection in storyboard from your source view controller to destination view controller (not button). Insert two different identifiers and when the button is pressed do condition and run a segue depends on the condition:
if(CONDITION TO RUN SEGUE !)
{
[self performSegueWithIdentifier:#"SEGUEIDENTIFIER1" sender:self ];
}else {
[self performSegueWithIdentifier:#"SEGUEIDENTIFIER2" sender:self ];
}

Related

APNS to open a certain part of an application

I've just implemented a commenting feature in my app. Ideally when someone leaves a comment, I'd like all notified people be able to swipe the push notification and open the app on that post.
I assume you want to open the concerned page directly. There are many ways to go about this, and it depends on how your app is laid out.
If you want to open an inner page upon app launch, you can programmatically trigger the segues that the user would otherwise need to make manually. (this ensures the back/home buttons work as opposed to loading the desired page directly).
Here's an excerpt from one of my own code, your use case may not be the same, but this is all i can do unless you give us more details.
- (BOOL) navigateToRespectiveSectionforPushNot:(NSDictionary*)pushNot
{
id rootVC = self.window.rootViewController;
NSLog(#"ROOT CLASS : %#", [rootVC class]);
if ([rootVC isKindOfClass:[SWRevealViewController class]])
{
NSLog(#"Root Class looking good... mission Navigate!!");
SWRevealViewController *homeVC = (SWRevealViewController*) rootVC;
NSString *category = [[pushNot objectForKey:pushPayloadKeyaps] objectForKey:pushPayloadKeyCategory];
NSString *subCat = [[pushNot objectForKey:pushPayloadKeyaps] objectForKey:pushPayloadKeySubCategory];
NSLog(#"category : %# , subcat : %#",category,subCat);
//The code for the page to which i'm supposed to navigate to is contained in the push notification payload
if ([category isEqualToString:pushCategoryItemChat])
{
[homeVC.rearViewController performSegueWithIdentifier:#"chatPush" sender:nil];
UINavigationController *nc = (UINavigationController*)homeVC.frontViewController;
NSLog(#"FrontView Class : %#",[nc.viewControllers[0] class]);
UITableViewController *tvc = (UITableViewController*)nc.viewControllers[0];
NSDictionary *send = #{chatPushTargetUserId:subCat,chatPushTargetUserName:#"",chatPushTargetUserImage:#""};
[tvc performSegueWithIdentifier:#"seguePushDemoVC" sender:send];
return YES;
}
//communityPush historyPush
else if ([category isEqualToString:pushCategoryItemCommunity])
{
if ([subCat isEqualToString:pushSubCatItemNewRequest])
{
[homeVC.rearViewController performSegueWithIdentifier:#"communityPush" sender:nil];
return YES;
}
else if ([subCat isEqualToString:pushSubCatItemAccepted])
{
[homeVC.rearViewController performSegueWithIdentifier:#"communityPush" sender:nil];
return YES;
}
}
else if ([category isEqualToString:pushCategoryItemHistory])
{
[homeVC.rearViewController performSegueWithIdentifier:#"historyPush" sender:nil];
return YES;
}
}
else
{
UIAlertView *whoa = [[UIAlertView alloc] initWithTitle:#"WHOA!!" message:#" That wasn't supposed to happen. You are not even logged in. Call 911..." delegate:nil cancelButtonTitle:#"mmKay.." otherButtonTitles:nil, nil];
[whoa show];
}
return NO;
}
I hope the code is self explanatory. cheers

UIAlert and push segues

I have an IF statement that checks labels to see if a label is empty, if it is show an alert.
if ([_DOBDate.text length] == 0)
{
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Cannot Proceed"
message:#"Please Submit your DOB and Gender"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[message show];
}
later on in the function I have perform segue, like this :
[self performSegueWithIdentifier:#"SetUptoMain" sender:self];
True, the alert does fire when the label is blank, but it also performs the segue. This perform segue line is not in the IF statement. So I would have thought it would have ran the IF statement and stayed there till I pressed OK. OK would be staying on the same view controller.
The segue is performed, is this due to Blocks ? any advice ?
So if the USER pressed Ok from the UIAlert the VC does not move, it stays where it was so the user can enter the details required.
This is my code :
- (IBAction)SettingsSave:(id)sender {
if ([_DOBDate.text length] == 0)
{
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Cannot Proceed"
message:#"Please Submit your DOB and Gender"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[message show];
}
more code...
then at the end
[self performSegueWithIdentifier:#"SetUptoMain" sender:self];
}
thanks
Seems to be an if/else logic issue. Read about it.
-(IBAction)yourAction:(id)sender
{
if ([_DOBDate.text length] == 0)
{
//Show your AlertView as you did
}
else
{
//put the rest of your code, including the performSegue
}
}
UIAlertView doesn't block execution. It runs asynchronously. Therefore the code path will go into your if statement, then continue past it.
If you only want the segue to be performed after the user presses the alert view button then you need to implement UIAlertViewDelegate.
In your header file add something like this:
#interface MyController : UIViewController <UIAlertViewDelegate>
When you create the alert view do it like this:
UIAlertView *message = [[UIAlertView alloc] initWithTitle: #"Cannot Proceed"
message: #"Please Submit your DOB and Gender"
delegate: self
cancelButtonTitle: #"OK"
otherButtonTitles: nil];
[message show];
And add this method to implement the UIAlertViewDelegate.
- (void) alertView: (UIAlertView *) alertView clickedButtonAtIndex: (NSInteger) buttonIndex {
// perform segue here. You can also check what button was pressed based on the button index.
}

Blinking labels don't appear upon return from second (modal) view controller

I've got two labels in a custom UITableViewCell. Their purpose is to indicate the status of a timing operation on the object represented by the cell.
One label displays a countup timer. The other simply blinks "Timer Sleeping." Their visibility is mutually exclusive (if one is visible, the other is not, and vice versa) according to a switch statement to determine which label is currently visible. Each is driven by a dedicated NSTimer.
Everything works fine--until I do a modal segue to another View Controller (for the purpose of adding another entity or other task) and then return to the original VC via Cancel or Savethrough delegation. Then, regardless of which label had been visible (and updating via its timer) prior to the segue, no label is to be seen. The cell appears blank.
The weird thing is that when I segue to yet another VC via a push segue, then return via the "Home" button, the labels appear, blinking or counting up, just as though nothing had happened. The only obvious difference I can see between the two return methods is that the modal is handled via delegation whereas the push is unwound through a nav controller.
Any ideas? I can supply any relevant code, but didn't know where to start and didn't want to paste all of it.
Thanks!
EDIT for clarification in response to question below:
I'm returning via delegation. Here's the code in the modal:
- (IBAction)saveButton:(UIBarButtonItem *)sender
{
if (self.activityField.text.length > 0)
{
if (self.categoryLabel.text.length < 1)
{
// self.thisActivity.category = #"Uncategorized";
// self.thisActivity.name =self.activityField.text;
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No category selected"
message:#"Please select a category or Cancel"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
else
{
self.thisCategory.name = self.categoryLabel.text;
self.thisActivity.name = self.activityField.text;
self.thisActivity.category = self.thisCategory.name;
NSLog(#"Category name is %#", self.thisCategory.name);
NSLog(#"Activity name is %#", self.thisActivity.name);
[self.delegate addActivityViewControllerDidSave];
}
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No activity entered"
message:#"Please enter a new activity or Cancel"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
}
- (IBAction)cancelButton:(UIBarButtonItem *)sender
{
[self.delegate addActivityViewControllerDidCancel:self.thisActivity];
NSLog(#"delegate is %#",self.delegate);
}
And here's the delegate method implementation code from the original VC:
#pragma mark - AddViewControllerDelegate stuff
-(void) addActivityViewControllerDidSave
{
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
[localContext MR_saveToPersistentStoreAndWait];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
[self refreshData];
}
-(void) addActivityViewControllerDidCancel:(WMDGActivity *) activityToDelete
{
[activityToDelete MR_deleteEntity];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
[self refreshData];
}
2nd edit:
Here's the refreshData code:
-(void) refreshData
{
actFRC = [WMDGActivity MR_fetchAllSortedBy:#"category,name"
ascending:YES withPredicate:nil
groupBy:#"category"
delegate:nil];
[self.myTableView reloadData];
}
I've tried calling this method in viewDidLoad, and NOT calling it there. Same results.
UPDATE, 3/26/2014:
OK, I've discovered that if I remove the call to refreshData from my addActivityViewControllerDidCancel method, the labels work fine. They likewise work fine if I remove the same line from addActivityViewControllerDidSave. Unfortunately, this prevents newly added items from appearing in the HomeViewController table view until the app is relaunched.
Here is my current code for the cancel and save methods:
-(void) addActivityViewControllerDidSave
{
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
[localContext MR_saveToPersistentStoreAndWait];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
[self refreshData];
}
-(void) addActivityViewControllerDidCancel:(WMDGActivity *) activityToDelete
{
[activityToDelete MR_deleteEntity];
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
[localContext MR_saveToPersistentStoreAndWait];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
// [self refreshData];
}
I view this as a temporary, or interim, fix. Sure would be grateful for a real cure.
Thanks!

Customizing the keyboard's "Next" and "Done" return buttons

Right now I have a simple Login view controller. It has 2 text fields, one for a username and one for a password. I would like to add the following functionality to the keyboards for these 2 text fields:
When the user is done typing their username in the username text field, they should be able to press the "Next" return key which should take them to the 2nd text field for the password.
When the user is done typing their password and they press the keyboard's "Done" return key, I want to perform an IBAction that I have setup.
Here is the IBAction code that I want to perform when the user presses the "Done" return key in the password text field:
-(IBAction)didTapLoginButton:(id)sender {
[self textFieldShouldReturn:_usernameEntry];
NSString *user = [_usernameEntry text];
NSString *pass = [_passwordEntry text];
if ([user length] < 4 || [pass length] < 4) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Invalid Entry" message:#"Username and Password must both be at least 4 characters long." delegate:self cancelButtonTitle:#"Okay" otherButtonTitles:nil];
[alert show];
} else {
[_activityIndicator startAnimating];
[PFUser logInWithUsernameInBackground:user password:pass block:^(PFUser *user, NSError *error) {
[_activityIndicator stopAnimating];
if (user) {
NSLog(#"Successful login");
//[self performSegueWithIdentifier:#"loginToMainAppSegue" sender:self];
[self performSegueWithIdentifier:#"loginToMediaCaptureVC" 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];
}
}];
}
}
I have already set my view controller as the delegate and both of the text fields work perfectly, but I would like to add the extra functionality that I have listed above.
If it makes a difference, the text fields and keyboards are not being created programatically. They were created on the storyboard.
Thanks for the help.
step1 - give tag to both your text field
step2 - check the tag in - (BOOL)textFieldShouldReturn:(UITextField *)textField;
if first username is active make the password textfield becomes first responder. if password field is active resign first responder
-(BOOL)textFieldShouldReturn:(UITextField*)textField;
{
if([_txtFieldUserName isFirstResponder]){
[_txtFieldPassword becomeFirstResponder];
}
else if ([_txtFieldPassword isFirstResponder]){
[_txtFieldPassword resignFirstResponder];
}
}
For a UITextField or editable UITextVie you can also do:
[myTextField setReturnKeyType:UIReturnKeyNext];
You can also configure this in Interface Builder, under Text Input Traits for your text field/view.
UPDATE
In Xamarin.iOS or Monotouch is:
myTextField.ReturnKeyType = UIReturnKeyType.Next;

iOS and xcode: how to create a modal segue to a special view only the first time the app is used

I want to make a "terms and conditions" screen that pops up the very first time that app is opened. On this view I would add a button that says "agree," and upon clicking it the code would execute:
[self dismissViewControllerAnimated:YES completion:nil];
...and would go to the first view of the app.
I am currently using a Tab Bar Controller that has 4 ViewControllers. So basically, I just need to have some method in viewWillAppear on my first ViewController that checks for an NSUserDefault key:value. The first time the app opens, it will be zero. After they click agree, I'll set it to 1 and the bit of code would never execute again.
Can you please offer some code to accomplish the task of routing the view from the firstViewController's view to this alternate view controller upon loading the app?
Thanks!
In the viewWillAppear method in your FirstViewController, check NSUserDefaults then present your TermsViewController. After user click agree in TermsViewController, set NSUserDefaults then call
[self.presentingViewController dismissModalViewControllerAnimated:YES]
The use of the popover window can get complicated. Try something like the following if you have little experience with Objective-C.
- (void)viewDidLoad {
if ([termsvalue == 0]) {
NSString *msg = [NSString stringWithFormat:#"Do you agree with the terms of use?"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"- Confirmation -"
message:msg
delegate:self
cancelButtonTitle:#"Disagree"
otherButtonTitles:#"I agree", nil];
[alert setTag:100];
[alert show];
}
}
- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView { // Validation
if ([alertView tag] == 100) {
return YES;
}
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { // Go
if ([alertView tag] == 100) {
if (buttonIndex == 1) {
// The user has agreed
}
}
}

Resources