iOS SVProgressHUD iOS11Crash解决办法
2020-09-09 本文已影响0人
一粒咸瓜子
iOS 11 Crash :AppDelegate window: unrecognized selector
在 iOS11 之后创建的项目会出现
SceneDelegate
文件,此文件的职能是将原先
AppDelegate
所负责的UI生命周期
委以己任。
在有 SceneDelegate
文件的项目中使用 SVProgressHUD
的话会出现以下错误:

报错信息:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[AppDelegate window]: unrecognized selector sent to instance
看了网上的解决办法,基本上都是在 AppDelegate 中实现 window 属性,个人感觉这样做不免有些尴尬,即干扰了 AppDelegate 中原有的逻辑,同时也复杂化了代码的可读性。
我的做法是:创建 AppDelegate 的分类:放在项目中即可,并不需要 import 到任何文件中!!
// AppDelegate+SVProgressHUD.h
/**
不需要导入到任何文件中
应在有 SceneDelegate 的项目中使用
*/
#import <Foundation/Foundation.h>
#import "AppDelegate.h"
@interface AppDelegate (SVProgressHUD)
@end
// AppDelegate+SVProgressHUD.m
#import "AppDelegate+SVProgressHUD.h"
#import "SceneDelegate.h"
@implementation AppDelegate (SVProgressHUD)
- (UIWindow *)window {
UIWindowScene *scene = (UIWindowScene *)UIApplication.sharedApplication.connectedScenes.allObjects[0];
SceneDelegate *sceneDelegate = (SceneDelegate *)scene.delegate;
return sceneDelegate.window ?: nil;
}
@end
dismiss 功能拓展
实现点按即消失的功能
思路:类的前向引用找到 hudView 添加 tap 手势
// SVProgressHUD+TapToDismiss.h
#import <SVProgressHUD/SVProgressHUD.h>
@protocol FakeProxy <NSObject>
@optional
+ (SVProgressHUD *)sharedView;
@end
@interface SVProgressHUD (TapToDismiss) <FakeProxy>
+ (void)tapToDimiss:(BOOL)enable;
@end
// SVProgressHUD+TapToDismiss.m
#import "SVProgressHUD+TapToDismiss.h"
#import <objc/runtime.h>
@implementation SVProgressHUD (TapToDismiss)
+ (void)tapToDimiss:(BOOL)enable {
SVProgressHUD *hud = [self sharedView];
hud.userInteractionEnabled = enable;
if (enable) {
UITapGestureRecognizer *tap = objc_getAssociatedObject(hud, _cmd);
if (!tap) {
tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped)];
objc_setAssociatedObject(hud, _cmd, tap, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[hud addGestureRecognizer:tap];
}
}
}
+ (void)tapped {
[SVProgressHUD dismiss];
}