控制器主窗口的找寻方法和MBProgressHUD使用注意点

一:主窗口根控制器切换。有时候,在程序里面用到切换底层主窗口的根控制器的时候,我们需要找出这个主窗口。切换主窗口根控制器有以下几个方法1,2,3,4,5:

            GuidePageController *log=[[GuidePageController alloc]init];
            UINavigationController *nav=[[UINavigationController alloc]initWithRootViewController:log];
            UIWindow * window = [UIApplication sharedApplication].delegate.window;//1
            //UIWindow * window = [UIApplication sharedApplication].windows[0];//2
            window.rootViewController=nav;
            //self.view.window.rootViewController=nav;//3
            //[UIApplication sharedApplication].keyWindow.rootViewController=nav;//4
            //presentViewController切换//5

二:MBProgressHUD使用注意点,很多时候我们都不用MBProgressHUD的原始方法去给用户提示一些信息,而是去用大神们去封装好的一些分类方法,这样节省了很多代码量。像MBProgressHUD+MJ等等。但是以下情况使用的时候我们要注意一下。我们以MBProgressHUD+MJ为例子做一个分析。
例子:比如我们要做一个登陆界面:

[MBProgressHUD showMessage:@"正在登录中...."];
AFHTTPRequestOperationManager*mager=[AFHTTPRequestOperationManager manager];
[mager POST:url parameters:nil success:^(AFHTTPRequestOperation * operation, id responseObject) {
        [MBProgressHUD hideHUD];
        [UIApplication sharedApplication].keyWindow.rootViewController=新的根控制器;
    } failure:^(AFHTTPRequestOperation * operation, NSError * error) {
        [MBProgressHUD hideHUD];
    }];

以上代码没问题,但是如果我们需要一个登陆成功提醒的话,那么代码可能会这样:

[MBProgressHUD showMessage:@"正在登录中...."];
AFHTTPRequestOperationManager*mager=[AFHTTPRequestOperationManager manager];
[mager POST:url parameters:nil success:^(AFHTTPRequestOperation * operation, id responseObject) {
        [MBProgressHUD hideHUD];
        [MBProgressHUD showSuccess:@"登录成功"];
        [UIApplication sharedApplication].keyWindow.rootViewController=新的根控制器;
    } failure:^(AFHTTPRequestOperation * operation, NSError * error) {
        [MBProgressHUD hideHUD];
    }];

这时候页面可能会出现Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior ()这个错误。我们追随[MBProgressHUD showSuccess:]进入看一下发现最终会走到这个方法里面:

+ (void)show:(NSString *)text icon:(NSString *)icon view:(UIView *)view
{
    if (view == nil) view = [[UIApplication sharedApplication].windows lastObject];
    // 快速显示一个提示信息
    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
    hud.labelText = text;
    // 设置图片
    hud.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"MBProgressHUD.bundle/%@", icon]]];
    // 再设置模式
    hud.mode = MBProgressHUDModeCustomView;

    // 隐藏时候从父控件中移除
    hud.removeFromSuperViewOnHide = YES;

    // 1秒之后再消失
    [hud hide:YES afterDelay:1.0];
}

这里面我们来看这四行代码:

    if (view == nil) view = [[UIApplication sharedApplication].windows lastObject];
    // 快速显示一个提示信息
    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
        // 隐藏时候从父控件中移除
    hud.removeFromSuperViewOnHide = YES;

    // 1秒之后再消失
    [hud hide:YES afterDelay:1.0];

一下纯属我个人理解:如果有不对的地方,还请多多指教。
什么意思呢?就是这个hud显示在主窗口的最后一个view上面了,隐藏时就从这个view上面移除。而这个hud会在1秒之后隐藏。接着,在这1秒内我们的程序已经走到了[UIApplication sharedApplication].keyWindow.rootViewController=新的根控制器;这一步,也就是切换了新的根控制器,没有指针在指向那个根控制器,那么之前所有根控制器里面的控制器以及他们的view都会被系统回收销毁。1秒后呢,hud开始隐藏,这时候hud的父控件早已经被销毁了,找不到父控件。就会报出以上的错误了。所以我们要要在隐藏之后再切换根控制器。

代码改进:我们显示登录成功的那个提示要单独做,首先在.m文件添加一个属性,@property (strong, nonatomic) MBProgressHUD *hud;

[MBProgressHUD showMessage:@"正在登录中...."];
AFHTTPRequestOperationManager*mager=[AFHTTPRequestOperationManager manager];
[mager POST:url parameters:nil success:^(AFHTTPRequestOperation * operation, id responseObject) {
        [MBProgressHUD hideHUD];
        _hud = [MBProgressHUD showHUDAddedTo:[[UIApplication sharedApplication].windows lastObject] animated:YES];
        _hud.labelText = @"登录成功";
        // 设置图片
        _hud.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"MBProgressHUD.bundle/%@", @"success.png"]]];
        // 设置模式
        _hud.mode = MBProgressHUDModeCustomView;
        //是否有庶罩
        _hud.dimBackground = YES;
        // 隐藏时候从父控件中移除
        _hud.removeFromSuperViewOnHide = YES;
        // 1秒之后执行一下方法
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            // 立即隐藏
            [_hud hide:YES];
            [UIApplication sharedApplication].keyWindow.rootViewController=新的根控制器;
        });
    } failure:^(AFHTTPRequestOperation * operation, NSError * error) {
        [MBProgressHUD hideHUD];
    }];
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值