validation method doesn't gets called and segue doesn't gets triggered - ios

I am trying to implement a sign up process with a parse backend. I have a validation method called processFieldEntries and once the done button gets enabled, I try to trigger the segue that I setup modally from my view controller(not from the done button) from view did appear method but neither the validation method gets called nor the segue gets triggered. I setup some debug and logging breakpoints for debugging but, I couldn't go any further apart from the fact that it does not see the view did load. I also tried setting up the segue from the done button. When I did that, the segue gets triggered, not from the code but from storyboard my storyboard here. If someone can help me to figure out how to call processfieldentriees along with the segue, I would really appreciate. Thank you.
NewUserSignUpViewController.h
#import <UIKit/UIKit.h>
#import "ProfileViewController.h"
#interface NewUserSignUpViewController : UIViewController<UITextFieldDelegate>
#property (strong, nonatomic) IBOutlet UIBarButtonItem *barButtonItem;
#property (strong, nonatomic) IBOutlet UITextField *usernameField;
#property (strong, nonatomic) IBOutlet UITextField *passwordField;
#property (strong, nonatomic) IBOutlet UITextField *repeatPasswordField;
- (IBAction)doneEvent:(id)sender;
- (IBAction)cancelEvent:(id)sender;
#end
NewUserSignUpViewController.m
#import "NewUserSignUpViewController.h"
#import "ProfileViewController.h"
#import <Parse/Parse.h>
#import "ActivityView.h"
#interface NewUserSignUpViewController ()
-(void)processFieldEntries;
- (void)textInputChanged:(NSNotification *)note;
- (BOOL)shouldEnableDoneButton;
#end
#implementation NewUserSignUpViewController
#synthesize barButtonItem = _doneButtonInTheBar;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(textInputChanged:) name:UITextFieldTextDidChangeNotification object:_usernameField];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(textInputChanged:) name:UITextFieldTextDidChangeNotification object:_passwordField];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(textInputChanged:) name:UITextFieldTextDidChangeNotification object:_repeatPasswordField];
}
-(void)viewDidAppear:(BOOL)animated
{
[_usernameField becomeFirstResponder];
[super viewDidAppear:animated];
//perform the segue
if (_doneButtonInTheBar.enabled == YES) {
[self performSegueWithIdentifier:#"segueToProfileView" sender:self];
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)dealloc {
}
#pragma mark - UITextFieldDelegate
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{ textField.delegate = self;
if (textField == _usernameField) {[_usernameField becomeFirstResponder];}
if (textField == _passwordField){[_passwordField becomeFirstResponder];}
if (textField == _repeatPasswordField)
{
[_repeatPasswordField becomeFirstResponder];
[self processFieldEntries];
}
return YES;
}
-(BOOL)shouldEnableDoneButton
{
BOOL enableDoneButton = NO;
if (_usernameField.text != nil && _usernameField.text.length != 0 &&_passwordField.text != nil &&
_passwordField.text.length !=0 && _repeatPasswordField.text != nil &&
_repeatPasswordField.text.length != 0) {
enableDoneButton = YES;
[self processFieldEntries];
}
return enableDoneButton;
}
-(void)textInputChanged:(NSNotification *)note
{
_doneButtonInTheBar.enabled = [ self shouldEnableDoneButton];
}
- (IBAction)doneEvent:(id)sender {
[_usernameField resignFirstResponder];
[_passwordField resignFirstResponder];
[_repeatPasswordField resignFirstResponder];
NSLog(#"processfieldentries");
[self processFieldEntries];
}
- (IBAction)cancelEvent:(id)sender {
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)processFieldEntries
{
// Check that we have a non-zero username and passwords.
// Compare password and passwordAgain for equality
// Throw up a dialog that tells them what they did wrong if they did it wrong.
NSString *username = _usernameField.text;
NSString *password = _passwordField.text;
NSString *passwordAgain = _repeatPasswordField.text;
NSString *errorText = #"Please ";
NSString *usernameBlankText = #"enter a username";
NSString *passwordBlankText = #"enter a password";
NSString *joinText = #", and ";
NSString *passwordMismatchText = #"enter the same password twice";
BOOL textError = NO;
// Messaging nil will return 0, so these checks implicitly check for nil text.
if (username.length == 0 || password.length == 0 || passwordAgain.length == 0) {
textError = YES;
//setting the keyboard for th first missing output
if (passwordAgain.length == 0) {
[_repeatPasswordField becomeFirstResponder];
}
if (password.length == 0) {
[_passwordField becomeFirstResponder];
}
if (username.length == 0) {
[_usernameField becomeFirstResponder];
}
if (username.length == 0) {
errorText = [errorText stringByAppendingString:usernameBlankText];
}
if (password.length == 0 || passwordAgain.length == 0) {
if (username.length == 0) { // We need some joining text in the error:
errorText = [errorText stringByAppendingString:joinText];
}
errorText = [errorText stringByAppendingString:passwordBlankText];
}
}else if ([password compare:passwordAgain] != NSOrderedSame)
{errorText = [errorText stringByAppendingString:passwordMismatchText];
[_passwordField becomeFirstResponder];}
if (textError) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:errorText message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:#"Ok", nil];
[alertView show];
return;
// Everything looks good; try to log in.
// Disable the done button for now.
_doneButtonInTheBar.enabled = NO;
ActivityView *activityView = [[ActivityView alloc]initWithFrame:CGRectMake(0.f, 0.f, self.view.frame.size.width, self.view.frame.size.height)];
UILabel *label = activityView.label;
label.text = #"signing up";
label.font = [UIFont boldSystemFontOfSize:20.0f];
[activityView.activityIndicator startAnimating];
[activityView layoutSubviews];
[self.view addSubview:activityView];
// Call into an object somewhere that has code for setting up a user.
// The app delegate cares about this, but so do a lot of other objects.
// For now, do this inline.
NSLog(#"does it reach here");
PFUser *user = [PFUser user];
user.username = username;
user.password = password;
[user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[[error userInfo] objectForKey:#"error"] message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:#"Ok", nil];
[alertView show];
_doneButtonInTheBar.enabled = [self shouldEnableDoneButton];
[activityView.activityIndicator stopAnimating];
[activityView removeFromSuperview];
// Bring the keyboard back up, because they'll probably need to change something.
[_usernameField becomeFirstResponder];
return;
}
// Success!
[activityView.activityIndicator stopAnimating];
[activityView removeFromSuperview];
}];
}
}
#end

You could try not to use performSegueWithIdentifier inside viewDidAppear (performSegue actually take you to the other ViewController). Instead you could call it from an IBAction method connected to the done button, after calling in the same method processFieldEntries. I hope this can help you :)

Related

app crashes due to auto adjusting scrollView?

I am having a screen for adding a reminder. The screen is having 2 textfields and 1 textview. These all are under scrollView which is a subclass of TPAvoidingScrollView class. This class itself manages the position of scrollView and hence the components inside as the keyboard appears and disappears.
The screen is as follows.
After I have gone through all the fields and selected certain values. By clicking on Add reminder the event is added into the main calendar and the screen pops out to the previous screen. And then problem starts to occur. As soon as I again comes to this screen and tapping on the Textview Notes the app crashes with these errors.
Here Reminder view controller is the name of the class
The code for the whole class is:
#import "ReminderViewController.h"
#import <EventKit/EventKit.h>
#import "ActionSheetPicker.h"
#import "NSDate-Utilities.h"
#interface ReminderViewController ()
#end
#implementation ReminderViewController
#synthesize scrollView;
#synthesize txt_notes;
#synthesize txt_remindOn;
#synthesize txt_repeatAlarm;
#synthesize btn_appointment;
#synthesize btn_pickup;
#synthesize btn_reminder;
#synthesize txt_currentFocussedTextField;
#synthesize selectedDate;
#synthesize arr_repeatAlarm;
#synthesize selectedIndex;
#synthesize isSelected;
#synthesize str_eventTitle;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.scrollView.contentSize = CGSizeMake(320, 520);
self.selectedDate = [NSDate date];
self.arr_repeatAlarm = [NSArray arrayWithObjects:#"None",#"Every Day", #"Every Week",
#"Every Month", #"Every year", nil];
btn_reminder.backgroundColor =[UIColor colorWithRed:0.0/255 green:89.0/255 blue:178.0/255
alpha:1.0f];
[[AppDelegate sharedInstance] setUpHighlightedStateOfButton:btn_reminder];
// Do any additional setup after loading the view.
}
#pragma mark - Check button click methods
-(IBAction)btn_appointment_click:(id)sender{
if(btn_appointment.selected){
[btn_appointment setSelected:NO];
[btn_pickup setSelected:YES];
isSelected = NO;
}
else{
[btn_appointment setSelected:YES];
[btn_pickup setSelected:NO];
isSelected = YES;
}
}
-(IBAction)btn_pickup_click:(id)sender{
if(btn_pickup.selected){
[btn_pickup setSelected:NO];
[btn_appointment setSelected:YES];
isSelected = NO;
}
else{
[btn_pickup setSelected:YES];
[btn_appointment setSelected:NO];
isSelected = YES;
}
}
#pragma mark - calendar Event methods
- (IBAction)btn_reminder_click:(id)sender{
[self addEventTocalendar:sender];
}
- (void)addEventTocalendar:(id)sender{
EKEventStore *store = [[EKEventStore alloc] init];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError
*error) {
if (!granted) { return; }
EKEvent *event = [EKEvent eventWithEventStore:store];
event.title = #"Pickup Reminder";
event.startDate = self.selectedDate;
event.endDate = [event.startDate dateByAddingTimeInterval:60*60];//set 1 hour meeting
event.notes = txt_notes.text;
event.recurrenceRules = EKRecurrenceFrequencyDaily;
[event addAlarm:[EKAlarm alarmWithRelativeOffset:60.0f * -5.0f]];
if (selectedIndex == 1) {
[event addRecurrenceRule:[[EKRecurrenceRule
alloc]initRecurrenceWithFrequency:EKRecurrenceFrequencyDaily interval:1 end:Nil]];
}
else if (selectedIndex == 2){
[event addRecurrenceRule:[[EKRecurrenceRule
alloc]initRecurrenceWithFrequency:EKRecurrenceFrequencyWeekly interval:1 end:Nil]];
}
else if (selectedIndex == 3){
[event addRecurrenceRule:[[EKRecurrenceRule
alloc]initRecurrenceWithFrequency:EKRecurrenceFrequencyMonthly interval:1 end:Nil]];
}
else if (selectedIndex == 4){
[event addRecurrenceRule:[[EKRecurrenceRule
alloc]initRecurrenceWithFrequency:EKRecurrenceFrequencyYearly interval:1 end:Nil]];
}
[event setCalendar:[store defaultCalendarForNewEvents]];
NSError *err = nil;
[store saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
NSString *savedEventId = event.eventIdentifier; //this is so you can access this
event later
BOOL isSuceess=[store saveEvent:event span:EKSpanThisEvent error:&err];
// This needs to be done as the UIKIT was getting called from the seconadary thread
and therefore to show the alert view in the main thread and to prevent the hanging of
the app I have to call the Aletview method in the main thread.
// i.e dispatch the event in the main thread
if(isSuceess){
UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:#"Event"
message:#"Event added in calendar" delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
dispatch_async(dispatch_get_main_queue(), ^{
[alertview show];
});
}
else {
UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:#"Event" message:[err
description] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
dispatch_async(dispatch_get_main_queue(), ^{
[alertview show];
});
}
}];
}
- (void)back{
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark - UIAlertViewDelegate methods
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark - Implementation methods
- (void)serviceWasSelected:(NSNumber *)selectedIndex element:(id)element {
self.selectedIndex = [selectedIndex intValue];
//may have originated from textField or barButtonItem, use an IBOutlet instead of element
self.txt_repeatAlarm.text = [self.arr_repeatAlarm objectAtIndex:self.selectedIndex];
}
- (void)dateWasSelected:(NSDate *)selectedDate element:(id)element{ //indexpath:
(NSIndexPath *)indexpath{
UITextField * textfield = (UITextField *)element;
if (textfield == self.txt_remindOn) {
self.selectedDate = selectedDate;
self.txt_remindOn.text = [self.selectedDate getDateStringInFormat:#"dd MMM yyyy
hh:mm aa"];
}
}
#pragma mark - TextField Delegate Methods
- (void)textFieldDidBeginEditing:(UITextField *)textField{
self.txt_currentFocussedTextField = textField;
[[AppDelegate sharedInstance] addToolbarForKeyboard:textField];
if (textField == self.txt_remindOn) {
[textField resignFirstResponder];
_actionSheetPicker = [[ActionSheetDatePicker alloc] initWithTitle:#""
datePickerMode:UIDatePickerModeDateAndTime selectedDate:self.selectedDate
minimumDate:[NSDate
date] maximumDate:Nil target:self action:#selector(dateWasSelected:element:)
origin:textField];
self.actionSheetPicker.hideCancel = NO;
[self.actionSheetPicker showActionSheetPicker];
}
if (textField == self.txt_repeatAlarm) {
[textField resignFirstResponder];
[ActionSheetStringPicker showPickerWithTitle:#"" rows:self.arr_repeatAlarm
initialSelection:self.selectedIndex target:self
successAction:#selector(serviceWasSelected:element:)
cancelAction:#selector(actionPickerCancelled:) origin:textField];
}
}
// making the keyboard disappear on pressing the Done button on the keyboard.
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return NO;
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range
replacementText:(NSString *)text {
if([text isEqualToString:#"\n"]) {
[textView resignFirstResponder];
return NO;
}
return YES;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end

Clean array by using delegate

I made an AR app that recognize image and show the object recognized in an AlertView. In the AlertView I have 2 buttons: Add and Cancel, I'm using the UIAlertViewDelegate to understand which button the user pressed. If the user press the Add button, the object recognized will be stored in an array. I pass this array to another ViewController, in which I set up a TableView. On the bottom of this TableView there's a button "Pay" to go to another ViewController in which I display the total price of the object recognized. From the last ViewController I can press a button to pay the objects I selected by using the AR. Now when I press this button the app close this ViewController and go back to the first ViewController, but the array in which I stored the object that the AR recognized it's full. To delete the content of this array I thought that the best way is to use the delegation methods, so I made this:
PaymentViewController.h
#import <UIKit/UIKit.h>
#protocol PaymentViewControllerDelegate;
#interface PaymentViewController : UIViewController
#property (strong, nonatomic) IBOutlet UILabel *labelTotal;
- (IBAction)buttonClosePaymentVC:(id)sender;
- (IBAction)buttonPay:(id)sender;
#property(nonatomic,strong)NSString *total;
#property(assign) id<PaymentViewControllerDelegate> delegate;
#end
#protocol PaymentViewControllerDelegate <NSObject>
- (void)cleanReportArray;
#end
PaymentViewController.m
#import "PaymentViewController.h"
#interface PaymentViewController () <UIAlertViewDelegate>
#end
#implementation PaymentViewController
#synthesize delegate = _delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.labelTotal.text = self.total;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)buttonClosePaymentVC:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)buttonPay:(id)sender {
NSString *pay = [NSString stringWithFormat:#"Stai per pagare %#, procedi?", self.total];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"HelloMS" message:pay delegate:self cancelButtonTitle:#"Si" otherButtonTitles:#"No", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
// Procedura per il pagamento e cancellazione del file plist
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"objects.plist"];
NSError *error;
if (![[NSFileManager defaultManager]removeItemAtPath:path error:&error]) {
NSLog(#"Errore: %#", error);
}
__weak UIViewController *vcThatPresentedCurrent = self.presentingViewController;
[self dismissViewControllerAnimated:YES completion:^{
[vcThatPresentedCurrent dismissViewControllerAnimated:YES completion:nil];
}];
[self.delegate cleanReportArray];
}
if (buttonIndex == 1) {
// Non deve far nulla: fa scomparire l'UIAlertView
}
}
Here I post to you the method of the class that will use the delegate:
Interface of the ScannerViewController.m
#interface ScannerViewController () <MSScannerSessionDelegate, PaymentViewControllerDelegate, UIActionSheetDelegate, UIAlertViewDelegate>
#property (weak) IBOutlet UIView *videoPreview;
- (IBAction)stopScanner:(id)sender;
#end
In ViewDidLoad I inserted this rows:
PaymentViewController *pay = [[PaymentViewController alloc]init];
[pay setDelegate:self];
And in the ScannerViewController.m I implemented the method I declared in PaymentViewController.h:
- (void)cleanReportArray {
[arrayObjectAdded removeAllObjects];
}
I tested my app on my iPhone, the app works fine until I try to pay the objects I scanned by camera, indeed, I tried to pay the object, but it doesn't clean the array in which I stored the objects scanned.
What's wrong in my code? I used an tutorial on the web to understand better how the delegation method works. I hope you can help me to fix this issue, thank you
UPDATE:
here i will post my ScannerViewController code:
ScannerViewController.h
#import <UIKit/UIKit.h>
#interface ScannerViewController : UIViewController
#end
ScannerViewController.m
#import "ScannerViewController.h"
#import "PaymentViewController.h"
#import "ReportViewController.h"
#import "MSScannerSession.h"
#import "MSResult.h"
#import "XmlReader.h"
static int kMSScanOptions = MS_RESULT_TYPE_IMAGE |
MS_RESULT_TYPE_EAN8 |
MS_RESULT_TYPE_EAN13;
#interface ScannerViewController () <MSScannerSessionDelegate, PaymentViewControllerDelegate, UIActionSheetDelegate, UIAlertViewDelegate>
#property (weak) IBOutlet UIView *videoPreview;
- (IBAction)stopScanner:(id)sender;
#end
#implementation ScannerViewController {
MSScannerSession *_scannerSession;
NSString *nameOfObjectScanned;
XmlReader *reader;
NSMutableArray *arrayObjectAdded;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
_scannerSession = [[MSScannerSession alloc] initWithScanner:[MSScanner sharedInstance]];
[_scannerSession setScanOptions:kMSScanOptions];
[_scannerSession setDelegate:self];
}
return self;
}
- (void)session:(MSScannerSession *)scanner didScan:(MSResult *)result {
if (!result) {
return;
}
[_scannerSession pause];
NSString *resultStr = nil;
if (result) {
switch ([result getType]) {
case MS_RESULT_TYPE_IMAGE:
resultStr = [NSString stringWithFormat:#"Immagine trovata: %#", [result getValue]];
break;
case MS_RESULT_TYPE_EAN8:
case MS_RESULT_TYPE_EAN13:
resultStr = [NSString stringWithFormat:#"EAN trovato: %#", [result getValue]];
break;
default:
break;
}
}
dispatch_async(dispatch_get_main_queue(), ^{
UIActionSheet *asView = [[UIActionSheet alloc]initWithTitle:resultStr delegate:self cancelButtonTitle:#"OK" destructiveButtonTitle:nil otherButtonTitles:nil, nil];
asView.actionSheetStyle = UIActionSheetStyleBlackTranslucent;
[asView showInView:self.view];
[self addObjectToList:resultStr];
});
}
- (void)addObjectToList:(NSString *)objectName {
// Ricerca dell'oggetto
NSString *object = [objectName substringFromIndex:18];
if ([object isEqualToString:#"Binario_con_coppia"]) {
[self showAlert:object];
}
if ([object isEqualToString:#"Dadi_colorati"]) {
[self showAlert:object];
}
if ([object isEqualToString:#"Dadi_rossi"]) {
[self showAlert:object];
}
if ([object isEqualToString:#"Bici_da_corsa"]) {
[self showAlert:object];
}
}
- (void)showAlert:(NSString*)name {
name = [name stringByReplacingOccurrencesOfString:#"_" withString:#" "];
nameOfObjectScanned = name;
NSString *message = [NSString stringWithFormat:#"Ho riconosciuto questo oggetto: %#, vuoi aggiungerlo al carrello?", name];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"HelloMS" message:message delegate:self cancelButtonTitle:#"Aggiungi" otherButtonTitles:#"Annulla", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSLog(#"Aggiungi");
for (int i = 0; i < [reader.objArray count]; i++) {
if ([[reader.objArray[i]objectForKey:#"name"] isEqualToString:nameOfObjectScanned]) {
// Salvo il nome dell'oggetto trovato, il prezzo e la descrizione
NSString *name = [reader.objArray[i]objectForKey:#"name"];
NSString *desc = [reader.objArray[i]objectForKey:#"desc"];
NSString *price = [reader.objArray[i]objectForKey:#"price"];
NSDictionary *newObjectAdded = [[NSDictionary alloc]init];
newObjectAdded = #{#"name": name,
#"desc": desc,
#"price": price};
[arrayObjectAdded addObject:newObjectAdded];
}
}
} else {
NSLog(#"Annulla");
}
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
[_scannerSession resume];
}
- (void)viewDidLoad
{
[super viewDidLoad];
arrayObjectAdded = [[NSMutableArray alloc]init];
CALayer *videoPreviewLayer = [self.videoPreview layer];
[videoPreviewLayer setMasksToBounds:YES];
CALayer *captureLayer = [_scannerSession previewLayer];
[captureLayer setFrame:[self.videoPreview bounds]];
[videoPreviewLayer insertSublayer:captureLayer below:[[videoPreviewLayer sublayers] objectAtIndex:0]];
reader = [[XmlReader alloc]init];
[reader parseXml];
[_scannerSession startCapture];
PaymentViewController *pay = [[PaymentViewController alloc]init];
[pay setDelegate:self];
}
- (void)cleanReportArray {
[arrayObjectAdded removeAllObjects];
}
- (void)dealloc {
[_scannerSession stopCapture];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)stopScanner:(id)sender {
ReportViewController *reportVC = [[ReportViewController alloc]initWithNibName:#"ReportViewController" bundle:nil];
reportVC.reportArray = arrayObjectAdded;
[reportVC setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentViewController:reportVC animated:YES completion:nil];
}
#end
To recognize picture I'm using this AR SDK. I hope you can help me to understand where's my issue
Your problem is that in viewDidLoad you have the code:
PaymentViewController *pay = [[PaymentViewController alloc]init];
[pay setDelegate:self];
this is the last thing you do in that method. So the instance of PaymentViewController that you create and set the delegate on is immediately destroyed (by ARC).
You need to modify your code so that you call setDelegate: on the actual instance of PaymentViewController that is presented on screen as this is the instance that needs to use the delegate (it receives the callback from the alert view).

Code does not wait for user to finish typing in the repeat password section

I am trying to setup a signup view with using parse.com as backend but for some reason whenever i start typing in the reenter password field, as soon as i type something, it starts going through this
else if ([password compare:passwordAgain] != NSOrderedSame) {
// We have non-zero strings.
// Check for equal password strings.
textError = YES;
errorText = [errorText stringByAppendingString:passwordMismatchText];
[_reEnterPasswordField becomeFirstResponder];
NSLog(#"stops here");
}
method and sends me the error message passwordMismatchText. It goes through this message everytime i change a word whether i added or deleted it. When I use the same methods with xib the files i had no problem. But after I try to do the same thing with storyboards I am having this issue. I tried creating a user default for _doneButton.enabled == YES and put an another if around the errorText =[...] message, but did not solve the problem. I appreciate for the help.
SignUpViewController.h
#import <UIKit/UIKit.h>
#interface SignUpViewController : UIViewController<UITextFieldDelegate>
#property (weak, nonatomic) IBOutlet UIBarButtonItem *doneButton;
#property (weak, nonatomic) IBOutlet UITextField *userNameField;
#property (weak, nonatomic) IBOutlet UITextField *passwordField;
#property (weak, nonatomic) IBOutlet UITextField *reEnterPasswordField;
- (IBAction)done:(id)sender;
- (IBAction)cancel:(id)sender;
#end
SignUpViewController.m
#import "SignUpViewController.h"
#import <Parse/Parse.h>
#import "ActivityView.h"
#import "ProfileViewController.h"
#interface SignUpViewController ()
- (void)textInputChanged:(NSNotification *)note;
-(void)processFieldEntries;
- (BOOL)shouldEnableDoneButton;
#end
#implementation SignUpViewController
#synthesize doneButton = _doneButton;
#synthesize userNameField = _userNameField;
#synthesize passwordField = _passwordField;
#synthesize reEnterPasswordField = _reEnterPasswordField;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter ]addObserver:self selector:#selector(textInputChanged:) name: UITextFieldTextDidChangeNotification object:_userNameField];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(textInputChanged:) name:UITextFieldTextDidChangeNotification object:_passwordField];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(textInputChanged:) name:UITextFieldTextDidChangeNotification object:_reEnterPasswordField];
_doneButton.enabled = NO;
NSLog(#"nsnotification is working fine");
}
-(void)viewWillAppear:(BOOL)animated
{
[_userNameField becomeFirstResponder];
[super viewWillAppear:animated];
NSLog(#"indeed usernamefield became a first responder");
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField == _userNameField ) {
[_userNameField becomeFirstResponder];
}
if (textField == _passwordField) {
[_passwordField becomeFirstResponder];
}
if (textField == _reEnterPasswordField)
{
[_reEnterPasswordField becomeFirstResponder];
}
NSLog(#"keyboard action works fine ");
return YES;
}
-(BOOL)shouldEnableDoneButton
{
BOOL enableDoneButton = NO;
if (_userNameField.text != nil &&
_userNameField.text.length > 0 &&
_passwordField.text != nil &&
_passwordField.text.length > 0 &&
_reEnterPasswordField.text != nil &&
_reEnterPasswordField.text.length > 0)
{
[self processFieldEntries];
enableDoneButton = YES;
NSLog(#"done button enabled");
}
return enableDoneButton;
}
-(void)textInputChanged:(NSNotification *)note
{
_doneButton.enabled = [self shouldEnableDoneButton];
}
- (IBAction)done:(id)sender {
[_userNameField resignFirstResponder];
[_passwordField resignFirstResponder];
[_reEnterPasswordField resignFirstResponder];
[self processFieldEntries];
NSLog(#"do you see this");
}
- (IBAction)cancel:(id)sender
{
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
-(void)processFieldEntries
{
// Check that we have a non-zero username and passwords.
// Compare password and passwordAgain for equality
// Throw up a dialog that tells them what they did wrong if they did it wrong.
NSString *username = _userNameField.text;
NSString *password = _passwordField.text;
NSString *passwordAgain = _reEnterPasswordField.text;
NSString *errorText = #"Please ";
NSString *usernameBlankText = #"enter a username";
NSString *passwordBlankText = #"enter a password";
NSString *joinText = #", and ";
NSString *passwordMismatchText = #"enter the same password twice";
BOOL textError = NO;
NSLog(#"validation begins here");
// Messaging nil will return 0, so these checks implicitly check for nil text.
if (username.length == 0 || password.length == 0 || passwordAgain.length == 0) {
textError = YES;
// Set up the keyboard for the first field missing input:
if (passwordAgain.length == 0) {
[_reEnterPasswordField becomeFirstResponder];
}
if (password.length == 0) {
[_passwordField becomeFirstResponder];
}
if (username.length == 0) {
[_userNameField becomeFirstResponder];
}
if (username.length == 0) {
errorText = [errorText stringByAppendingString:usernameBlankText];
}
if (password.length == 0 || passwordAgain.length == 0) {
if (username.length == 0) { // We need some joining text in the error:
errorText = [errorText stringByAppendingString:joinText];
}
errorText = [errorText stringByAppendingString:passwordBlankText];
}
} else if ([password compare:passwordAgain] != NSOrderedSame) {
// We have non-zero strings.
// Check for equal password strings.
textError = YES;
errorText = [errorText stringByAppendingString:passwordMismatchText];
[_reEnterPasswordField becomeFirstResponder];
NSLog(#"stops here");
}
if (textError) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:errorText message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:#"Ok", nil];
[alertView show];
return;
}
NSLog(#"validation works just fine");
// Everything looks good; try to log in.
// Disable the done button for now.
_doneButton.enabled = NO;
ActivityView *activityCircle = [[ActivityView alloc] initWithFrame:CGRectMake(0.f, 0.f, self.view.frame.size.width, self.view.frame.size.height)];
UILabel *label = activityCircle.label;
label.text = #"Signing You Up";
label.font = [UIFont boldSystemFontOfSize:20.f];
[activityCircle.activityIndicator startAnimating];
[activityCircle layoutSubviews];
[self.view addSubview:activityCircle];
NSLog(#"activity view works just fine");
//parse registeration
// Call into an object somewhere that has code for setting up a user.
// The app delegate cares about this, but so do a lot of other objects.
// For now, do this inline.
PFUser *user = [PFUser user];
user.username = username;
user.password = password;
[user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[[error userInfo] objectForKey:#"error"] message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:#"Ok", nil];
[alertView show];
_doneButton.enabled = [self shouldEnableDoneButton];
[activityCircle.activityIndicator stopAnimating];
[activityCircle removeFromSuperview];
// Bring the keyboard back up, because they'll probably need to change something.
[_userNameField becomeFirstResponder];
return;
}
// Success!
[activityCircle.activityIndicator stopAnimating];
[activityCircle removeFromSuperview];
//add the next screen here
}];
NSLog(#"user signedup just fine");
//now pass the view from sign up to profile view
}
/*
//this one didnt work
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
ProfileViewController *myProfileView = [segue destinationViewController];
if (_doneButton.enabled == YES) {
[myProfileView performSegueWithIdentifier:#"SignUpSegue" sender:_doneButton];
}
}
*/
-(BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
NSLog(#"is this method visible");
if (_doneButton.enabled == YES) {
[self performSegueWithIdentifier:#"SignUpSegue" sender:_doneButton];
}
return NO;
}
#end
this is the log files that I am getting
2013-09-06 02:49:19.938 nsnotification is working fine
2013-09-06 02:49:19.942 indeed usernamefield became a first responder
2013-09-06 02:49:47.446 validation begins here
2013-09-06 02:49:47.448 stops here
2013-09-06 02:49:47.485 done button enabled
2013-09-06 02:49:49.271 validation begins here
2013-09-06 02:49:49.273 stops here
2013-09-06 02:49:49.296 done button enabled
2013-09-06 02:49:51.257 validation begins here
2013-09-06 02:49:51.259 validation works just fine
2013-09-06 02:49:51.265 activity view works just fine
2013-09-06 02:49:51.270 user signedup just fine
2013-09-06 02:49:51.271 done button enabled
You are triggering the code to run by your observation of UITextFieldTextDidChangeNotification. As this moves through your methods you eventually call processFieldEntries. Probably you shouldn't be calling processFieldEntries from shouldEnableDoneButton.

Background audio wont play

I'm struggling for couple of days now to sort this thing out and simply just can't find the way. I want to play audio in background when app exits or when i click on link to go to Safari, but i just wont go to background mode. Please help.
FirstViewController.h file :
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVAudioPlayer.h>
#import <AVFoundation/AVFoundation.h>
#interface RygestopFirstViewController : UIViewController <AVAudioPlayerDelegate> {
IBOutlet UIButton *playButton;
IBOutlet UISlider *volumeSlider;
IBOutlet UISlider *progressBar;
IBOutlet UILabel *currentTime;
IBOutlet UILabel *duration;
AVAudioPlayer *player;
UIImage *playBtnBG;
UIImage *pauseBtnBG;
NSTimer *updateTimer;
BOOL inBackground;
}
- (IBAction)playButtonPressed:(UIButton*)sender;
- (IBAction)volumeSliderMoved:(UISlider*)sender;
- (IBAction)progressSliderMoved:(UISlider*)sender;
#property (nonatomic, retain) UIButton *playButton;
#property (nonatomic, retain) UISlider *volumeSlider;
#property (nonatomic, retain) UISlider *progressBar;
#property (nonatomic, retain) UILabel *currentTime;
#property (nonatomic, retain) UILabel *duration;
#property (nonatomic, retain) NSTimer *updateTimer;
#property (nonatomic, assign) AVAudioPlayer *player;
#property (nonatomic, assign) BOOL inBackground;
#end
FirstViewController.m code:
// amount to skip on rewind or fast forward
#define SKIP_TIME 1.0
// amount to play between skips
#define SKIP_INTERVAL .2
#implementation RygestopFirstViewController
#synthesize playButton;
#synthesize volumeSlider;
#synthesize progressBar;
#synthesize currentTime;
#synthesize duration;
#synthesize updateTimer;
#synthesize player;
#synthesize inBackground;
-(void)updateCurrentTimeForPlayer:(AVAudioPlayer *)p
{
currentTime.text = [NSString stringWithFormat:#"%d:%02d", (int)p.currentTime / 60, (int)p.currentTime % 60, nil];
progressBar.value = p.currentTime;
}
- (void)updateCurrentTime
{
[self updateCurrentTimeForPlayer:self.player];
}
- (void)updateViewForPlayerState:(AVAudioPlayer *)p
{
[self updateCurrentTimeForPlayer:p];
if (updateTimer)
[updateTimer invalidate];
if (p.playing)
{
[playButton setImage:((p.playing == YES) ? pauseBtnBG : playBtnBG) forState:UIControlStateNormal];
updateTimer = [NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:#selector(updateCurrentTime) userInfo:p repeats:YES];
}
else
{
[playButton setImage:((p.playing == YES) ? pauseBtnBG : playBtnBG) forState:UIControlStateNormal];
updateTimer = nil;
}
}
- (void)updateViewForPlayerStateInBackground:(AVAudioPlayer *)p
{
[self updateCurrentTimeForPlayer:p];
if (p.playing)
{
[playButton setImage:((p.playing == YES) ? pauseBtnBG : playBtnBG) forState:UIControlStateNormal];
}
else
{
[playButton setImage:((p.playing == YES) ? pauseBtnBG : playBtnBG) forState:UIControlStateNormal];
}
}
-(void)updateViewForPlayerInfo:(AVAudioPlayer*)p
{
duration.text = [NSString stringWithFormat:#"%d:%02d", (int)p.duration / 60, (int)p.duration % 60, nil];
progressBar.maximumValue = p.duration;
volumeSlider.value = p.volume;
}
-(void)pausePlaybackForPlayer:(AVAudioPlayer*)p
{
[p pause];
[self updateViewForPlayerState:p];
}
-(void)startPlaybackForPlayer:(AVAudioPlayer*)p
{
if ([p play])
{
[self updateViewForPlayerState:p];
}
else
NSLog(#"Could not play %#\n", p.url);
}
- (IBAction)playButtonPressed:(UIButton *)sender
{
if (player.playing == YES)
[self pausePlaybackForPlayer: player];
else
[self startPlaybackForPlayer: player];
}
- (IBAction)volumeSliderMoved:(UISlider *)sender
{
player.volume = [sender value];
}
- (IBAction)progressSliderMoved:(UISlider *)sender
{
player.currentTime = sender.value;
[self updateCurrentTimeForPlayer:player];
}
- (void)dealloc
{
[super dealloc];
[playButton release];
[volumeSlider release];
[progressBar release];
[currentTime release];
[duration release];
[updateTimer release];
[player release];
[playBtnBG release];
[pauseBtnBG release];
}
#pragma mark AVAudioPlayer delegate methods
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)p successfully:(BOOL)flag
{
if (flag == NO)
NSLog(#"Playback finished unsuccessfully");
[p setCurrentTime:0.];
if (inBackground)
{
[self updateViewForPlayerStateInBackground:p];
}
else
{
[self updateViewForPlayerState:p];
}
}
- (void)playerDecodeErrorDidOccur:(AVAudioPlayer *)p error:(NSError *)error
{
NSLog(#"ERROR IN DECODE: %#\n", error);
}
// we will only get these notifications if playback was interrupted
- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)p
{
NSLog(#"Interruption begin. Updating UI for new state");
// the object has already been paused, we just need to update UI
if (inBackground)
{
[self updateViewForPlayerStateInBackground:p];
}
else
{
[self updateViewForPlayerState:p];
}
}
- (void)audioPlayerEndInterruption:(AVAudioPlayer *)p
{
NSLog(#"Interruption ended. Resuming playback");
[self startPlaybackForPlayer:p];
}
#pragma mark background notifications
- (void)registerForBackgroundNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(setInBackgroundFlag)
name:UIApplicationWillResignActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(clearInBackgroundFlag)
name:UIApplicationWillEnterForegroundNotification
object:nil];
}
- (void)setInBackgroundFlag
{
inBackground = true;
}
- (void)clearInBackgroundFlag
{
inBackground = false;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"Play", #"First");
self.tabBarItem.image = [UIImage imageNamed:#"Home"];
}
return self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
//Make sure we can recieve remote control events
- (BOOL)canBecomeFirstResponder {
return YES;
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
playBtnBG = [[UIImage imageNamed:#"Player.png"] retain];
pauseBtnBG = [[UIImage imageNamed:#"Pause.png"] retain];
[playButton setImage:playBtnBG forState:UIControlStateNormal];
[self registerForBackgroundNotifications];
updateTimer = nil;
duration.adjustsFontSizeToFitWidth = YES;
currentTime.adjustsFontSizeToFitWidth = YES;
progressBar.minimumValue = 0.0;
// Load the the sample file, use mono or stero sample
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: [[NSBundle mainBundle] pathForResource:#"Sound1" ofType:#"m4a"]];
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
if (self.player)
{
[self updateViewForPlayerInfo:player];
[self updateViewForPlayerState:player];
player.numberOfLoops = 0;
player.delegate = self;
}
[fileURL release];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#end
And, by the way, i want to run thin in tab bar application, so the background mode must be present always.
Here's what you're looking for: https://devforums.apple.com/message/264397 and set your background mode to 'App plays audio' in your app's .plist file.

How to add a textfield to an NSMutableArray

I'm trying to present what was entered into a textfield into a nsmutable array that will later be displayed.
I think that the problem is in the -(void)viewDidLoad method but I included all of the code just in case. The catch is that I will be leaving this page and then returning to it after another piece of information is selected. As this happens, I need to keep track of EACH thing that was entered into the textfield. Thanks for any help!
#import "EnteringCoursesViewController.h"
#import "SelectRotationController.h"
#implementation EnteringCoursesViewController
#synthesize classField;
#synthesize indicatedClass;
#synthesize labelClassTitle;
#synthesize selectRotationController;
#synthesize classesEnteredTable;
- (IBAction)chooseType {
UIActionSheet *typeSheet = [[UIActionSheet alloc]
initWithTitle:#"Class types"
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:#"Core Class", #"Elective", nil];
[typeSheet showInView:self.view];
[typeSheet release];
}
- (void)actionSheet:(UIActionSheet *)typeSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0) {
self.indicatedClass = classField.text;
NSString *indicatedString = indicatedClass;
NSString *greeting = [[NSString alloc]
initWithFormat:#"%# meets 6 times per rotation", indicatedString];
labelClassTitle.text = greeting;
labelClassTitle.hidden = NO;
[greeting release];
[indicatedClass release];
}
else if (buttonIndex == 1) {
self.indicatedClass = classField.text;
NSString *indicatedString = indicatedClass;
NSString *greeting = [[NSString alloc]
initWithFormat:#"%# meets 3 times per rotation", indicatedString];
labelClassTitle.text = greeting;
labelClassTitle.hidden = NO;
[greeting release];
[indicatedClass release];
}
}
- (IBAction)chooseFirstMeeting:(id)sender {
SelectRotationController *selectView = [[SelectRotationController alloc]
initWithNibName:#"SelectRotationController"
bundle:[NSBundle mainBundle]];
[selectView.navigationItem setTitle:#"First Period Day Choose"];
[self.navigationController pushViewController:self.selectRotationController animated:YES];
self.selectRotationController = selectView;
[selectView release];
}
- (IBAction)enteredClassText:(id)sender {
NSMutableArray *classesEntered = [[NSMutableArray alloc] init];
[classesEntered addObject:indicatedClass];
[classesEntered release];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidLoad {
self.navigationItem.hidesBackButton = YES;
[super viewDidLoad];
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[classField release];
[labelClassTitle release];
[indicatedClass release];
[selectRotationController release];
[classesEnteredTable release];
[super dealloc];
}
#end
If viewDidLoad is called "indicatedClass" is not yet initialised and therefore nil.
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/Reference/Reference.html
Important Raises an NSInvalidArgumentException if anObject is nil.
If you want to save that by leaving the view, add the addObject-Call in the viewDidUnload-method. Definitely you should check if the value is nil ;)
I dont see any alloc for your variable indicatedClass but an release!? It might be that the variable doesnt exists if viewDidUnload is calling.
EDIT
You init an NSMutableArray, add the object to this array and after that you released that object. Therefore the Data is away. You must save your array therewith you can use the content later. Keyword: NSUserDefaults ;)
Check also of nil values:
- (IBAction)enteredClassText:(id)sender {
if (indicatedClass != nil) {
NSMutableArray *classesEntered = [[NSMutableArray alloc] init];
[classesEntered addObject:indicatedClass];
[classesEntered release];
}
}
If the sender is an UILabel you can also use this snippet:
- (IBAction)enteredClassText:(id)sender {
if (sender.text != nil) {
NSMutableArray *classesEntered = [NSMutableArray arrayWithObject:sender.text];
// TODO: Save your array to NSUserDefaults...
}
}

Resources