Control the transition between two viewControllers - iphone

I am new to objective-c and have recently started making iOS applications in Xcode. I was making a login application that has two view controllers. It looks like this: http://imgur.com/W3nxMEG
Now my issue is that I was the app to go to second ViewController only if:
1) Text fields are filled
2) Passwords match
that's the code that I've written. I couldnt find any command that controls the transition between the viewControlled based on the certain constraints:
(IBAction)loginButton:(id)sender {
BOOL passMatch, emptyUser, emptyPass, emptyrePass;
passMatch = [password isEqualToString:reEnter];
emptyUser = [username isEqualToString:#""];
emptyPass = [password isEqualToString:#""];
emptyrePass = [reEnter isEqualToString:#""];
if (emptyPass || emptyUser || emptyrePass){
UIAlertView *error=[[UIAlertView alloc] initWithTitle:#"Ooops!" message:#"You must complete all the fields " delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[error show];
}
else{
passMatch = [password isEqualToString:reEnter];
if (passMatch){
UIAlertView *pass=[[UIAlertView alloc] initWithTitle:#"Success!" message:#"Passwords match " delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[pass show];
} else{
UIAlertView *error=[[UIAlertView alloc] initWithTitle:#"Ooops!" message:#"Passwords dont match " delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[error show];
}
}
Shall be thankful if anyone can help me solve this

First make sure your UITextField and UIButton from your storyBoard are hooked with a property in LoginViewController.h
It'll look like this:
LoginViewController.h
#interface LoginViewController : UIViewController
#property (strong, nonatomic) IBOutlet UITextField *password;
#property (strong, nonatomic) IBOutlet UITextField *username;
// and so on..
// for your button
#property (strong, nonatomic) IBOutlet UIButton *loginButton;
#end
LoginViewController.m
#implementation LoginViewController
-(IBAction)loginButton:(id)sender
{
// you can enable/disable your button here also, by:
// UIButton *senderButton = (UIButton *)sender;
// senderButton.enabled = YES/NO;
// i'm just using .length because i trust numbers more that the #""
NSString *errorMessage;
if (self.username.text.length == 0)
errorMessage = #"username is required";
else if (self.password.text.length == 0)
errorMessage = #"password is required";
else if (self.reEnter.text.length == 0)
errorMessage = #"please confirm your password";
else if (self.password.text.length == 0 || self.username.text.length == 0 || self.reEnter.text.length == 0)
errorMessage = #"You must complete all the fields";
if (errorMessage.length > 0)
{
UIAlertView *error=[[UIAlertView alloc] initWithTitle:#"Ooops!" message:errorMessage delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[error show];
}
else
{
if ([self.username.text isEqual: #"youUsername"] && [self.password.text isEqual: #"youPassword"] && [self.password.text isEqual: self.reEnter.text])
{
UIAlertView *pass=[[UIAlertView alloc] initWithTitle:#"Success!" message:#"Login successful" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[pass show];
//presentYourSecondViewController
//[self presentViewController:(UIViewController) animated:(BOOL) completion:nil];
//[self.navigationController pushViewController:(UIViewController)animated:(BOOL)];
}
else
{
UIAlertView *error=[[UIAlertView alloc] initWithTitle:#"Ooops!" message:#"Login failed" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[error show];
}
}
/* Your code...
BOOL passMatch, emptyUser, emptyPass, emptyrePass;
passMatch = [password isEqualToString:reEnter];
emptyUser = [username isEqualToString:#""];
emptyPass = [password isEqualToString:#""];
emptyrePass = [reEnter isEqualToString:#""];
if (emptyPass || emptyUser || emptyrePass){
UIAlertView *error=[[UIAlertView alloc] initWithTitle:#"Ooops!" message:#"You must complete all the fields " delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[error show];
}
else
{
passMatch = [password isEqualToString:reEnter];
if (passMatch){
UIAlertView *pass=[[UIAlertView alloc] initWithTitle:#"Success!" message:#"Passwords match " delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[pass show];
} else{
UIAlertView *error=[[UIAlertView alloc] initWithTitle:#"Ooops!" message:#"Passwords dont match " delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[error show];
}
}
*/
}
#end
There is nothing wrong with your condition i just over did it i guess.. Anyway hope i've help you Happy coding cheers..

Related

Xcode Point System Iphone Trivia Game

I am a beginner at creating iPhone apps and am trying to incorporate a simple point system for an iphone trivia game. Here is an basic overview of the app:
http://i.stack.imgur.com/nC0CI.png
So basically what I'm trying to do is make the user type the answer in the textfield. After typing an answer, they would click the button "Answer". If the answer is correct, an alert would show up saying "Correct", adding 100. If incorrect, it would say "Incorrect", subtracting 100.
However here is the problem: when you first answer correctly or incorrectly, the number remains at 0. When you click the button a second time, then it would properly increase/decrease. How do you fix this?
Here is my .h file
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController{
NSString *stringpoint;
int point;
}
#property (nonatomic, retain) IBOutlet UITextField *textAnswer;
#property (nonatomic, retain) IBOutlet UILabel *pointlabel;
-(IBAction) checkAnswer;
#end
.m file
#synthesize textAnswer, pointlabel;
int point=0;
-(IBAction)checkAnswer {
pointlabel.text = [NSString stringWithFormat:#"%i",point];
if ([textAnswer.text isEqualToString:#"fruit"]) {
point=point+100;
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Correct!"
delegate:self cancelButtonTitle:#"Close" otherButtonTitles:nil];
[alert show];
[alert release];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Incorrect"
delegate:self cancelButtonTitle:#"Close" otherButtonTitles:nil];
point=point-100;
[alert show];
[alert release];
}
}
I am using Xcode 4.3.
You are updating the label that shows points before you calculate the new total, just need to move it to after:
-(IBAction)checkAnswer {
// don't do this here, too early
// pointlabel.text = [NSString stringWithFormat:#"%i",point];
if ([textAnswer.text isEqualToString:#"fruit"]) {
point=point+100;
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Correct!"
delegate:self cancelButtonTitle:#"Close" otherButtonTitles:nil];
[alert show];
[alert release];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Incorrect"
delegate:self cancelButtonTitle:#"Close" otherButtonTitles:nil];
point=point-100;
[alert show];
[alert release];
}
// now you've changed value of points above, so update the label
pointlabel.text = [NSString stringWithFormat:#"%i",point];
}

MFMessageController crash sometimes

I have the concept of sharing to contacts in my App and used MFMessageComposeViewController.
-(IBAction)btnAddClicked:(id)sender {
#try {
selections = [[NSMutableArray alloc] init];
for(NSIndexPath *indexPath in arSelectedRows) {
NSMutableDictionary *searchable = [[NSMutableDictionary alloc
]init];
[searchable setObject:[[contactsArray objectAtIndex:indexPath.row]objectForKey:#"Phone"]forKey:#"Phone"];
[selections addObject:searchable];
}
if([selections count]>0)
{
NSString *temp1=#"";
for(int i=0;i<[selections count];i++)
{
toRecepients=[[selections objectAtIndex:i]objectForKey:#"Phone"];
temp1=[temp1 stringByAppendingString:toRecepients];
temp1=[temp1 stringByAppendingString:#","];
}
temp1 = [temp1 substringToIndex:[temp1 length]-1];
if(![MFMessageComposeViewController canSendText]) {
UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Your device doesn't support SMS!" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[warningAlert show];
return;
}
NSArray *recipents = [temp1 componentsSeparatedByString:#","];
MFMessageComposeViewController *messageController = [[MFMessageComposeViewController alloc] init];
messageController.messageComposeDelegate = self;
messageController.navigationBar.topItem.leftBarButtonItem.title = #"Cancel";
[messageController setRecipients:recipents];
[messageController setBody:self.message];
[self presentModalViewController:messageController animated:YES];
}
else{
UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Select the contacts you would like to share to" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[warningAlert show];
return;
}
}
#catch (NSException *exception) {
if (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone)
{
ErrorView *errorView=[[ErrorView alloc]initWithNibName:#"ErrorView" bundle:nil];
if([[[UIDevice currentDevice]systemVersion]floatValue]<5.0)
{
[self presentModalViewController:errorView animated:YES];
}
else
{
[self presentViewController:errorView animated:YES completion:nil];
}
[errorView release];
}
if (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad) {
ErrorView *errorView=[[ErrorView alloc]initWithNibName:#"ErrorView~iPad" bundle:nil];
if([[[UIDevice currentDevice]systemVersion]floatValue]<5.0)
{
[self presentModalViewController:errorView animated:YES];
}
else
{
[self presentViewController:errorView animated:YES completion:nil];
}
[errorView release];
}
} }
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult) result {
switch (result) {
case MessageComposeResultCancelled:
{
UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Failed to send SMS!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[warningAlert show];
break;
}
case MessageComposeResultFailed:
{
UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Failed to send SMS!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[warningAlert show];
break;
}
case MessageComposeResultSent:
{
NSString *messa=[NSString stringWithFormat:#"Shared to %lu contact(s)",(unsigned long)[selections count]];
UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:#"Succesful" message:messa delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[warningAlert show];
break;
}
default:
break;
}
[self dismissViewControllerAnimated:YES completion:nil];
}
This is the code Im using, which crashes sometimes and displays the error
Assertion failed: (result == KERN_SUCCESS), function +[XPCMachSendRight wrapSendRight:], file /SourceCache/XPCObjects/XPCObjects-46/XPCMachSendRight.m, line 27.
I have put breakpoint to debug, but xcode doesn't showup where the error is produced.
Any ideas/ suggestions would be appreciable..
Enable zombie Objects to find out the line of actual crash.
You can enable Zombie by following steps:
1.Select you project scheme and chose edit scheme.
2.A window will appear, now select diagnostics.
3.Select check mark for enable Zombie objects.
Now run your project.

How to access or call an action in to a function

I have the right navigation bar button action,I have set an action for it like the following:
-(IBAction)save:(id)sender
{
//Code for saving entered data
UITextField *fieldOne = [self.fields objectAtIndex:0];
UITextField *fieldTwo = [self.fields objectAtIndex:1];
UITextField *fieldThree = [self.fields objectAtIndex:2];
sqlite3_stmt *statement;
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &remindersDB) == SQLITE_OK && textField.text != nil)
{
NSString *insertSQL = [NSString stringWithFormat:#"INSERT INTO reminders(name, event, date) VALUES (\"%#\", \"%#\", \"%#\")", fieldOne.text, fieldTwo.text,fieldThree.text];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(remindersDB, insert_stmt, -1, &statement, NULL);
NSLog(#"%#",fieldOne.text);
NSLog(#"%#",fieldTwo.text);
NSLog(#"%#",fieldThree.text);
if (sqlite3_step(statement) == SQLITE_DONE)
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"\n Reminder Saved." message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
[alert show];
[alert dismissWithClickedButtonIndex:0 animated:YES];
[alert release];
}
else
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Alert" message:#"Reminder not saved" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
rowID = sqlite3_last_insert_rowid(remindersDB);
NSLog(#"last inserted rowId = %d",rowID);
sqlite3_finalize(statement);
sqlite3_close(remindersDB);
}
//Alert for not entering any data
if ([textField.text length] == 0)
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Fill Data" message:#"Please fill name,event and date of reminder" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
++self.numberOfSaves;
NSLog(#"Number of saves = %d",numberOfSaves);
[self.tableView reloadData];
}
Now I want to check how many times the button is clicked,I have an idea in mind that to create a function and used the condition
-(int)numberOfSaves
{
int saves = 0;
if(self.navigationItem.rightBarButtonItem.enabled==YES)
{
saves++;
}
return saves;
}
It's not working......
Is there anyway to check such condition,If so how can I achieve it,I am newbie to objective-c,please help me out...
Thanks all in advance :)
You cannot return from a void method.
You'd want to change -(void)numberOfSaves to -(int)numberOfSaves, if that were the right way to go about things, but I don't think this is what you want.
In your header file (.h) you'll want to declare an instance variable for the class:
#property (nonatomic, strong) NSInteger numberOfSaves;
In your implementation file (.m) make sure to synthesize it:
#synthesize numberOfSaves = _numberOfSaves;
Replace your IBAction method:
- (IBAction)save:(id)sender
{
++self.numberOfSaves;
}
And just throw away the -(void)numberOfSaves method all together. This should accomplish what I think you're trying to do. You can figure out how many saves you have committed now with self.numberOfSaves

How to create different uiactionsheet for two buttons ?

Hi here i developing small application. In a subclass screen i have two buttons. When i press the first button, it will shows four actionsheet. When i press second button it wil shows five actionsheet. I was successfully shows it. But i cant set second button actions of five actionsheet. In my code the when i press second button of first actionsheet, it wil actioned first button of first actionsheet. Here i want set actions for individual actionsheets. Pls help me. Here is my code is
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if ( indexPath.row == 0)
{
UIActionSheet *popupQuery = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:#"Edit" otherButtonTitles:#"Remove", #"Sell",#"Scrap", nil];
popupQuery.actionSheetStyle = UIActionSheetStyleBlackTranslucent;
[popupQuery showInView:self.view];
[popupQuery release];
}
if ( indexPath.row == 1 )
{
UIActionSheet *popupQuery = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:#"Unsell" otherButtonTitles:#"Edit Item", #"Edit Sale",#"Sold",#"Scrap", nil];
popupQuery.tag=5;
popupQuery.actionSheetStyle = UIActionSheetStyleBlackOpaque;
[popupQuery showInView:self.view];
[popupQuery release];
}
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0)
{
Updateasset *object=[[Updateasset alloc]initWithNibName:#"Updateasset" bundle:nil];
[self presentModalViewController:object animated:NO];
[object release];
}
else if (buttonIndex == 1)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Remove" message:#"Do you want to Remove"
delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[alert show];
[alert release];
}
else if (buttonIndex == 2)
{
Egarageselling *object=[[Egarageselling alloc]initWithNibName:#"Egarageselling" bundle:nil];
[self presentModalViewController:object animated:YES];
[object release];
}
else if (buttonIndex == 3)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Scrap" message:#"Do you want to Scrap"
delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[alert show];
[alert release];
}
else if (buttonIndex == 4)
{
}
else if (buttonIndex == 5)
{
}
else if (buttonIndex == 6)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Scrap" message:#"Do you want to Scrap"
delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[alert show];
[alert release];
}
else if (buttonIndex == 7)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Scrap" message:#"Do you want to Scrap"
delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[alert show];
[alert release];
}
else if (buttonIndex == 8)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Scrap" message:#"Do you want to Scrap"
delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[alert show];
[alert release];
}
else if (buttonIndex == 9)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Scrap" message:#"Do you want to Scrap"
delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[alert show];
[alert release];
}
}
How to solve this problem.
Set different tags for two actionsheets like
popupQuery.tag=5;
popupQuery.tag=6;
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(actionSheet.tag==5)
{
if (buttonIndex == 0)
{
}
so on
}
if(actionSheet.tag==6)
{
if (buttonIndex == 0)
{
}
so on
}
}
I might just add, that in a situation like this I would say that best practice is to make your actionsheet to public or private instance variables. It would look like this in your header file (for public):
#property (nonatomic, retain) UIActionSheet *as1;
#property (nonatomic, retain) UIActionSheet *as2;
In your implementation file you synthesize them, like this:
#synthesize as1, as2;
Then remember to set them from where you now allocate your popupQuery's today:
...
self.as1 = popupQuery;
...
...
self.as2 = popupQuery;
...
And in your delegate method you can now do it like this (which I also find more readable if I should ever present the code for another developer):
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(self.as1 == actionSheet) {
if (buttonIndex == 0) { ... }
...
}
if(self.as2 == actionSheet) {
if (buttonIndex == 0) { ... }
...
}
}
I hope you find it useful in this and many other cases. I myself, do it like that, all the time. No harm in having a public or private reference for that matter to you objects. You never know when they might come in handy.

iPhone SDK: How can you hide an alert box?

I am using the following code to show an alert box:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Info" message:#"My Message" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
Can you tell me how to hide the alert box again when the phone changes orientation?
First you have to save a reference to the alert in your interface.
#interface MyViewController : UIViewController {
UIAlertView *alert;
}
#property (nonatomic, retain) IBOutlet UIAlertView *alert;
when you create the alert you use
self.alert = [[[UIAlertView alloc] initWithTitle:#"Info" message:#"My Message" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil] autorelease];
[alert show];
and then you have to add another method didRotateFromInterfaceOrientation:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
[alert dismissWithClickedButtonIndex:[alert cancelButtonIndex] animated:YES];
self.alert = nil;
}