I have developed this class that is basically a UIAlertView with an input field that runs on blocks. So, whatever the user does on the alertView (click cancel, ok, or fill the text), returns to a block:
HEADER
typedef void (^onClickBlock)(NSInteger buttonIndex, NSString *textoInput);
#interface AlertViewBlocoComInput : NSObject
- (void)mostrarAlertViewBlocoComTitulo:(NSString *)titulo
mensagem:(NSString *)mensagem
tituloBotaoCancel:(NSString *)tituloCancel
outrosBotoesArray:(NSArray *)titulosOutrosBotoes
inputComPlaceHolder:(NSString *)textoPlaceholder
comBlocoExecucao:(onClickBlock)bloco;
#end
IMPLEMENTATION
#interface AlertComBloco : UIAlertView
#property (nonatomic, copy) onClickBlock runOnClickBlock;
#end
#implementation AlertComBloco
#end
#interface AlertViewBlocoComInput () <UIAlertViewDelegate>
#end
#implementation AlertViewBlocoComInput
- (void)mostrarAlertViewBlocoComTitulo:(NSString *)titulo
mensagem:(NSString *)mensagem
tituloBotaoCancel:(NSString *)tituloCancel
outrosBotoesArray:(NSArray *)titulosOutrosBotoes
inputComPlaceHolder:(NSString *)textoPlaceholder
comBlocoExecucao:(onClickBlock)bloco
{
AlertComBloco *alerta = [[AlertComBloco alloc] initWithTitle:titulo
message:mensagem
delegate:self
cancelButtonTitle:tituloCancel
otherButtonTitles:nil];
alerta.runOnClickBlock =bloco;
// adicionar os outros botões
for (NSString *umOutroBotao in titulosOutrosBotoes) {
[alerta addButtonWithTitle:umOutroBotao];
}
[alerta setAlertViewStyle:UIAlertViewStylePlainTextInput];
UITextField *input = [alerta textFieldAtIndex:0];
input.placeholder = textoPlaceholder;
[alerta show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
AlertComBloco *alerta = (AlertComBloco *)alertView;
onClickBlock bloco = alerta.runOnClickBlock;
UITextField *input = [alertView textFieldAtIndex:0];
if (bloco) {
bloco(buttonIndex, input.text);
}
}
#end
I run it, it shows the alertView with the message, placeholder, perfect. I click cancel or fill the text and press ok and the alertview:clickedButtonAtIndex: is never triggered. I am not seeing why.
thanks
You can directly subclass UIAlertView and add your own initializer. I have abstracted your classes to a single subclass of UIAlertView and it works fine. Please see my posts below,
typedef void (^onClickBlock)(NSInteger buttonIndex, NSString *textoInput);
#interface AlertComBloco : UIAlertView<UIAlertViewDelegate>
#property (nonatomic, copy) onClickBlock runOnClickBlock;
#end
#implementation AlertComBloco
- (id)initWithTitulo:(NSString *)titulo mensagem:(NSString*)mensagem tituloBotaoCancel:(NSString*)tituloCancel outrosBotoesArray:(NSArray *)titulosOutrosBotoes inputComPlaceHolder:(NSString *)textoPlaceholder
comBlocoExecucao:(onClickBlock)bloco{
if(self = [self initWithTitle:titulo message:mensagem delegate:self cancelButtonTitle:tituloCancel otherButtonTitles:nil, nil]){
_runOnClickBlock = bloco;
for (NSString *umOutroBotao in titulosOutrosBotoes) {
[self addButtonWithTitle:umOutroBotao];
}
[self setAlertViewStyle:UIAlertViewStylePlainTextInput];
UITextField *input = [self textFieldAtIndex:0];
input.placeholder = textoPlaceholder;
}
return self;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
UITextField *input = [alertView textFieldAtIndex:0];
if (self.runOnClickBlock) {
self.runOnClickBlock(buttonIndex, input.text);
}
}
#end
Then, you could call it with the block in your view controller just like this,
- (void)showAlert:(id)sender{
AlertComBloco *alertCombo = [[AlertComBloco alloc] initWithTitulo:#"Hi" mensagem:#"Custom Alert" tituloBotaoCancel:#"Cancel" outrosBotoesArray:#[#"Other"] inputComPlaceHolder:#"Placeholder" comBlocoExecucao:^(NSInteger buttonIndex, NSString *textoInput) {
NSLog(#"Button at index %ld, with text %#", (long)buttonIndex, textoInput);
}];
[alertCombo show];
}
You haven't shown us how you're calling this but most likely your AlertViewBlocoComInput is a local variable that has fallen out of scope and is therefore deallocated before the user completes their input. You can demonstrate this by temporarily adding a dealloc method that will tell you when the object is deallocated.
- (void)dealloc {
NSLog(#"%s", __PRETTY_FUNCTION__);
}
In terms of fixing this, you could make your AlertViewBlocoComInput instance a class property, so it won't be released until you manually nil it. Or you can make AlertViewBlocoComInput maintain a strong reference to itself until clickedButtonAtIndex is called.
Or, easiest, leverage the fact that UIAlertView already retains itself, so you can retire AlertComBloco altogether, folding it into AlertViewBlocoComInput:
typedef void (^onClickBlock)(NSInteger buttonIndex, NSString *textoInput);
#interface AlertViewBlocoComInput : UIAlertView <UIAlertViewDelegate>
- (instancetype)initComTitulo:(NSString *)titulo
mensagem:(NSString *)mensagem
tituloBotaoCancel:(NSString *)tituloCancel
outrosBotoesArray:(NSArray *)titulosOutrosBotoes
inputComPlaceHolder:(NSString *)textoPlaceholder
comBlocoExecucao:(onClickBlock)bloco;
#property (nonatomic, copy) onClickBlock runOnClickBlock;
#end
#implementation AlertViewBlocoComInput
- (instancetype)initComTitulo:(NSString *)titulo
mensagem:(NSString *)mensagem
tituloBotaoCancel:(NSString *)tituloCancel
outrosBotoesArray:(NSArray *)titulosOutrosBotoes
inputComPlaceHolder:(NSString *)textoPlaceholder
comBlocoExecucao:(onClickBlock)bloco
{
self = [super initWithTitle:titulo message:mensagem delegate:self cancelButtonTitle:tituloCancel otherButtonTitles:nil];
if (self) {
self.runOnClickBlock =bloco;
// adicionar os outros botões
for (NSString *umOutroBotao in titulosOutrosBotoes) {
[self addButtonWithTitle:umOutroBotao];
}
[self setAlertViewStyle:UIAlertViewStylePlainTextInput];
UITextField *input = [self textFieldAtIndex:0];
input.placeholder = textoPlaceholder;
}
return self;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (self.runOnClickBlock) {
UITextField *input = [alertView textFieldAtIndex:0];
self.runOnClickBlock(buttonIndex, input.text);
}
}
#end
And you'd call it like so:
AlertViewBlocoComInput *obj = [[AlertViewBlocoComInput alloc] initComTitulo:#"title" mensagem:#"message" tituloBotaoCancel:#"OK" outrosBotoesArray:nil inputComPlaceHolder:#"Placeholder" comBlocoExecucao:^(NSInteger buttonIndex, NSString *textoInput) {
// do whatever you want with `buttonIndex` and `textoInput` here
//
// NSLog(#"%ld %#", (long)buttonIndex, textoInput);
}];
[obj show];
Related
so I'm trying to get a variable containing the name of a PDF file I wish to open in a UIweb View to show up in a label. I first identify the global variable in a seperate class here:
header:
#import <Foundation/Foundation.h>
extern NSString *PDFNameString;
extern NSString *PDFActualName;
#interface GlobalVars : NSObject
{
}
#property (nonatomic, strong) NSString *PDFActualName;
#property (nonatomic, strong) NSString *PDFNameString;
#end
.m:
#import "GlobalVars.h"
NSString *PDFNameString;
NSString *PDFActualName; //the name of the PDF file
#implementation GlobalVars
{
}
#end
then I have the menu where I have an alert dialog featuring a text field so that the user can input the PDF name:
.h
#import <Foundation/Foundation.h>
#import "GlobalVars.h"
#interface TitleViewController : UIViewController{
NSFileManager *FM1;
}
#property (retain, nonatomic) IBOutlet UIBarButtonItem *OpenPDF;
#property (retain, nonatomic) IBOutlet UIBarButtonItem *ViewPDF;
-(void)OpeningPDF;
-(void)alertView;
#end
.m
#import "TitleViewController.h"
#interface TitleViewController ()
#end
#implementation TitleViewController
UIAlertView * alert;
UITextField *textField;
int StopTheAlerts = 0;
- (void)viewDidLoad
{
[super viewDidLoad];
FM1 = [NSFileManager defaultManager];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)ButtonClicked:(id)sender {
self.OpeningPDF;
}
- (void)dealloc {
[_OpenPDF release];
[_ViewPDF release];
[super dealloc];
}
- (void)OpeningPDF
{
StopTheAlerts = 0;
alert = [[UIAlertView alloc]
initWithTitle:#"Please enter a valid PDF name below:"
message:#"(Please add .PDF on the end!) \n \n"
delegate:self cancelButtonTitle:#"Cancel"
otherButtonTitles:#"ok", nil];
textField = [[UITextField alloc] init];
[textField setBackgroundColor:[UIColor whiteColor]];
textField.delegate = nil;
textField.borderStyle = UITextBorderStyleLine;
textField.frame = CGRectMake(15, 90, 255, 30);
textField.placeholder = #"PDF name";
textField.keyboardAppearance = UIKeyboardAppearanceAlert; //set up an alert box with a text field
[textField becomeFirstResponder];
[alert addSubview:textField];
[alert show];
[alert release];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
PDFNameString = textField.text; //set the PDF name variable to the name entered
PDFActualName = textField.text;
NSArray *Paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *DocumentDir = [Paths objectAtIndex:0];
NSString *TempFilePath = PDFNameString;
PDFNameString = [DocumentDir stringByAppendingPathComponent:TempFilePath];
if([FM1 fileExistsAtPath: PDFNameString]){
_ViewPDF.enabled = true;
}
else {
while(StopTheAlerts <= 0){
UIAlertView *ErrorAlert = [[UIAlertView alloc]
initWithTitle:#"This file dosn't exist!"
message:#"Please reenter the file name!"
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[ErrorAlert show];
[ErrorAlert release];
StopTheAlerts = 1;
}
}
}
#end
This part all works fine, however, when I switch over the the view that contains the UIWebView to actually view the PDF (I've removed that in this part of the code) it has the old "message sent to deallocated instance 0xdb8fca0" error when I try to assign my global variable to the label containing the PDF name, this error also occurs when trying to get the UIWebView to read the PDF using the other global variable.
.h
#import <UIKit/UIKit.h>
#import "GlobalVars.h"
#interface ViewController : UIViewController
#property (retain, nonatomic) IBOutlet UILabel *PDFNameL;
#end
.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_PDFNameL.text = PDFActualName;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)dealloc {
[_PDFNameL release];
[super dealloc];
}
#end
If anyone knows a solution to the problem I would be very happy
thanks
I am tryin to pass the user login emial to other view controllers. It is going from a UITextField to a UILabel but it display null when I log in a user. I want it to display the email name in the UILabel field. Any help? here are my files.
vc1.h
#import <UIKit/UIKit.h>
#interface loginUserViewController : UIViewController
#property (nonatomic, strong) IBOutlet UITextField *email;
#property (nonatomic, retain) IBOutlet UITextField *password;
#property (nonatomic, retain) IBOutlet UIButton *login;
#property (nonatomic,retain) IBOutlet UIButton *registerBtn;
-(IBAction)loginUser:(id)sender;
#end
vc2.h
#import <UIKit/UIKit.h>
#import "loginUserViewController.h"
#interface Home : UIViewController
#property (weak, nonatomic) IBOutlet NSString *getEmail;
#property (weak, nonatomic) IBOutlet UILabel *username;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *Nav;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *logout;
-(IBAction)logout:(id)sender;
-(IBAction)bandHome:(id)sender;
#end
vc2.m
import "Home.h"
#import "loginUserViewController.h"
#interface Home ()
#end
#implementation Home
#synthesize getEmail,username, band1, band2, band3;
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self){
}
return self;
}
-(void)viewDidLoad
{
[super viewDidLoad];
// loginUserViewController *object = [[loginUserViewController alloc]init];
// NSString *string = [[NSString alloc] initWithFormat:#"%#", object.email.text];
username.text = getEmail;
}
vc1.m
#import "loginUserViewController.h"
#import "Home.h"
#import "createBandViewController.h"
#interface loginUserViewController ()
#end
#implementation loginUserViewController
#synthesize email, password;
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
}
- (void)viewDidload
{
[super viewDidLoad];
}
-(IBAction)loginUser:(id)sender {
if ([email.text isEqualToString:#""] || [password.text isEqualToString:#""])
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"alert" message:#"Please Fill all the field" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
return;
}
NSMutableString *strURL = [[NSMutableString alloc] initWithFormat:#"Pretend reference/login2.php?email=%#&password=%#", email.text, password.text ];
[strURL setString:[strURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];
NSMutableString *strResult = [[NSMutableString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding];
NSLog(#"logging in");
if ([strResult isEqualToString:#"1"])
{
NSLog(#"Logged in!");
[self performSegueWithIdentifier:#"login" sender:self];
Home *VC;
VC = [self.storyboard instantiateViewControllerWithIdentifier:#"Home"];
[self.navigationController pushViewController:VC animated:YES];
VC.getEmail = self.email.text;
}else
{
// invalid information
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"alert" message:#"Invalide Information" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
return;
}
//email.text = #"";
password.text = #"";
}
-(void)WillAppear:(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];
}
// Dismisses keyboard by clicking out and hitting return key.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.view endEditing:YES];
}
-(BOOL)textFieldShouldReturn:(UITextField *) textField {
[textField resignFirstResponder];
return YES;
}
#end
vc2.h
#property (weak, nonatomic) IBOutlet NSString *getEmail;
vc2.m
#synthesize getEmail;
-(void)viewDidLoad
{
[super viewDidLoad];
username.text = getEmail;
}
vc1.m
-(IBAction)loginUser:(id)sender {
if ([email.text isEqualToString:#""] || [password.text isEqualToString:#""])
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"alert" message:#"Please Fill all the field" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
return;
}
else
{
vc2 *VC;
VC = [self.storyboard instantiateViewControllerWithIdentifier:#"vc2Identifier"];
[self.navigationController pushViewController:VC animated:YES];
VC.getEmail = self.email.text
}
}
You don't need to alloc and init the view controller where you have to get the data , but you have to pass the data from vc1 to vc2 and use the variable of vc2 in vc1 , And what your were doing was using the vc1 value in vc2 . And you were allocating the LoginViewController , and in viewDidUnload method , you have set email textfield as nil . that is why you were getting nil value in vc2
I have a simple class like this
.h
#interface DJMyClass : NSObject
+ (void)someFunction;
#end
.m
#import "DJJavaFunction+UIAlert.h"
#interface DJMyClass ()
#property (nonatomic, strong) NSString* someString;
#end
#implementation DJMyClass
+(void)functionWithName:(NSString *)functionName
callbackId:(int)callbackId
args:(NSArray *)args
{
DJMyClass *newFunction = [[DJMyClass alloc] init];
newFunction.function = functionName;
newFunction.callbackId = callbackId;
newFunction.args = args;
[newFunction processFunction];
}
- (void)processFunction
{
[self showAlertWithTitle:title message:message buttons:buttons inputField:inputField callbackId:_callbackId];
}
#end
Now I have created different extensions of this class, which I import and use within this class.
.h
#interface DJMyClass (UIAlert) <UIAlertViewDelegate>
- (void)showAlertWithTitle:(NSString *)title
message:(NSString *)message
buttons:(NSArray *)buttons
inputField:(NSDictionary *)inputField
callbackId:(int)callbackId;
#end
.m
#implementation DJJavaFunction (UIAlert)
- (void)showAlertWithTitle:(NSString *)title
message:(NSString *)message
buttons:(NSArray *)buttons
inputField:(NSDictionary *)inputField
callbackId:(int)callbackId
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:self
cancelButtonTitle:nil
otherButtonTitles:nil];
// Add the buttons
for (NSString *btn in buttons)
{
[alert addButtonWithTitle:btn];
}
// Add text field
if (!inputField)
{
alert.alertViewStyle = UIAlertViewStyleDefault;
}
else
{
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
UITextField *textField = [alert textFieldAtIndex:0];
textField.placeholder = inputField[#"placeholder"];
textField.text = inputField[#"text"];
}
alert.delegate = self;
alert.tag = 44;
[alert show];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
NSLog(#"%s", __PRETTY_FUNCTION__);
}
#end
This all works well, except that the UIAlertViewDelegate methods are never called.
Is it even possible to respond to UIAlertViewDelegate calls from within a category?
Thanks
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).
i am trying to replace an object at in an array by replacing it with the text returned from an alert view.
so far i have:
int selected = indexPath.row;
and for my alertview delegate method.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (alertView.tag == 1) {
[myMutableArray replaceObjectAtIndex:selected withObject:[[alertView textFieldAtIndex:0] text]];
[_tableView reloadData];
}
}
i keep getting an error of
Incompatible integer to pointer conversion assigning to 'NSInteger *' (aka 'long *') from 'NSInteger' (aka 'long')
The error you see comes from the fact that you put a * somewhere before the NSInteger variable.
Without knowing what the rest of your code looks like, you could try this in your ViewController.m file. It sets the text of a label and replaces an object in a mutable array with the text from the alert view when the "OK" button is pressed.
#import "ViewController.h"
#interface ViewController () <UIAlertViewDelegate>
#property (strong,nonatomic) NSMutableArray *mutArray;
#property (weak,nonatomic) IBOutlet UILabel *label;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *array = #[#"item1",#"item2",#"item3"];
self.mutArray = [[NSMutableArray alloc] init];
self.mutArray = [array mutableCopy];
}
- (IBAction)showAlert:(id)sender {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"My Alert Example"
message:#"message here"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK",nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
int selected = 1;
if (buttonIndex != alertView.cancelButtonIndex) {
NSLog(#"ok button");
UITextField *textField = [alertView textFieldAtIndex:0];
self.label.text = textField.text;
[self.mutArray replaceObjectAtIndex:selected withObject:textField.text];
NSLog(#"mutArray is %#",self.mutArray);
} else {
NSLog(#"cancel button");
}
}
#end
Since it looks like you're using a UITableView, in your case you would have int selected = indexPath.row instead of int selected = 1.