简体   繁体   English

使用委托清理数组

[英]Clean array by using delegate

I made an AR app that recognize image and show the object recognized in an AlertView. 我制作了一个AR应用程序,可以识别图像并显示在AlertView中识别的对象。 In the AlertView I have 2 buttons: Add and Cancel, I'm using the UIAlertViewDelegate to understand which button the user pressed. 在AlertView中,我有2个按钮:添加和取消,我使用UIAlertViewDelegate来了解用户按下了哪个按钮。 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. 我将此数组传递给另一个ViewController,在其中设置了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. 在此TableView的底部,有一个“付款”按钮,可转到另一个ViewController,在其中显示所识别对象的总价。 From the last ViewController I can press a button to pay the objects I selected by using the AR. 在最后一个ViewController中,我可以按一个按钮以支付使用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. 现在,当我按下此按钮时,应用程序将关闭该ViewController并返回到第一个ViewController,但是我在其中存储了AR识别为已满的对象的数组。 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 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 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 ScannerViewController.m的接口

@interface ScannerViewController () <MSScannerSessionDelegate, PaymentViewControllerDelegate, UIActionSheetDelegate, UIAlertViewDelegate>
@property (weak) IBOutlet UIView *videoPreview;
- (IBAction)stopScanner:(id)sender;
@end

In ViewDidLoad I inserted this rows: ViewDidLoad我插入了以下行:

PaymentViewController *pay = [[PaymentViewController alloc]init];
[pay setDelegate:self];

And in the ScannerViewController.m I implemented the method I declared in PaymentViewController.h : ScannerViewController.m我实现了我在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. 我在iPhone上测试了我的应用程序,该应用程序运行良好,直到我尝试支付相机拍摄的对象的费用为止,的确,我试图支付对象的费用,但是它不能清除存储扫描对象的数组。 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代码:

ScannerViewController.h ScannerViewController.h

#import <UIKit/UIKit.h>

@interface ScannerViewController : UIViewController

@end

ScannerViewController.m 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 . 为了识别图片,我使用了这个AR SDK I hope you can help me to understand where's my issue 希望您能帮助我了解我的问题所在

Your problem is that in viewDidLoad you have the code: 您的问题是在viewDidLoad您有以下代码:

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). 因此,您创建并设置委托的PaymentViewController实例将立即被销毁(由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). 您需要修改代码,以便在屏幕上显示的PaymentViewController实际实例上调用setDelegate:因为这是需要使用委托的实例(它从警报视图接收回调)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM