Debug view hierarchy in Xcode 7.3 fails
Asked Answered
D

3

21

This function fails with runtime error:

-[UIWindow viewForFirstBaselineLayout]: unrecognized selector sent to instance 0x7fb9dae257d0

Anybody encountered the same?

UPD:
Fails on simulator iOS 8.1/8.4. 9.3 works fine.

UPD2: UIWindow is created like:

window = UIWindow(frame: UIScreen.mainScreen().bounds)    
window?.rootViewController = RootViewController.rootVC
window?.makeKeyAndVisible()
Dorsey answered 30/3, 2016 at 15:51 Comment(9)
what kinda deal do you do with the UIWindow, anyway?Overflow
No deal at all. The User Interface Inspector fails on its own.Dorsey
I am facing up the same problem now,looking for solutionsZenia
@orkenstein, which iOS version did throw such exception to you?Overflow
@holex, get this on simulators ios 8.1/8.4. Version 9.3 works correct.Dorsey
how do you create your UIWindow instance? could you share that knowledge as well?Overflow
@holex, check UPD2.Dorsey
for me also stopped working on 8.4 simulatorWittenberg
Have you tried testing on a device (e.g. iPhone)?Garry
N
21

I got the view debugger working again by placing the following fix in my project:

#ifdef DEBUG

#import <UIKit/UIKit.h>
#import <objc/runtime.h>

@implementation UIView (FixViewDebugging)

+ (void)load
{
    Method original = class_getInstanceMethod(self, @selector(viewForBaselineLayout));
    class_addMethod(self, @selector(viewForFirstBaselineLayout), method_getImplementation(original), method_getTypeEncoding(original));
    class_addMethod(self, @selector(viewForLastBaselineLayout), method_getImplementation(original), method_getTypeEncoding(original));
}

@end

#endif

When your project loads, the load method will execute, causing viewForFirstBaselineLayout and viewForLastBaselineLayout to use the viewForBaselineLayout implementation if they are not currently implemented, so view debugging gets iOS8 flavor the behavior it was looking for.

To add this to your own project, create a new empty Objective-C file in your project and paste the contents in. You can name it whatever you want. I call mine "UIView+FixViewDebugging". If you are in a pure Swift project you do not need to create a bridging header. The file will be compiled into your project and you don't need to reference it.

Note this will only work for debug builds because of the #ifdef DEBUG. You can remove it but then you may accidentally compile this into your release builds (though it should have no ill side effects). If this method isn't working with these lines, check that your target has DEBUG=1 in Build Settings > Apple LLVM - Preprocessing > Preprocessor Macros > Debug.

Nyhagen answered 28/4, 2016 at 22:34 Comment(6)
Still broken as of Xcode 7.3.1 (7D1014), with or without the swizzling above, even in 9.3 (13E230) Simulator.Frolicsome
Worked for me on XCode 7.3.1Nancee
Didn't work for me in XCode 7.3.1, iPhone 6s iOS 9.3.2.Linders
This piece of code might not work when you (like in my case) don't have the DEBUG flag enabled. Removing #ifdef #endif might solve your problem.Wounded
@MatthieuRiegler Thanks, I've added that to my answer.Nyhagen
Thank you! Worked perfectly with Xcode 7.3.1 and iOS 8.1 simulator.Stearic
D
21

Looks like Xcode 7.3 uses viewForFirstBaselineLayout property to draw the UI. But this property is marked as available since iOS 9.0.

Screenshot of UIView.h

[UIView viewForFirstBaselineLayout] method should be used for the version prior to iOS 9.0. It seems the guys from Apple didn't consider this case.

Dario answered 12/4, 2016 at 14:51 Comment(1)
That's correct, once I switched to iOS 8 simulator, the error happens and switched back to iOS 9, no more error.Schreibe
N
21

I got the view debugger working again by placing the following fix in my project:

#ifdef DEBUG

#import <UIKit/UIKit.h>
#import <objc/runtime.h>

@implementation UIView (FixViewDebugging)

+ (void)load
{
    Method original = class_getInstanceMethod(self, @selector(viewForBaselineLayout));
    class_addMethod(self, @selector(viewForFirstBaselineLayout), method_getImplementation(original), method_getTypeEncoding(original));
    class_addMethod(self, @selector(viewForLastBaselineLayout), method_getImplementation(original), method_getTypeEncoding(original));
}

@end

#endif

When your project loads, the load method will execute, causing viewForFirstBaselineLayout and viewForLastBaselineLayout to use the viewForBaselineLayout implementation if they are not currently implemented, so view debugging gets iOS8 flavor the behavior it was looking for.

To add this to your own project, create a new empty Objective-C file in your project and paste the contents in. You can name it whatever you want. I call mine "UIView+FixViewDebugging". If you are in a pure Swift project you do not need to create a bridging header. The file will be compiled into your project and you don't need to reference it.

Note this will only work for debug builds because of the #ifdef DEBUG. You can remove it but then you may accidentally compile this into your release builds (though it should have no ill side effects). If this method isn't working with these lines, check that your target has DEBUG=1 in Build Settings > Apple LLVM - Preprocessing > Preprocessor Macros > Debug.

Nyhagen answered 28/4, 2016 at 22:34 Comment(6)
Still broken as of Xcode 7.3.1 (7D1014), with or without the swizzling above, even in 9.3 (13E230) Simulator.Frolicsome
Worked for me on XCode 7.3.1Nancee
Didn't work for me in XCode 7.3.1, iPhone 6s iOS 9.3.2.Linders
This piece of code might not work when you (like in my case) don't have the DEBUG flag enabled. Removing #ifdef #endif might solve your problem.Wounded
@MatthieuRiegler Thanks, I've added that to my answer.Nyhagen
Thank you! Worked perfectly with Xcode 7.3.1 and iOS 8.1 simulator.Stearic
A
0

Yes. when click the debug view hierarchy button ,the page has nothing, and print "[UIWindow viewForFirstBaselineLayout]: unrecognized selector sent to instance 0x7fb9dae257d0" .

To solved it, just be sure you are using the iOS systom not below iOS 9.0 and you will still use that function freely.

Allynallys answered 31/5, 2016 at 6:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.