【问题标题】:MBProgressHUD not resettingMBProgressHUD 未重置
【发布时间】:2012-03-14 10:18:21
【问题描述】:

我在我们的教学应用中使用 MBProgressHUD,它是通过标签栏导航的。

用户将通过 Urban Airship 的店面从 tableview 直接进入 UA 详细视图。 单击购买后,我会使用

来打开 HUD
 HUD = [[MBProgressHUD alloc] initWithWindow:[UIApplication sharedApplication].keyWindow];
 [self.view.window addSubview:HUD];

它正在使用 showWhileExecuting 语句。

从“正在连接”到“正在下载”再到“解包”,需要经过三个 while 语句。 一切正常。

问题来了... 我第二次这样做标签文本不会改变。它卡在“正在连接”上。 我可以在 NSLog 中看到它正在经历其他循环。
最重要的是,如果我尝试更改模式,应用程序会崩溃。

这只会发生第二次,以及任何后续使用。如果我杀死该应用程序,一切都会再次运行。

在我看来,MBProgressHUD 完成后没有重置。
(项目中使用了ARC)

谁有解决方案? 谢谢

编辑:

- (void)showWithLabelDeterminate 
{

    HUD = [[MBProgressHUD alloc] initWithWindow:[UIApplication sharedApplication].keyWindow];
    HUD.mode = MBProgressHUDModeIndeterminate;
    [self.view.window addSubview:HUD];


    HUD.delegate = self;
    HUD.labelText = NSLocalizedString(@"Connecting","");
    HUD.detailsLabelText = @" ";
    HUD.minSize = CGSizeMake(145.f, 145.f);
    HUD.dimBackground = YES;

    [HUD showWhileExecuting:@selector(lessonDownloadProgress) onTarget:self withObject:nil animated:YES];
}


-(void)lessonDownloadProgress
{

    DataManager *sharedManager = [DataManager sharedManager];
    //  HUD.mode = MBProgressHUDModeIndeterminate;
    HUD.labelText = nil;
    HUD.detailsLabelText = nil;

    while ([sharedManager.downHUD floatValue] == 0.0f) 
    { 
        [self parentViewController];
        NSLog(@"HUD lessonDownloadProgress: %f", HUD.progress);
        HUD.labelText = NSLocalizedString(@"Connecting","");
        HUD.detailsLabelText = @" ";
        NSLog(@"Waiting for download to start");
        //  Wait for download to start
        usleep(80000);
    }

    // Switch to determinate mode     
    // HUD.mode = MBProgressHUDModeDeterminate;
    HUD.labelText = NSLocalizedString(@"DownLoading","");
    HUD.progress = [sharedManager.downHUD floatValue];

    while (HUD.progress < 1.0f && [sharedManager.cleanedUp isEqualToString:@"No"])
    {
        //  [self parentViewController];
        HUD.labelText = NSLocalizedString(@"Downloading","");
        NSLog(@"HUD lessonDownloadProgress: %f", HUD.progress);
        HUD.progress = [sharedManager.downHUD floatValue];                       
        NSString *percent = [NSString stringWithFormat:@"%.0f", HUD.progress/1*100];
        HUD.detailsLabelText = [percent stringByAppendingString:@"%"];
        usleep(50000);
    }

    //  Switch HUD while cleanUp
    HUD.mode = MBProgressHUDModeIndeterminate;

    while ([sharedManager.cleanedUp isEqualToString:@"No"]) 
    {
        [self parentViewController];
        HUD.labelText = NSLocalizedString(@"Unpacking","");
        HUD.detailsLabelText = @" ";
        //  wait for cleanup
        NSLog(@"Waiting for clean up");
        usleep(50000);
    }

    NSLog(@"++ Finished loops ++");
    NSLog(@"Finished HUD lessonDownloadProgress: %f", HUD.progress);

    [MBProgressHUD hideHUDForView:self.view animated:YES];
    [HUD removeFromSuperview];
    HUD.delegate = nil;

    [HUD release];
    HUD = nil;

}

【问题讨论】:

  • HUD 是 ivar 还是局部变量?
  • 这是本地的,我想... MBProgressHUD = *HUD
  • 很可能 ARC 正在发布您对 MBProgressHUD 的引用,因此修改其子视图的尝试随后会失败。
  • 其实 ARC 对这个类是关闭的。有什么我可以做的吗?我已经尝试了所有这些; ` [HUD removeFromSuperview]; HUD.delegate = nil; [HUD释放]; HUD = 无; `
  • 好的,那我们能看到更多代码吗?例如你有showWhileExecuting 和你提到的while 语句的一些sn-ps。

标签: ios mbprogresshud


【解决方案1】:

我无法在您发布的代码中发现问题;但一些重构可能会有所帮助。

您可以使用 KVO 观察 DataManager 上的属性并响应这些更改,而不是轮询 DataManager(“不要给我们打电话;我们会打电话给你的。)如果你愿意,这里有一个建议的方法。

你的类界面:

@interface YourClass : UIViewController    // or whatever your superclass is...
{
    MBProgressHUD *_hud;
    DataManager *_dataManager;

    //  your other ivars
}
@end

在你的实现文件中...

@interface YourClass()
@property (nonatomic, retain) DataManager dataManager;
@end

上面我已经将你的 dataManager 声明为一个属性,以便我们可以观察它。

要开始下载过程,我们现在有一个方法downloadLesson

- (void)downloadLesson;
{
    //  show HUD and retain it (showHUDAddedTo:animated: returns autoreleased object)
    MBProgressHUD *HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES] retain];

    //  observe properties on the dataManager
    [self addObserver:self forKeyPath:@"dataManager.progress" options:NSKeyValueObservingOptionNew context:nil];
    [self addObserver:self forKeyPath:@"dataManager.cleanedUp" options:NSKeyValueObservingOptionNew context:nil];
    [self addObserver:self forKeyPath:@"dataManager.downHUD" options:NSKeyValueObservingOptionNew context:nil];

    //  begin your download here...

    HUD.labelText = NSLocalizedString(@"Connecting", "");
    HUD.detailsLabelText = @" ";
    HUD.progress = self.dataManager.downHUD;
}

现在使用 KVO 更新 HUD 的外观:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
{
    if( [keyPath isEqualToString:@"dataManager.cleanedUp"] )
    {
        if( [[[self dataManager] cleanedUp] isEqualToString:@"Yes"] )
        {
            [MBProgressHUD hideHUDForView:[[UIApplication sharedApplication] keyWindow] animated:YES];
            [HUD release];  HUD = nil;
            [self removeObserver:self forKeyPath:@"dataManager.progress"];
            [self removeObserver:self forKeyPath:@"dataManager.cleanedUp"];
            [self removeObserver:self forKeyPath:@"dataManager.downHUD"];
        }
    }
    if( [keyPath isEqualToString:@"dataManager.downHUD"] )
    {
        //  if the data manager updates progress, update our HUD
        HUD.progress = self.dataManager.downHUD;
        if( self.dataManager.downHUD == 0.0 )
            //  no progress; we're just connecting
            HUD.labelText = NSLocalizedString(@"Connecting", "");
        else if( self.dataManager.downHUD < 1.0 )
        {
            //  progress >0.0 and < 1.0; we're downloading
            HUD.labelText = NSLocalizedString(@"Downloading", "");
            NSString *percent = [NSString stringWithFormat:@"%.0f%%", HUD.progress/1*100];
            HUD.detailsLabelText = percent;
        }
        else
        {
            //  progress == 1.0, but we haven't cleaned up, so unpacking
            if( [[[self dataManager] cleanedUp] isEqualToString:@"No"] )
            {
                HUD.labelText = NSLocalizedString(@"Unpacking","");
                HUD.detailLabelsText = @" ";
            }
        }
    }
}

或者,您可以使用通知进行更新,其中DataManager 发布您的视图控制器注册的NSNotifications。或者,如果您愿意重构 DataManager,您可以使用块来进行更新。所有这些解决方案都避免了必须显式阻止您的线程来轮询DataManager。希望这会有所帮助。

【讨论】:

    【解决方案2】:

    你实现了委托方法吗?

    - (void)hudWasHidden:(MBProgressHUD *)hud {
        // Remove HUD from screen when the HUD was hidded
        [HUD removeFromSuperview];
        HUD = nil;
    }
    

    【讨论】:

    • 干杯,设法杀死它。它实际上是调用 HUD 时留下的一段旧代码。呼!!
    【解决方案3】:

    这是因为标签是在init上设置的。试试这个:

    你应该把这个方法添加到 MBProgressHud 的头文件中:

    + (MB_INSTANCETYPE)showHUDAddedTo:(UIView *)view withText:(NSString *)text;
    

    并在.m文件中实现如下:

    + (MB_INSTANCETYPE)showHUDAddedTo:(UIView *)view withText:(NSString *)text
    {
        MBProgressHUD *hud = [[self alloc] initWithView:view];
        hud.labelText = text;
        [view addSubview:hud];
        [hud show:YES];
        return MB_AUTORELEASE(hud);
    }
    

    并在任何你想要的地方调用它:

    [MBProgressHUD showHUDAddedTo:self.view withText:@"Loading..."];
    

    【讨论】:

      猜你喜欢
      • 2011-07-28
      • 1970-01-01
      • 2014-10-23
      • 1970-01-01
      • 2012-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多