Используйте MBProgressHUD с несколькими отправками - PullRequest
2 голосов
/ 29 марта 2012

Каков наилучший способ изменить метку для HUD как в потоке обработки, так и в главном потоке?

[activitySpinner startAnimating];
    //[HUD setLabelText:@"Connecting"];
    //[HUD showUsingAnimation:YES];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
        hud.labelText = @"Connecting1";

        NSString *url = [NSString stringWithFormat:@"my URL", [dataObj.pListData objectForKey:@"API_BASE_URL"], userField.text, passwordField.text];
        NSLog(@"Login: %@",url);
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];

        NSError *error;        
        NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
        [HUD setLabelText:@"Processing"];
        dispatch_async(dispatch_get_main_queue(), ^{
            if ([json objectForKey:@"authToken"] != nil) {
                [HUD setLabelText:@"Logging In"];
                NSLog(@"Found authtoken %@", [json objectForKey:@"authToken"]);
                [dataObj setAuthToken:[json objectForKey:@"authToken"]];
                [dataObj setLocationId:[json objectForKey:@"c_id"]];

                [dataObj setStaffId:[[json objectForKey:@"staffOrRoomsId"] integerValue]];
                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
                [HUD setLabelText:@"Downloading"];

                });

                [self getAllData];
                [self performSegueWithIdentifier:@"segueToRootController" sender:self];


            } else {
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alert" message:[json objectForKey:@"friendlyErrors"] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
                [alert show];
                alert = nil;
            }
            [MBProgressHUD hideHUDForView:self.view animated:YES];
        });


        [activitySpinner stopAnimating];
    });

Я пробовал описанное выше, поскольку при запуске изменения метки наОсновной поток не изменится, пока не будет завершена вся обработка.

В моем viewWillAppear я устанавливаю

HUD = [[MBProgressHUD alloc] initWithView:self.view];
    [self.view addSubview:HUD];
    HUD.delegate = self;

Будет показано подключение, но не будет отображаться Обработка или загрузка.

Ответы [ 2 ]

1 голос
/ 22 апреля 2012

Поскольку Objective-C чувствителен к регистру, у вас есть два экземпляра MBProgressHUD:

  • HUD, который вы создаете с помощью [[MBProgressHUD alloc] initWithView:self.view];, чем добавляете в представление, но не видите (он изначально скрыт) * ​​1006 *
  • hud, который вы создаете, добавляете в представление и сразу же показываете с помощью удобного конструктора [MBProgressHUD showHUDAddedTo:self.view animated:YES];

По сути это означает, что HUD скрыт во всем вашем коде, и любые изменения свойств, которые вы установили для него, не будут отображаться (Обработка и загрузка), в то время как hud виден и показывает единственный текст, который вы установили для него ( Connecting1).

В вашем коде есть дополнительная ошибка, которая включает в себя создание представления (экземпляр hud MBProgressHUD) в фоновом потоке. Общее правило заключается в том, чтобы изменять вид только в основном потоке. Установка текста hud (и некоторых других свойств) является здесь одним заметным исключением, поскольку MBProgressHUD делает здесь небольшую хитрость KVO, чтобы обеспечить вам безопасность потоков.

Кроме того, вы должны знать, что даже когда вы исправляете вышеуказанную ошибку, у вас будет сценарий, в котором вы устанавливаете текст «Вход» (или отображаете предупреждение) и сразу скрываете HUD, что означает, что это текст будет виден только очень кратко. Вы, вероятно, не хотите скрывать HUD, когда загрузка завершена. Есть также похожая проблема с ActivitySpinner.

В общем, вы можете попробовать что-то вроде этого (написано в верхней части моей головы):

[activitySpinner startAnimating];
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = @"Connecting1";
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSString *url = [NSString stringWithFormat:@"my URL", [dataObj.pListData objectForKey:@"API_BASE_URL"], userField.text, passwordField.text];
    NSLog(@"Login: %@",url);
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];

    NSError *error;        
    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
    [hud setLabelText:@"Processing"];
    dispatch_async(dispatch_get_main_queue(), ^{
        if ([json objectForKey:@"authToken"] != nil) {
            [hud setLabelText:@"Logging In"];
            NSLog(@"Found authtoken %@", [json objectForKey:@"authToken"]);
            [dataObj setAuthToken:[json objectForKey:@"authToken"]];
            [dataObj setLocationId:[json objectForKey:@"c_id"]];

            [dataObj setStaffId:[[json objectForKey:@"staffOrRoomsId"] integerValue]];
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
                [HUD setLabelText:@"Downloading"];
                // Download synchronosly here? 
                dispatch_async(dispatch_get_main_queue(), ^{
                    [MBProgressHUD hideHUDForView:self.view animated:YES];
                    [activitySpinner stopAnimating];
                });
            });

            [self getAllData];
            [self performSegueWithIdentifier:@"segueToRootController" sender:self];
        } else {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alert" message:[json objectForKey:@"friendlyErrors"] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
            [alert show];
            alert = nil;
            [MBProgressHUD hideHUDForView:self.view animated:YES];
            [activitySpinner stopAnimating];
        }
    });
});
0 голосов
/ 23 апреля 2012

На самом деле после тестирования этого устройства я обнаружил, что оно действительно отображает Обработка и загрузка. Это просто не отображается в эмуляторе. Я думаю, поскольку он использует процессор компьютера, это происходит так быстро.

...