开发者

ios UIAlertView: make alert wait for my response [duplicate]

开发者 https://www.devze.com 2023-03-17 15:28 出处:网络
This question already has answers here: Closed 11 years ago. Possible Duplicate: Make UIAlertView blocking
This question already has answers here: Closed 11 years ago.

Possible Duplicate:

Make UIAlertView blocking

Been beating my head against the wall for hours on this one.

Here's what I've got: OrderDetailsViewController is set as an UIAlertViewDelegate

I've got a procedure that receives information back from a search form. It checks to see if the item is already on the order and if not continues adding the item(s). If it sees a duplicate, it pops up a UIAlertView asking what the user wants to do: there are 3 options, "Combine" - add the new qty to the old item, "Add" the duplicate as a separate line item, or "Cancel" throw the new item away. I need it to wait for an answer from the UIAlertView so that I can continue adding the dupe or throwing away the dupe -- the "Combine" is handled in the delegate, but I still need an answer for the main procedure.

Here's what I have so far:

 - (void)returnItemAndQty:(ProductsSearchController *)productsSearchController
         withItemsToAdd:(NSMutableArray *)itemsToAdd 
         withQty:(NSDictionary *)qtyToAdd andClose:(BOOL)close
{
if ([itemsToAdd count] == 0) {
    return;
}
Items *items;
for (int index = 0; index < [itemsToAdd count]; index++) {
    items = [itemsToAdd objectAtIndex:index];
    qtyAddedToOrder = [NSDecimalNumber decimalNumberWithString:[qtyToAdd objectForKey:items.ItemCode]];     
    NSLog(@"Item Code: %@", items.ItemCode);
    NSLog(@"Qty: %@", [qtyToAdd objectForKey:items.ItemCode]);
    NSError *error;

    //For handling duplicate items. . . 
    duplicateItemDisposition = -1; //Reset the dispostion for normal operation
    if([self isIte开发者_开发技巧mOnOrder:items.ItemCode])
    {
        int i = [self itemIsAlreadyOnOrder:itemAlreadyOnOrder withQty:qtyAddedToOrder];

        if (i == COMBINE || i == CANCEL){ //either Cancel or Combine was pressed.
            items.Checked = NO;
            if (![items.managedObjectContext save:&error])
            {
                NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            }
            continue;
        }
    }
    //Add the new item or duplicate if that's what you want
    OrdersDetails *newOrderDetail = [NSEntityDescription insertNewObjectForEntityForName:@"OrdersDetails" 
                                                                  inManagedObjectContext:self.managedObjectContext];

.//more code snipped, that handles the "ADD" or non-dupe
.
.

Here's where it tests for a duplicate. . .

- (BOOL)isItemOnOrder:(NSString *)itemCode
{

 NSFetchRequest *request = [[NSFetchRequest alloc] init];

     NSEntityDescription *entity = [NSEntityDescription entityForName:@"OrdersDetails"
                                          inManagedObjectContext:managedObjectContext];
    [request setEntity:entity];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc]initWithKey:@"Desc1" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sort, nil];
    [request setSortDescriptors:sortDescriptors];
    [sort release];
    [sortDescriptors release];

    NSPredicate *pred = [NSPredicate predicateWithFormat:@"(ItemCode=%@ AND OrderID=%@)", itemCode, orders.OrderID];
    [request setPredicate:pred];

    NSError *error;
    NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:& error] mutableCopy];
   [request release];
   if (mutableFetchResults == nil) {
       itemAlreadyOnOrder = nil;
       return NO;
   }else if ([mutableFetchResults count] > 0){
       itemAlreadyOnOrder = [mutableFetchResults objectAtIndex:0];
       return YES;
   }else{
       itemAlreadyOnOrder = nil;
       return NO;
   }
}

Here's where it sees that a dupe exists and the UIAlertview delegate with it. . .

- (int) itemIsAlreadyOnOrder:(OrdersDetails *)existingOrderDetail withQty:(NSDecimalNumber *)qty 
{
    if (existingOrderDetail == nil) {
    return -1;
    }

    UIAlertView *duplicateAlert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"Duplicate Item %@ found.",existingOrderDetail.ItemCode] message:@"Tap Combine to combine the items, Tap Add to add the duplicate item or Tap Cancel to discard the duplicate" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Combine", @"Add", nil];
    [duplicateAlert show];

    return duplicateItemDisposition;

    [duplicateAlert release];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
// Cancel = 0, Combine = 1, Add = 2

    if (buttonIndex == CANCEL){
        duplicateItemDisposition = CANCEL;
    }else if (buttonIndex == COMBINE){
            duplicateItemDisposition = COMBINE;
            NSDecimalNumber *existingQty = [[NSDecimalNumber alloc] initWithDecimal:[itemAlreadyOnOrder.Qty decimalValue]];
            NSDecimalNumber *existingPrice = itemAlreadyOnOrder.Price;
            NSDecimalNumber *newQty = [existingQty decimalNumberByAdding:qtyAddedToOrder];
            itemAlreadyOnOrder.ExtPrice = [newQty decimalNumberByMultiplyingBy:existingPrice];
           [existingQty release];
           NSError *error;
           if (![itemAlreadyOnOrder.managedObjectContext save:&error]){
        NSLog(@"Error saving. %@, %@", error, [error userInfo]);
               [self handleFreeGoods:itemAlreadyOnOrder];
           }else if (buttonIndex == ADD){
               duplicateItemDisposition = ADD;
           }
}

Now I read something on here about using an NSCondition in a background thread, but I have no idea what that means. I looked up NSCondition, and it was less than enlightening.

Any ideas on how to pause the execution?


The UIAlertView can't block, as it gets displayed at the end of the runloop. Instead of having the method itemIsAlreadyOnOrder: return a value indicating what should be done with the duplicate entry, the delegate method from the UIAlertView needs to notify your controller that the item in question has been resolved. Track the object in question somewhere (_objectToVerify or something like that), and in the delegate method from the UIAlertView call a method based on the users choice, which will act on that _objectToVerify.


I don't know how much this might change your current design, but the Cocoa design pattern would have the method that puts up the alert not return anything, so something like if (duplicate) showAlertView in pseudocode. Then in the alert view's delegate, call a method that actually handles the processing of the duplicate based on user input.

0

精彩评论

暂无评论...
验证码 换一张
取 消