[九九Tips]- http://www.jianshu.com/users/bab86b3e8aa3/latest_articles
参考的博客:
https://wellphone.me/post/2017/use_uidebugginginformationoverlay_to_debug_ui/
使用步骤(简化版):
-
先把文件
UIDebuggingInformationOverlay+Enable.m
放在拖到工程里,这个文件内容放在文章的结尾处。 -
在
didFinishLaunchingWithOptions
方法中粘贴下面一段代码
#ifdef DEBUG
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
id overlayClass = NSClassFromString(@"UIDebuggingInformationOverlay");
[overlayClass performSelector:NSSelectorFromString(@"prepareDebuggingOverlay")];
#pragma clang diagnostic pop
#endif
- 运行后,用两个手指头在状态栏上同时点击下就可以显示出这个调试的悬浮层。
运行效果
![](https://img.haomeiwen.com/i2423912/49f4e5a3ed8b9549.png)
你值得拥有~
下面的代码为附件文件,请保存为 UIDebuggingInformationOverlay+Enable.m 格式拖到工程目录下:
#import <UIKit/UIKit.h>
#import <objc/runtime.h>
/*
In iOS 11, Apple added additional checks to disable this overlay unless the
device is an internal device. To get around this, we swizzle out the
-[UIDebuggingInformationOverlay init] method (which returns nil now if
the device is non-internal) and +[UIDebuggingInformationOverlay prepareDebuggingOverlay]
method.
Usage:
1.Copy this file to your project.
2.Add the following code to [AppDelegate application:didFinishLaunchingWithOptions:]
#if DEBUG
id overlayClass = NSClassFromString(@"UIDebuggingInformationOverlay");
[overlayClass performSelector:NSSelectorFromString(@"prepareDebuggingOverlay")];
#endif
*/
#if defined(DEBUG) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincomplete-implementation"
#pragma clang diagnostic ignored "-Wundeclared-selector"
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
@interface UIWindow (PrivateMethods)
- (void)_setWindowControlsStatusBarOrientation:(BOOL)orientation;
@end
@interface FakeWindowClass : UIWindow
@end
@implementation FakeWindowClass
- (instancetype)initSwizzled {
self = [super init];
if (self) {
[self _setWindowControlsStatusBarOrientation:NO];
}
return self;
}
@end
@implementation NSObject (UIDebuggingInformationOverlayEnable)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class cls = NSClassFromString(@"UIDebuggingInformationOverlay");
[FakeWindowClass swizzleSelector:@selector(init) newSelector:@selector(initSwizzled) forClass:cls isClassMethod:NO];
[self swizzleSelector:@selector(prepareDebuggingOverlay) newSelector:@selector(prepareDebuggingOverlaySwizzled) forClass:cls isClassMethod:YES];
});
}
+ (void)swizzleSelector:(SEL)originalSelector newSelector:(SEL)swizzledSelector forClass:(Class)class isClassMethod:(BOOL)isClassMethod {
Method originalMethod = NULL;
Method swizzledMethod = NULL;
if (isClassMethod) {
originalMethod = class_getClassMethod(class, originalSelector);
swizzledMethod = class_getClassMethod([self class], swizzledSelector);
} else {
originalMethod = class_getInstanceMethod(class, originalSelector);
swizzledMethod = class_getInstanceMethod([self class], swizzledSelector);
}
method_exchangeImplementations(originalMethod, swizzledMethod);
}
+ (void)prepareDebuggingOverlaySwizzled {
id overlayClass = NSClassFromString(@"UIDebuggingInformationOverlayInvokeGestureHandler");
id handler = [overlayClass performSelector:NSSelectorFromString(@"mainHandler")];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:handler action:@selector(_handleActivationGesture:)];
tapGesture.numberOfTouchesRequired = 2;
tapGesture.numberOfTapsRequired = 1;
tapGesture.delegate = handler;
UIView *statusBarWindow = [[UIApplication sharedApplication] valueForKey:@"statusBarWindow"];
[statusBarWindow addGestureRecognizer:tapGesture];
}
@end
#pragma clang diagnostic pop
#endif
网友评论