diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index eb2ebd7..0000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ab77023 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +*.diff +*.mode1v3 +*.orig +*.pbxuser +*.perspective +*.perspectivev3 +*.swp +.DS_Store +build/ +dist/ +project.xcworkspace/ +tags +xcuserdata/ +docs/*.html +docs/referencia +.DS_Store +DCIntrospectDemo/DCIntrospectDemo.xcodeproj/project.xcworkspace/xcuserdata/aircat.xcuserdatad/UserInterfaceState.xcuserstate +DCIntrospectDemo/DCIntrospectDemo.xcodeproj/project.xcworkspace/xcuserdata/domesticcat.xcuserdatad/UserInterfaceState.xcuserstate +DCIntrospectDemo/DCIntrospectDemo.xcodeproj/xcuserdata/aircat.xcuserdatad/xcschemes/xcschememanagement.plist +DCIntrospectDemo/DCIntrospectDemo.xcodeproj/xcuserdata/domesticcat.xcuserdatad/xcschemes/DCIntrospectDemo.xcscheme +DCIntrospectDemo/DCIntrospectDemo/.DS_Store +DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoViewController (Air-Cat's conflicted copy 2011-07-27).h +DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoViewController (Air-Cat's conflicted copy 2011-07-27).m +DCIntrospectDemo/DCIntrospectDemo/en.lproj/MainWindow (Air-Cat's conflicted copy 2011-07-27).xib \ No newline at end of file diff --git a/DCIntrospect/DCCrossHairView.h b/DCIntrospect/DCCrossHairView.h new file mode 100644 index 0000000..7160ffa --- /dev/null +++ b/DCIntrospect/DCCrossHairView.h @@ -0,0 +1,16 @@ +// +// DCCrossHairView.h +// +// Created by Domestic Cat on 3/05/11. +// + + +@interface DCCrossHairView : UIView +{ +} + +@property (nonatomic, retain) UIColor *color; + +- (id)initWithFrame:(CGRect)frame color:(UIColor *)aColor; + +@end diff --git a/DCIntrospect/DCCrossHairView.m b/DCIntrospect/DCCrossHairView.m new file mode 100644 index 0000000..cc1c989 --- /dev/null +++ b/DCIntrospect/DCCrossHairView.m @@ -0,0 +1,43 @@ +// +// DCCrossHairView.m +// +// Created by Domestic Cat on 3/05/11. +// + +#import "DCCrossHairView.h" + +@implementation DCCrossHairView +@synthesize color; + +- (void)dealloc +{ + [color release]; + [super dealloc]; +} + +- (id)initWithFrame:(CGRect)frame color:(UIColor *)aColor +{ + if ((self = [super initWithFrame:frame])) + { + self.color = aColor; + self.backgroundColor = [UIColor clearColor]; + self.opaque = NO; + } + + return self; +} + +- (void)drawRect:(CGRect)rect +{ + CGContextRef context = UIGraphicsGetCurrentContext(); + [self.color set]; + CGContextMoveToPoint(context, floorf(self.bounds.size.width / 2.0f) + 0.5f, 0.0f); + CGContextAddLineToPoint(context, floorf(self.bounds.size.width / 2.0f) + 0.5f, self.bounds.size.height); + CGContextStrokePath(context); + + CGContextMoveToPoint(context, 0, floorf(self.bounds.size.height / 2.0f) + 0.5f); + CGContextAddLineToPoint(context, self.bounds.size.width, floorf(self.bounds.size.height / 2.0f) + 0.5f); + CGContextStrokePath(context); +} + +@end diff --git a/DCIntrospect/DCFrameView.h b/DCIntrospect/DCFrameView.h index d5d3502..393f9b6 100644 --- a/DCIntrospect/DCFrameView.h +++ b/DCIntrospect/DCFrameView.h @@ -1,16 +1,55 @@ // // DCFrameView.h -// DCIntrospect // // Created by Domestic Cat on 29/04/11. // +#import +#import "DCCrossHairView.h" + +@protocol DCFrameViewDelegate + +@required + +- (void)touchAtPoint:(CGPoint)point; + +@end + @interface DCFrameView : UIView { - + } +@property (nonatomic, assign) id delegate; @property (nonatomic) CGRect mainRect; @property (nonatomic) CGRect superRect; +@property (nonatomic, retain) UILabel *touchPointLabel; +@property (nonatomic, retain) NSMutableArray *rectsToOutline; +@property (nonatomic, retain) DCCrossHairView *touchPointView; + +/////////// +// Setup // +/////////// + +- (id)initWithFrame:(CGRect)frame delegate:(id)aDelegate; + +//////////////////// +// Custom Setters // +//////////////////// + +- (void)setMainRect:(CGRect)newMainRect; +- (void)setSuperRect:(CGRect)newSuperRect; + +///////////////////// +// Drawing/Display // +///////////////////// + +- (void)drawRect:(CGRect)rect; + +//////////////////// +// Touch Handling // +//////////////////// + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; @end diff --git a/DCIntrospect/DCFrameView.m b/DCIntrospect/DCFrameView.m index c459d09..040fcd9 100644 --- a/DCIntrospect/DCFrameView.m +++ b/DCIntrospect/DCFrameView.m @@ -1,33 +1,60 @@ // // DCFrameView.m -// DCIntrospectDemo // // Created by Domestic Cat on 29/04/11. -// Copyright 2011 __MyCompanyName__. All rights reserved. // #import "DCFrameView.h" - @implementation DCFrameView +@synthesize delegate; @synthesize mainRect, superRect; +@synthesize touchPointLabel; +@synthesize rectsToOutline; +@synthesize touchPointView; - (void)dealloc { + self.delegate = nil; + [touchPointLabel release]; + [touchPointView release]; + [super dealloc]; } -- (id)initWithFrame:(CGRect)frame +#pragma mark - Setup + +- (id)initWithFrame:(CGRect)frame delegate:(id)aDelegate { self = [super initWithFrame:frame]; if (self) { + self.delegate = aDelegate; self.backgroundColor = [UIColor clearColor]; self.opaque = NO; + + self.touchPointLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease]; + self.touchPointLabel.text = @"X 320 Y 480"; + self.touchPointLabel.font = [UIFont boldSystemFontOfSize:12.0f]; + self.touchPointLabel.textAlignment = UITextAlignmentCenter; + self.touchPointLabel.textColor = [UIColor whiteColor]; + self.touchPointLabel.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.65f]; + self.touchPointLabel.layer.cornerRadius = 5.5f; + self.touchPointLabel.layer.masksToBounds = YES; + self.touchPointLabel.alpha = 0.0f; + [self addSubview:self.touchPointLabel]; + + self.rectsToOutline = [NSMutableArray array]; + + self.touchPointView = [[[DCCrossHairView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 17.0f, 17.0f) color:[UIColor blueColor]] autorelease]; + self.touchPointView.alpha = 0.0f; + [self addSubview:self.touchPointView]; } return self; } +#pragma mark - Custom Setters + - (void)setMainRect:(CGRect)newMainRect { mainRect = newMainRect; @@ -40,68 +67,168 @@ - (void)setSuperRect:(CGRect)newSuperRect [self setNeedsDisplay]; } +#pragma mark - Drawing/Display + - (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); - CGContextClearRect(context, self.bounds); - - [[UIColor blueColor] set]; - mainRect = CGRectMake(mainRect.origin.x + 0.5, - mainRect.origin.y + 0.5, - mainRect.size.width - 1.0, - mainRect.size.height - 1.0); - CGContextStrokeRect(context, mainRect); - - UIFont *font = [UIFont boldSystemFontOfSize:11]; - CGSize widthTextSize; - CGSize heightTextSize; + + if (self.rectsToOutline.count > 0) + { + for (NSValue *value in self.rectsToOutline) + { + UIColor *randomColor = [UIColor colorWithRed:(arc4random() % 256) / 256.0f + green:(arc4random() % 256) / 256.0f + blue:(arc4random() % 256) / 256.0f + alpha:1.0f]; + [randomColor set]; + CGRect valueRect = [value CGRectValue]; + valueRect = CGRectMake(valueRect.origin.x + 0.5f, + valueRect.origin.y + 0.5f, + valueRect.size.width - 1.0f, + valueRect.size.height - 1.0f); + CGContextStrokeRect(context, valueRect); + } + return; + } + + if (CGRectIsEmpty(self.mainRect)) + return; + CGRect mainRectOffset = CGRectOffset(mainRect, -superRect.origin.x, -superRect.origin.y); + BOOL showAntialiasingWarning = NO; + if (! CGRectIsEmpty(self.superRect)) + { + if ((mainRectOffset.origin.x != floorf(mainRectOffset.origin.x) && mainRect.origin.x != 0) || (mainRectOffset.origin.y != floor(mainRectOffset.origin.y) && mainRect.origin.y != 0)) + showAntialiasingWarning = YES; + } + + if (showAntialiasingWarning) + { + [[UIColor redColor] set]; + NSLog(@"DCIntrospect: *** WARNING: One or more values of this view's frame are non-integer values. This view will likely look blurry. ***"); + } + else + { + [[UIColor blueColor] set]; + } + + CGRect adjustedMainRect = CGRectMake(self.mainRect.origin.x + 0.5f, + self.mainRect.origin.y + 0.5f, + self.mainRect.size.width - 1.0f, + self.mainRect.size.height - 1.0f); + CGContextStrokeRect(context, adjustedMainRect); - NSString *widthText = [NSString stringWithFormat:@"%.1f", mainRect.size.width]; - widthTextSize = [widthText sizeWithFont:font]; - CGRect widthTextRect = CGRectMake(mainRect.origin.x + (mainRect.size.width - widthTextSize.width) / 2, - mainRect.origin.y - widthTextSize.height, - widthTextSize.width, - widthTextSize.height); - if (widthTextRect.origin.y < 0) - widthTextRect.origin.y = 2.0; - [widthText drawInRect:widthTextRect withFont:font]; - - NSString *heightText = [NSString stringWithFormat:@"%.1f", mainRect.size.height]; - heightTextSize = [widthText sizeWithFont:font]; - CGRect heightTextRect = CGRectMake(mainRect.origin.x - heightTextSize.width, - mainRect.origin.y + (mainRect.size.height - heightTextSize.height) / 2, - widthTextSize.width, - widthTextSize.height); - if (heightTextRect.origin.x < 0) - heightTextRect.origin.x = 2.0; - [heightText drawInRect:heightTextRect withFont:font]; + UIFont *font = [UIFont systemFontOfSize:10.0f]; float dash[2] = {3, 3}; CGContextSetLineDash(context, 0, dash, 2); - [UIColor colorWithRed:0.0 green:0.0 blue:1.0 alpha:0.5]; - // edge->left side - CGContextMoveToPoint(context, superRect.origin.x, floorf(CGRectGetMidY(mainRect)) + 0.5); - CGContextAddLineToPoint(context, mainRect.origin.x - widthTextSize.width - 2.0, floorf(CGRectGetMidY(mainRect)) + 0.5); + CGContextMoveToPoint(context, CGRectGetMinX(self.superRect), floorf(CGRectGetMidY(adjustedMainRect)) + 0.5f); + CGContextAddLineToPoint(context, CGRectGetMinX(adjustedMainRect), floorf(CGRectGetMidY(adjustedMainRect)) + 0.5f); CGContextStrokePath(context); - // left side->edge - CGContextMoveToPoint(context, CGRectGetMaxX(mainRect), floorf(CGRectGetMidY(mainRect)) + 0.5); - CGContextAddLineToPoint(context, CGRectGetMaxX(superRect), floorf(CGRectGetMidY(mainRect)) + 0.5); - CGContextStrokePath(context); + NSString *leftDistanceString = (showAntialiasingWarning) ? [NSString stringWithFormat:@"%.1f", CGRectGetMinX(mainRectOffset)] : [NSString stringWithFormat:@"%.0f", CGRectGetMinX(mainRectOffset)]; + CGSize leftDistanceStringSize = [leftDistanceString sizeWithFont:font]; + [leftDistanceString drawInRect:CGRectMake(CGRectGetMinX(superRect) + 1.0f, + floorf(CGRectGetMidY(adjustedMainRect)) - leftDistanceStringSize.height, + leftDistanceStringSize.width, + leftDistanceStringSize.height) + withFont:font]; + + // right side->edge + if (CGRectGetMaxX(self.mainRect) < CGRectGetMaxX(self.superRect)) + { + CGContextMoveToPoint(context, CGRectGetMaxX(adjustedMainRect), floorf(CGRectGetMidY(adjustedMainRect)) + 0.5f); + CGContextAddLineToPoint(context, CGRectGetMaxX(self.superRect), floorf(CGRectGetMidY(adjustedMainRect)) + 0.5f); + CGContextStrokePath(context); + } + NSString *rightDistanceString = (showAntialiasingWarning) ? [NSString stringWithFormat:@"%.1f", CGRectGetMaxX(self.superRect) - CGRectGetMaxX(adjustedMainRect) - 0.5] : [NSString stringWithFormat:@"%.0f", CGRectGetMaxX(self.superRect) - CGRectGetMaxX(adjustedMainRect) - 0.5]; + CGSize rightDistanceStringSize = [rightDistanceString sizeWithFont:font]; + [rightDistanceString drawInRect:CGRectMake(CGRectGetMaxX(self.superRect) - rightDistanceStringSize.width - 1.0f, + floorf(CGRectGetMidY(adjustedMainRect)) - 0.5f - rightDistanceStringSize.height, + rightDistanceStringSize.width, + rightDistanceStringSize.height) + withFont:font]; // edge->top side - CGContextMoveToPoint(context, floorf(CGRectGetMidX(mainRect)) + 0.5, superRect.origin.y); - CGContextAddLineToPoint(context, floorf(CGRectGetMidX(mainRect)) + 0.5, CGRectGetMinY(mainRect) - heightTextSize.height - 2.0); + CGContextMoveToPoint(context, floorf(CGRectGetMidX(adjustedMainRect)) + 0.5f, self.superRect.origin.y); + CGContextAddLineToPoint(context, floorf(CGRectGetMidX(adjustedMainRect)) + 0.5f, CGRectGetMinY(adjustedMainRect)); CGContextStrokePath(context); + NSString *topDistanceString = (showAntialiasingWarning) ? [NSString stringWithFormat:@"%.1f", mainRectOffset.origin.y] : [NSString stringWithFormat:@"%.0f", mainRectOffset.origin.y]; + CGSize topDistanceStringSize = [topDistanceString sizeWithFont:font]; + [topDistanceString drawInRect:CGRectMake(floorf(CGRectGetMidX(adjustedMainRect)) + 3.0f, + floorf(CGRectGetMinY(self.superRect)), + topDistanceStringSize.width, + topDistanceStringSize.height) + withFont:font]; // bottom side->edge - CGContextMoveToPoint(context, floorf(CGRectGetMidX(mainRect)) + 0.5, CGRectGetMaxY(mainRect)); - CGContextAddLineToPoint(context, floorf(CGRectGetMidX(mainRect)) + 0.5, CGRectGetMaxY(superRect)); - CGContextStrokePath(context); + if (CGRectGetMaxY(self.mainRect) < CGRectGetMaxY(self.superRect)) + { + CGContextMoveToPoint(context, floorf(CGRectGetMidX(adjustedMainRect)) + 0.5f, CGRectGetMaxY(adjustedMainRect)); + CGContextAddLineToPoint(context, floorf(CGRectGetMidX(adjustedMainRect)) + 0.5f, CGRectGetMaxY(self.superRect)); + CGContextStrokePath(context); + } + NSString *bottomDistanceString = (showAntialiasingWarning) ? [NSString stringWithFormat:@"%.1f", CGRectGetMaxY(self.superRect) - CGRectGetMaxY(mainRectOffset)] : [NSString stringWithFormat:@"%.0f", self.superRect.size.height - mainRectOffset.origin.y - mainRectOffset.size.height]; + CGSize bottomDistanceStringSize = [bottomDistanceString sizeWithFont:font]; + [bottomDistanceString drawInRect:CGRectMake(floorf(CGRectGetMidX(adjustedMainRect)) + 3.0f, + floorf(CGRectGetMaxY(self.superRect)) - bottomDistanceStringSize.height - 1.0f, + bottomDistanceStringSize.width, + bottomDistanceStringSize.height) + withFont:font]; + } +#pragma mark - Touch Handling + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + CGFloat labelDistance = 16.0f; + CGPoint touchPoint = [[touches anyObject] locationInView:self]; + + // adjust the point so it's exactly on the point of the mouse cursor + touchPoint.x -= 1; + touchPoint.y -= 2; + + NSString *touchPontLabelString = [NSString stringWithFormat:@"%.0f, %.0f", touchPoint.x, touchPoint.y]; + self.touchPointLabel.text = touchPontLabelString; + + CGSize stringSize = [touchPontLabelString sizeWithFont:touchPointLabel.font]; + CGRect frame = CGRectMake(touchPoint.x - floorf(stringSize.width / 2.0f) - 5.0f, + touchPoint.y - stringSize.height - labelDistance, + stringSize.width + 11.0f, + stringSize.height + 4.0f); + + // make sure the label stays inside the frame + UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; + CGFloat minY = UIInterfaceOrientationIsPortrait(orientation) ? [UIApplication sharedApplication].statusBarFrame.size.height : [UIApplication sharedApplication].statusBarFrame.size.width; + minY += 2.0f; // to keep it touching the top bar + if (frame.origin.x < 2.0f) + frame.origin.x = 2.0f; + else if (CGRectGetMaxX(frame) > self.bounds.size.width - 2.0f) + frame.origin.x = self.bounds.size.width - frame.size.width - 2.0f; + if (frame.origin.y < minY) + frame.origin.y = touchPoint.y + stringSize.height + 4.0f; + + self.touchPointLabel.frame = frame; + self.touchPointView.center = CGPointMake(touchPoint.x + 0.5f, touchPoint.y + 0.5f); + self.touchPointView.alpha = self.touchPointLabel.alpha = 1.0f; + + [self.delegate touchAtPoint:touchPoint]; +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self touchesBegan:touches withEvent:event]; +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + [UIView animateWithDuration:0.08 animations:^{ + self.touchPointView.alpha = self.touchPointLabel.alpha = 0.0f; + }]; +} @end diff --git a/DCIntrospect/DCIntrospect.h b/DCIntrospect/DCIntrospect.h index a718738..f7178bc 100644 --- a/DCIntrospect/DCIntrospect.h +++ b/DCIntrospect/DCIntrospect.h @@ -1,36 +1,155 @@ // -// DCIntrospect +// DCIntrospect.h // // Created by Domestic Cat on 29/04/11. // -#import +#define kDCIntrospectNotificationIntrospectionDidStart @"kDCIntrospectNotificationIntrospectionDidStart" +#define kDCIntrospectNotificationIntrospectionDidEnd @"kDCIntrospectNotificationIntrospectionDidEnd" +#define kDCIntrospectAnimationDuration 0.08 + +#import +#include "TargetConditionals.h" + +#import "DCIntrospectSettings.h" #import "DCFrameView.h" -#import +#import "DCStatusBarOverlay.h" -@interface DCIntrospect : NSObject -{ +#ifdef DEBUG + +@interface UIView (debug) + +- (NSString *)recursiveDescription; +@end + +#endif + +@interface DCIntrospect : NSObject +{ } +@property (nonatomic) BOOL keyboardBindingsOn; // default: YES +@property (nonatomic) BOOL showStatusBarOverlay; // default: YES +@property (nonatomic, retain) UIGestureRecognizer *invokeGestureRecognizer; // default: nil + +@property (nonatomic) BOOL on; +@property (nonatomic) BOOL handleArrowKeys; +@property (nonatomic) BOOL viewOutlines; +@property (nonatomic) BOOL highlightNonOpaqueViews; +@property (nonatomic) BOOL flashOnRedraw; @property (nonatomic, retain) DCFrameView *frameView; +@property (nonatomic, retain) UITextView *inputTextView; +@property (nonatomic, retain) DCStatusBarOverlay *statusBarOverlay; + +@property (nonatomic, retain) NSMutableDictionary *objectNames; + @property (nonatomic, assign) UIView *currentView; +@property (nonatomic) CGRect originalFrame; +@property (nonatomic) CGFloat originalAlpha; +@property (nonatomic, retain) NSMutableArray *currentViewHistory; + +@property (nonatomic) BOOL showingHelp; -+ (DCIntrospect *)sharedIntrospector; -- (void)start; +/////////// +// Setup // +/////////// + ++ (DCIntrospect *)sharedIntrospector; // this returns nil when NOT in DEGBUG mode +- (void)start; // NOTE: call setup AFTER [window makeKeyAndVisible] so statusBarOrientation is reported correctly. + +//////////////////// +// Custom Setters // +//////////////////// + +- (void)setInvokeGestureRecognizer:(UIGestureRecognizer *)newGestureRecognizer; +- (void)setKeyboardBindingsOn:(BOOL)keyboardBindingsOn; ////////////////// -// Introspector // +// Main Actions // ////////////////// -- (void)introspectorInvoked:(UIGestureRecognizer *)gestureRecognizer; +- (void)invokeIntrospector; // can be called manually +- (void)touchAtPoint:(CGPoint)point; // can be called manually +- (void)selectView:(UIView *)view; +- (void)statusBarTapped; + +////////////////////// +// Keyboard Capture // +////////////////////// + +- (void)textViewDidChangeSelection:(UITextView *)textView; +- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)string; + +///////////////////////////////// +// Logging Code & Object Names // +///////////////////////////////// + +- (void)logCodeForCurrentViewChanges; + +// make sure all names that are added are removed at dealloc or else they will be retained here! +- (void)setName:(NSString *)name forObject:(id)object accessedWithSelf:(BOOL)accessedWithSelf; +- (NSString *)nameForObject:(id)object; +- (void)removeNamesForViewsInView:(UIView *)view; +- (void)removeNameForObject:(id)object; + +//////////// +// Layout // +//////////// + - (void)updateFrameView; +- (void)updateStatusBar; +- (void)updateViews; +- (void)showTemporaryStringInStatusBar:(NSString *)string; + +///////////// +// Actions // +///////////// + +- (void)logRecursiveDescriptionForCurrentView; +- (void)logRecursiveDescriptionForView:(UIView *)view; +- (void)forceSetNeedsDisplay; +- (void)forceSetNeedsLayout; +- (void)forceReloadOfView; +- (void)toggleOutlines; +- (void)addOutlinesToFrameViewFromSubview:(UIView *)view; +- (void)toggleNonOpaqueViews; +- (void)setBackgroundColor:(UIColor *)color ofNonOpaqueViewsInSubview:(UIView *)view; +- (void)toggleRedrawFlashing; +- (void)callDrawRectOnViewsInSubview:(UIView *)subview; +- (void)flashRect:(CGRect)rect inView:(UIView *)view; + +///////////////////////////// +// (Somewhat) Experimental // +///////////////////////////// + +- (void)logPropertiesForCurrentView; +- (void)logPropertiesForObject:(id)object; +- (void)logAccessabilityPropertiesForObject:(id)object; +- (NSArray *)subclassesOfClass:(Class)parentClass; + +///////////////////////// +// Description Methods // +///////////////////////// + +- (NSString *)describeProperty:(NSString *)propertyName value:(id)value; +- (NSString *)describeColor:(UIColor *)color; + +///////////////////////// +// DCIntrospector Help // +///////////////////////// + +- (void)toggleHelp; +- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; //////////////////// // Helper Methods // //////////////////// - (UIWindow *)mainWindow; -- (NSMutableArray *)findViewsAtPoint:(CGPoint)touchPoint inView:(UIView *)view addToArray:(NSMutableArray *)views; +- (NSMutableArray *)viewsAtPoint:(CGPoint)touchPoint inView:(UIView *)view; +- (void)fadeView:(UIView *)view toAlpha:(CGFloat)alpha; +- (BOOL)view:(UIView *)view containsSubview:(UIView *)subview; +- (BOOL)shouldIgnoreView:(UIView *)view; @end diff --git a/DCIntrospect/DCIntrospect.m b/DCIntrospect/DCIntrospect.m index df5fdbf..520113a 100644 --- a/DCIntrospect/DCIntrospect.m +++ b/DCIntrospect/DCIntrospect.m @@ -1,24 +1,180 @@ // -// DCIntrospect +// DCIntrospect.m // // Created by Domestic Cat on 29/04/11. // #import "DCIntrospect.h" +#import + +#include +#include +#include +#include +#include + +// break into GDB code complied from following sources: +// http://blog.timac.org/?p=190, http://developer.apple.com/library/mac/#qa/qa1361/_index.html, http://cocoawithlove.com/2008/03/break-into-debugger.html + +// Returns true if the current process is being debugged (either +// running under the debugger or has a debugger attached post facto). +static bool AmIBeingDebugged(void) +{ + int junk; + int mib[4]; + struct kinfo_proc info; + size_t size; + + // Initialize the flags so that, if sysctl fails for some bizarre + // reason, we get a predictable result. + + info.kp_proc.p_flag = 0; + + // Initialize mib, which tells sysctl the info we want, in this case + // we're looking for information about a specific process ID. + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + + // Call sysctl. + + size = sizeof(info); + junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0); + assert(junk == 0); + + // We're being debugged if the P_TRACED flag is set. + + return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); +} + +#if TARGET_CPU_ARM +#define DEBUGSTOP(signal) __asm__ __volatile__ ("mov r0, %0\nmov r1, %1\nmov r12, %2\nswi 128\n" : : "r"(getpid ()), "r"(signal), "r"(37) : "r12", "r0", "r1", "cc"); +#define DEBUGGER do { int trapSignal = AmIBeingDebugged () ? SIGINT : SIGSTOP; DEBUGSTOP(trapSignal); if (trapSignal == SIGSTOP) { DEBUGSTOP (SIGINT); } } while (false); +#elif TARGET_CPU_X86 || TARGET_CPU_X86_64 +#define DEBUGGER do { int trapSignal = AmIBeingDebugged () ? SIGINT : SIGSTOP; __asm__ __volatile__ ("pushl %0\npushl %1\npush $0\nmovl %2, %%eax\nint $0x80\nadd $12, %%esp" : : "g" (trapSignal), "g" (getpid ()), "n" (37) : "eax", "cc"); } while (false); +#else +#define DEBUGGER +#warning "Debugger disabled." +#endif + +@interface DCIntrospect () + +- (void)takeFirstResponder; + +@end + DCIntrospect *sharedInstance = nil; @implementation DCIntrospect +@synthesize keyboardBindingsOn, showStatusBarOverlay, invokeGestureRecognizer; +@synthesize on; +@synthesize handleArrowKeys; +@synthesize viewOutlines, highlightNonOpaqueViews, flashOnRedraw; +@synthesize statusBarOverlay; +@synthesize inputTextView; @synthesize frameView; -@synthesize currentView; +@synthesize objectNames; +@synthesize currentView, originalFrame, originalAlpha; +@synthesize currentViewHistory; +@synthesize showingHelp; + +#pragma mark Setup + ++ (void)load +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + NSString *simulatorRoot = [[[NSProcessInfo processInfo] environment] objectForKey:@"IPHONE_SIMULATOR_ROOT"]; + if (simulatorRoot) + { + void *AppSupport = dlopen([[simulatorRoot stringByAppendingPathComponent:@"/System/Library/PrivateFrameworks/AppSupport.framework/AppSupport"] fileSystemRepresentation], RTLD_LAZY); + CFStringRef (*CPCopySharedResourcesPreferencesDomainForDomain)(CFStringRef domain) = (CFStringRef (*)())dlsym(AppSupport, "CPCopySharedResourcesPreferencesDomainForDomain"); + if (CPCopySharedResourcesPreferencesDomainForDomain) + { + CFStringRef accessibilityDomain = CPCopySharedResourcesPreferencesDomainForDomain(CFSTR("com.apple.Accessibility")); + if (accessibilityDomain) + { + // This must be done *before* UIApplicationMain, hence +load + CFPreferencesSetValue(CFSTR("ApplicationAccessibilityEnabled"), kCFBooleanTrue, accessibilityDomain, kCFPreferencesAnyUser, kCFPreferencesAnyHost); + CFRelease(accessibilityDomain); + } + } + } + + [pool drain]; +} + +static void *originalValueForKeyIMPKey = &originalValueForKeyIMPKey; + +id UITextInputTraits_valueForKey(id self, SEL _cmd, NSString *key); +id UITextInputTraits_valueForKey(id self, SEL _cmd, NSString *key) +{ + static NSMutableSet *textInputTraitsProperties = nil; + if (!textInputTraitsProperties) + { + textInputTraitsProperties = [[NSMutableSet alloc] init]; + unsigned int count = 0; + objc_property_t *properties = protocol_copyPropertyList(@protocol(UITextInputTraits), &count); + for (unsigned int i = 0; i < count; i++) + { + objc_property_t property = properties[i]; + NSString *propertyName = [NSString stringWithUTF8String:property_getName(property)]; + [textInputTraitsProperties addObject:propertyName]; + } + free(properties); + } + + IMP valueForKey = (IMP)[objc_getAssociatedObject([self class], originalValueForKeyIMPKey) pointerValue]; + if ([textInputTraitsProperties containsObject:key]) + { + id textInputTraits = valueForKey(self, _cmd, @"textInputTraits"); + return valueForKey(textInputTraits, _cmd, key); + } + else + { + return valueForKey(self, _cmd, key); + } +} + +// See http://stackoverflow.com/questions/6617472/why-does-valueforkey-on-a-uitextfield-throws-an-exception-for-uitextinputtraits ++ (void)workaroundUITextInputTraitsPropertiesBug +{ + Method valueForKey = class_getInstanceMethod([NSObject class], @selector(valueForKey:)); + const char *valueForKeyTypeEncoding = method_getTypeEncoding(valueForKey); + + unsigned int count = 0; + Class *classes = objc_copyClassList(&count); + for (unsigned int i = 0; i < count; i++) + { + Class class = classes[i]; + if (class_getInstanceMethod(class, NSSelectorFromString(@"textInputTraits"))) + { + IMP originalValueForKey = class_replaceMethod(class, @selector(valueForKey:), (IMP)UITextInputTraits_valueForKey, valueForKeyTypeEncoding); + if (!originalValueForKey) + originalValueForKey = (IMP)[objc_getAssociatedObject([class superclass], originalValueForKeyIMPKey) pointerValue]; + if (!originalValueForKey) + originalValueForKey = class_getMethodImplementation([class superclass], @selector(valueForKey:)); + + objc_setAssociatedObject(class, originalValueForKeyIMPKey, [NSValue valueWithPointer:(void *)originalValueForKey], OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + } + free(classes); +} + (DCIntrospect *)sharedIntrospector { +#ifdef DEBUG if (!sharedInstance) { sharedInstance = [[DCIntrospect alloc] init]; + sharedInstance.keyboardBindingsOn = YES; + sharedInstance.showStatusBarOverlay = ![UIApplication sharedApplication].statusBarHidden; + [self workaroundUITextInputTraitsPropertiesBug]; } - +#endif return sharedInstance; } @@ -27,96 +183,1475 @@ - (void)start UIWindow *mainWindow = [self mainWindow]; if (!mainWindow) { - NSLog(@"DCIntrospector: Couldn't start. No main window?"); + NSLog(@"DCIntrospect: Couldn't setup. No main window?"); return; } + + if (!self.statusBarOverlay) + { + self.statusBarOverlay = [[[DCStatusBarOverlay alloc] init] autorelease]; + } + + if (!self.inputTextView) + { + self.inputTextView = [[[UITextView alloc] initWithFrame:CGRectZero] autorelease]; + self.inputTextView.delegate = self; + self.inputTextView.autocorrectionType = UITextAutocorrectionTypeNo; + self.inputTextView.autocapitalizationType = UITextAutocapitalizationTypeNone; + self.inputTextView.inputView = [[[UIView alloc] init] autorelease]; + self.inputTextView.scrollsToTop = NO; + [mainWindow addSubview:self.inputTextView]; + } + + if (self.keyboardBindingsOn) + { + if (![self.inputTextView becomeFirstResponder]) + { + [self performSelector:@selector(takeFirstResponder) withObject:nil afterDelay:0.5]; + } + } + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarTapped) name:kDCIntrospectNotificationStatusBarTapped object:nil]; + + // reclaim the keyboard after dismissal if it is taken + [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillHideNotification + object:nil + queue:nil + usingBlock:^(NSNotification *notification) { + if (self.keyboardBindingsOn) + { + [self performSelector:@selector(takeFirstResponder) + withObject:nil + afterDelay:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]]; + } + }]; + + // dirty hack for UIWebView keyboard problems + [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillShowNotification + object:nil + queue:nil + usingBlock:^(NSNotification *notification) { + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(takeFirstResponder) object:nil]; + }]; + + // listen for device orientation changes to adjust the status bar + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateViews) name:UIDeviceOrientationDidChangeNotification object:nil]; + + if (!self.currentViewHistory) + self.currentViewHistory = [[[NSMutableArray alloc] init] autorelease]; + + NSLog(@"DCIntrospect is setup. %@ to start.", [kDCIntrospectKeysInvoke isEqualToString:@" "] ? @"Push the space bar" : [NSString stringWithFormat:@"Type '%@'", kDCIntrospectKeysInvoke]); +} + +- (void)takeFirstResponder +{ + if (![self.inputTextView becomeFirstResponder]) + NSLog(@"DCIntrospect: Couldn't reclaim keyboard input. Is the keyboard used elsewhere?"); +} - UITapGestureRecognizer *mainGestureRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(introspectorInvoked:)] autorelease]; - mainGestureRecognizer.cancelsTouchesInView = NO; - mainGestureRecognizer.delaysTouchesBegan = NO; - mainGestureRecognizer.delaysTouchesEnded = NO; - mainGestureRecognizer.numberOfTapsRequired = 2; - mainGestureRecognizer.numberOfTouchesRequired = 1; - [mainWindow addGestureRecognizer:mainGestureRecognizer]; +- (void)resetInputTextView +{ + self.inputTextView.text = @"\n2 4567 9\n"; + self.handleArrowKeys = NO; + self.inputTextView.selectedRange = NSMakeRange(5, 0); + self.handleArrowKeys = YES; } -#pragma Introspector +#pragma mark Custom Setters +- (void)setInvokeGestureRecognizer:(UIGestureRecognizer *)newGestureRecognizer +{ + UIWindow *mainWindow = [self mainWindow]; + [mainWindow removeGestureRecognizer:invokeGestureRecognizer]; + + [invokeGestureRecognizer release]; + invokeGestureRecognizer = nil; + invokeGestureRecognizer = [newGestureRecognizer retain]; + [invokeGestureRecognizer addTarget:self action:@selector(invokeIntrospector)]; + [mainWindow addGestureRecognizer:invokeGestureRecognizer]; +} -- (void)introspectorInvoked:(UIGestureRecognizer *)gestureRecognizer +- (void)setKeyboardBindingsOn:(BOOL)areKeyboardBindingsOn { - self.currentView.layer.borderWidth = 0.0; - CGPoint touchPoint = [gestureRecognizer locationInView:nil]; + keyboardBindingsOn = areKeyboardBindingsOn; + if (self.keyboardBindingsOn) + [self.inputTextView becomeFirstResponder]; + else + [self.inputTextView resignFirstResponder]; +} + +#pragma mark Main Actions - NSMutableArray *views = [NSMutableArray new]; - views = [self findViewsAtPoint:touchPoint inView:[self mainWindow] addToArray:views]; - NSLog(@"got back %@", views); - self.currentView = [views lastObject]; - self.currentView.layer.borderColor = [UIColor blueColor].CGColor; - self.currentView.layer.borderWidth = 1.0; +- (void)invokeIntrospector +{ + self.on = !self.on; + + if (self.on) + { + [self updateViews]; + [self updateStatusBar]; + [self updateFrameView]; + + if (self.keyboardBindingsOn) + [self.inputTextView becomeFirstResponder]; + else + [self.inputTextView resignFirstResponder]; + + [self resetInputTextView]; + + [[NSNotificationCenter defaultCenter] postNotificationName:kDCIntrospectNotificationIntrospectionDidStart + object:nil]; + } + else + { + if (self.viewOutlines) + [self toggleOutlines]; + if (self.highlightNonOpaqueViews) + [self toggleNonOpaqueViews]; + if (self.showingHelp) + [self toggleHelp]; + + self.statusBarOverlay.hidden = YES; + self.frameView.alpha = 0; + self.currentView = nil; + + [[NSNotificationCenter defaultCenter] postNotificationName:kDCIntrospectNotificationIntrospectionDidEnd + object:nil]; + } +} + +- (void)touchAtPoint:(CGPoint)point +{ + // convert the point into the main window + CGPoint convertedTouchPoint = [[self mainWindow] convertPoint:point fromView:self.frameView]; + + // find all the views under that point – will be added in order on screen, ie mainWindow will be index 0, main view controller at index 1 etc. + NSMutableArray *views = [self viewsAtPoint:convertedTouchPoint inView:[self mainWindow]]; + if (views.count == 0) + return; + + // get the topmost view and setup the UI + [self.currentViewHistory removeAllObjects]; + UIView *newView = [views lastObject]; + [self selectView:newView]; +} + +- (void)selectView:(UIView *)view +{ + self.currentView = view; + self.originalFrame = self.currentView.frame; + self.originalAlpha = self.currentView.alpha; + + if (self.frameView.rectsToOutline.count > 0) + { + [self.frameView.rectsToOutline removeAllObjects]; + [self.frameView setNeedsDisplay]; + self.viewOutlines = NO; + } + [self updateFrameView]; + [self updateStatusBar]; + + if (![self.currentViewHistory containsObject:self.currentView]) + [self.currentViewHistory addObject:self.currentView]; } +- (void)statusBarTapped +{ + if (self.showingHelp) + { + [self toggleHelp]; + return; + } +} + +#pragma mark Keyboard Capture + +- (void)textViewDidChangeSelection:(UITextView *)textView +{ + if (!(self.on && self.handleArrowKeys)) + return; + + NSUInteger selectionLocation = textView.selectedRange.location; + NSUInteger selectionLength = textView.selectedRange.length; + BOOL shiftKey = selectionLength != 0; + BOOL optionKey = selectionLocation % 2 == 1; + + CGRect frame = self.currentView.frame; + if (shiftKey) + { + if (selectionLocation == 4 && selectionLength == 1) + frame.origin.x -= 10.0f; + else if (selectionLocation == 5 && selectionLength == 1) + frame.origin.x += 10.0f; + else if (selectionLocation == 0 && selectionLength == 5) + frame.origin.y -= 10.0f; + else if (selectionLocation == 5 && selectionLength == 5) + frame.origin.y += 10.0f; + } + else if (optionKey) + { + if (selectionLocation == 7) + frame.size.width += 1.0f; + else if (selectionLocation == 3) + frame.size.width -= 1.0f; + else if (selectionLocation == 9) + frame.size.height += 1.0f; + else if (selectionLocation == 1) + frame.size.height -= 1.0f; + } + else + { + if (selectionLocation == 4) + frame.origin.x -= 1.0f; + else if (selectionLocation == 6) + frame.origin.x += 1.0f; + else if (selectionLocation == 0) + frame.origin.y -= 1.0f; + else if (selectionLocation == 10) + frame.origin.y += 1.0f; + } + + self.currentView.frame = CGRectMake(floorf(frame.origin.x), + floorf(frame.origin.y), + floorf(frame.size.width), + floorf(frame.size.height)); + + [self updateFrameView]; + [self updateStatusBar]; + + [self resetInputTextView]; +} + +- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)string +{ + if ([string isEqualToString:kDCIntrospectKeysDisableForPeriod]) + { + [self setKeyboardBindingsOn:NO]; + [[self inputTextView] resignFirstResponder]; + NSLog(@"DCIntrospect: Disabled for %.1f seconds", kDCIntrospectTemporaryDisableDuration); + [self performSelector:@selector(setKeyboardBindingsOn:) withObject:[NSNumber numberWithFloat:YES] afterDelay:kDCIntrospectTemporaryDisableDuration]; + return NO; + } + + if ([string isEqualToString:kDCIntrospectKeysInvoke]) + { + [self invokeIntrospector]; + return NO; + } + + if (!self.on) + return NO; + + if (self.showingHelp) + { + [self toggleHelp]; + return NO; + } + + if ([string isEqualToString:kDCIntrospectKeysToggleViewOutlines]) + { + [self toggleOutlines]; + return NO; + } + else if ([string isEqualToString:kDCIntrospectKeysToggleNonOpaqueViews]) + { + [self toggleNonOpaqueViews]; + return NO; + } + else if ([string isEqualToString:kDCIntrospectKeysToggleFlashViewRedraws]) + { + [self toggleRedrawFlashing]; + return NO; + } + else if ([string isEqualToString:kDCIntrospectKeysToggleShowCoordinates]) + { + [UIView animateWithDuration:0.15 + delay:0 + options:UIViewAnimationOptionAllowUserInteraction + animations:^{ + self.frameView.touchPointLabel.alpha = !self.frameView.touchPointLabel.alpha; + } completion:^(BOOL finished) { + NSString *coordinatesString = [NSString stringWithFormat:@"Coordinates are %@", (self.frameView.touchPointLabel.alpha) ? @"on" : @"off"]; + if (self.showStatusBarOverlay) + [self showTemporaryStringInStatusBar:coordinatesString]; + else + NSLog(@"DCIntrospect: %@", coordinatesString); + }]; + return NO; + } + else if ([string isEqualToString:kDCIntrospectKeysToggleHelp]) + { + [self toggleHelp]; + return NO; + } + + if (self.on && self.currentView) + { + if ([string isEqualToString:kDCIntrospectKeysLogProperties]) + { + [self logPropertiesForObject:self.currentView]; + return NO; + } + else if ([string isEqualToString:kDCIntrospectKeysLogAccessibilityProperties]) + { + [self logAccessabilityPropertiesForObject:self.currentView]; + return NO; + } + else if ([string isEqualToString:kDCIntrospectKeysLogViewRecursive]) + { + [self logRecursiveDescriptionForView:self.currentView]; + return NO; + } + else if ([string isEqualToString:kDCIntrospectKeysSetNeedsDisplay]) + { + [self forceSetNeedsDisplay]; + return NO; + } + else if ([string isEqualToString:kDCIntrospectKeysSetNeedsLayout]) + { + [self forceSetNeedsLayout]; + return NO; + } + else if ([string isEqualToString:kDCIntrospectKeysReloadData]) + { + [self forceReloadOfView]; + return NO; + } + else if ([string isEqualToString:kDCIntrospectKeysMoveUpInViewHierarchy]) + { + if (self.currentView.superview) + { + [self selectView:self.currentView.superview]; + } + else + { + NSLog(@"DCIntrospect: At top of view hierarchy."); + return NO; + } + return NO; + } + else if ([string isEqualToString:kDCIntrospectKeysMoveBackInViewHierarchy]) + { + if (self.currentViewHistory.count == 0) + return NO; + + int indexOfCurrentView = [self.currentViewHistory indexOfObject:self.currentView]; + if (indexOfCurrentView == 0) + { + NSLog(@"DCIntrospect: At bottom of view history."); + return NO; + } + + [self selectView:[self.currentViewHistory objectAtIndex:indexOfCurrentView - 1]]; + } + else if ([string isEqualToString:kDCIntrospectKeysMoveDownToFirstSubview]) + { + if (self.currentView.subviews.count>0) { + [self selectView:[self.currentView.subviews objectAtIndex:0]]; + }else{ + NSLog(@"DCIntrospect: No subviews."); + return NO; + } + return NO; + } + else if ([string isEqualToString:kDCIntrospectKeysMoveToNextSiblingView]) + { + NSUInteger currentViewsIndex = [self.currentView.superview.subviews indexOfObject:self.currentView]; + + if (currentViewsIndex==NSNotFound) { + NSLog(@"DCIntrospect: BROKEN HIERARCHY."); + } else if (self.currentView.superview.subviews.count>currentViewsIndex + 1) { + [self selectView:[self.currentView.superview.subviews objectAtIndex:currentViewsIndex + 1]]; + }else{ + NSLog(@"DCIntrospect: No next sibling views."); + return NO; + } + return NO; + } + else if ([string isEqualToString:kDCIntrospectKeysMoveToPrevSiblingView]) + { + NSUInteger currentViewsIndex = [self.currentView.superview.subviews indexOfObject:self.currentView]; + if (currentViewsIndex==NSNotFound) { + NSLog(@"DCIntrospect: BROKEN HIERARCHY."); + } else if (currentViewsIndex!=0) { + [self selectView:[self.currentView.superview.subviews objectAtIndex:currentViewsIndex - 1]]; + } else { + NSLog(@"DCIntrospect: No previous sibling views."); + } + return NO; + } + else if ([string isEqualToString:kDCIntrospectKeysLogCodeForCurrentViewChanges]) + { + [self logCodeForCurrentViewChanges]; + return NO; + } + + CGRect frame = self.currentView.frame; + if ([string isEqualToString:kDCIntrospectKeysNudgeViewLeft]) + frame.origin.x -= 1.0f; + else if ([string isEqualToString:kDCIntrospectKeysNudgeViewRight]) + frame.origin.x += 1.0f; + else if ([string isEqualToString:kDCIntrospectKeysNudgeViewUp]) + frame.origin.y -= 1.0f; + else if ([string isEqualToString:kDCIntrospectKeysNudgeViewDown]) + frame.origin.y += 1.0f; + else if ([string isEqualToString:kDCIntrospectKeysCenterInSuperview]) + frame = CGRectMake(floorf((self.currentView.superview.frame.size.width - frame.size.width) / 2.0f), + floorf((self.currentView.superview.frame.size.height - frame.size.height) / 2.0f), + frame.size.width, + frame.size.height); + else if ([string isEqualToString:kDCIntrospectKeysIncreaseWidth]) + frame.size.width += 1.0f; + else if ([string isEqualToString:kDCIntrospectKeysDecreaseWidth]) + frame.size.width -= 1.0f; + else if ([string isEqualToString:kDCIntrospectKeysIncreaseHeight]) + frame.size.height += 1.0f; + else if ([string isEqualToString:kDCIntrospectKeysDecreaseHeight]) + frame.size.height -= 1.0f; + else if ([string isEqualToString:kDCIntrospectKeysIncreaseViewAlpha]) + { + if (self.currentView.alpha < 1.0f) + self.currentView.alpha += 0.05f; + } + else if ([string isEqualToString:kDCIntrospectKeysDecreaseViewAlpha]) + { + if (self.currentView.alpha > 0.0f) + self.currentView.alpha -= 0.05f; + } + else if ([string isEqualToString:kDCIntrospectKeysEnterGDB]) + { + UIView *view = self.currentView; + view.tag = view.tag; // suppress the xcode warning about an unused variable. + NSLog(@"DCIntrospect: access current view using local 'view' variable."); + DEBUGGER; + return NO; + } + + self.currentView.frame = CGRectMake(floorf(frame.origin.x), + floorf(frame.origin.y), + floorf(frame.size.width), + floorf(frame.size.height)); + + [self updateFrameView]; + [self updateStatusBar]; + } + + return NO; +} + +#pragma mark Object Names + +- (void)logCodeForCurrentViewChanges +{ + if (!self.currentView) + return; + + NSString *varName = [self nameForObject:self.currentView]; + if ([varName isEqualToString:[NSString stringWithFormat:@"%@", self.currentView.class]]) + varName = @"<#view#>"; + + NSMutableString *outputString = [NSMutableString string]; + if (!CGRectEqualToRect(self.originalFrame, self.currentView.frame)) + { + [outputString appendFormat:@"%@.frame = CGRectMake(%.1f, %.1f, %.1f, %.1f);\n", varName, self.currentView.frame.origin.x, self.currentView.frame.origin.y, self.currentView.frame.size.width, self.currentView.frame.size.height]; + } + + if (self.originalAlpha != self.currentView.alpha) + { + [outputString appendFormat:@"%@.alpha = %.2f;\n", varName, self.currentView.alpha]; + } + + if (outputString.length == 0) + NSLog(@"DCIntrospect: No changes made to %@.", self.currentView.class); + else + printf("\n\n%s\n", [outputString UTF8String]); +} + +- (void)setName:(NSString *)name forObject:(id)object accessedWithSelf:(BOOL)accessedWithSelf +{ + if (!self.objectNames) + self.objectNames = [NSMutableDictionary dictionary]; + + if (accessedWithSelf) + name = [@"self." stringByAppendingString:name]; + + [self.objectNames setValue:object forKey:name]; +} + +- (NSString *)nameForObject:(id)object +{ + __block NSString *objectName = [NSString stringWithFormat:@"%@", [object class]]; + if (!self.objectNames) + return objectName; + + [self.objectNames enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + if (obj == object) + { + objectName = (NSString *)key; + *stop = YES; + } + }]; + + return objectName; +} + +- (void)removeNamesForViewsInView:(UIView *)view +{ + if (!self.objectNames) + return; + + NSMutableArray *objectsToRemove = [NSMutableArray array]; + [self.objectNames enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + if ([[obj class] isSubclassOfClass:[UIView class]]) + { + UIView *subview = (UIView *)obj; + if ([self view:view containsSubview:subview]) + [objectsToRemove addObject:key]; + } + }]; + + [objectsToRemove enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + NSString *key = (NSString *)obj; + [self.objectNames removeObjectForKey:key]; + }]; +} + +- (void)removeNameForObject:(id)object +{ + if (!self.objectNames) + return; + + NSString *objectName = [self nameForObject:object]; + [self.objectNames removeObjectForKey:objectName]; +} + +#pragma mark Layout + - (void)updateFrameView { UIWindow *mainWindow = [self mainWindow]; if (!self.frameView) { - NSLog(@"Creating frameview"); - self.frameView = [[[DCFrameView alloc] initWithFrame:(CGRect){ CGPointZero, mainWindow.frame.size }] autorelease]; + self.frameView = [[[DCFrameView alloc] initWithFrame:(CGRect){ CGPointZero, mainWindow.frame.size } delegate:self] autorelease]; [mainWindow addSubview:self.frameView]; + self.frameView.alpha = 0.0f; + [self updateViews]; } - + [mainWindow bringSubviewToFront:self.frameView]; + + if (self.on) + { + if (self.currentView) + { + self.frameView.mainRect = [self.currentView.superview convertRect:self.currentView.frame toView:self.frameView]; + if (self.currentView.superview == mainWindow) + self.frameView.superRect = CGRectZero; + else if (self.currentView.superview.superview) + self.frameView.superRect = [self.currentView.superview.superview convertRect:self.currentView.superview.frame toView:self.frameView]; + else + self.frameView.superRect = CGRectZero; + } + else + { + self.frameView.mainRect = CGRectZero; + } + + [self fadeView:self.frameView toAlpha:1.0f]; + } + else + { + [self fadeView:self.frameView toAlpha:0.0f]; + } +} - [UIView animateWithDuration:0.1 - delay:0.0 - options:UIViewAnimationOptionAllowUserInteraction - animations:^{ - self.frameView.alpha = 0.0; - } - completion:nil]; +- (void)updateStatusBar +{ + if (self.currentView) + { + NSString *nameForObject = [self nameForObject:self.currentView]; + + // remove the 'self.' if it's there to save space + if ([nameForObject hasPrefix:@"self."]) + nameForObject = [nameForObject substringFromIndex:@"self.".length]; + + if (self.currentView.tag != 0) + self.statusBarOverlay.leftLabel.text = [NSString stringWithFormat:@"%@ (tag: %i)", nameForObject, self.currentView.tag]; + else + self.statusBarOverlay.leftLabel.text = [NSString stringWithFormat:@"%@", nameForObject]; + + self.statusBarOverlay.rightLabel.text = NSStringFromCGRect(self.currentView.frame); + } + else + { + self.statusBarOverlay.leftLabel.text = @"DCIntrospect"; + self.statusBarOverlay.rightLabel.text = [NSString stringWithFormat:@"'%@' for help", kDCIntrospectKeysToggleHelp]; + } + + if (self.showStatusBarOverlay) + self.statusBarOverlay.hidden = NO; + else + self.statusBarOverlay.hidden = YES; +} - self.frameView.mainRect = [self.currentView.superview convertRect:self.currentView.frame toView:self.frameView]; - self.frameView.superRect = [self.currentView.superview.superview convertRect:self.currentView.superview.frame toView:mainWindow]; +- (void)updateViews +{ + // current interface orientation + UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; + CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width; + CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height; + + CGFloat pi = (CGFloat)M_PI; + if (orientation == UIDeviceOrientationPortrait) + { + self.frameView.transform = CGAffineTransformIdentity; + self.frameView.frame = CGRectMake(0, 0, screenWidth, screenHeight); + } + else if (orientation == UIDeviceOrientationLandscapeLeft) + { + self.frameView.transform = CGAffineTransformMakeRotation(pi * (90) / 180.0f); + self.frameView.frame = CGRectMake(screenWidth - screenHeight, 0, screenHeight, screenHeight); + } + else if (orientation == UIDeviceOrientationLandscapeRight) + { + self.frameView.transform = CGAffineTransformMakeRotation(pi * (-90) / 180.0f); + self.frameView.frame = CGRectMake(0, 0, screenWidth, screenHeight); + } + else if (orientation == UIDeviceOrientationPortraitUpsideDown) + { + self.frameView.transform = CGAffineTransformMakeRotation(pi); + self.frameView.frame = CGRectMake(0, 0, screenWidth, screenHeight); + } + + self.currentView = nil; + [self updateFrameView]; +} - [UIView animateWithDuration:0.1 - delay:0.0 - options:UIViewAnimationOptionAllowUserInteraction - animations:^{ - self.frameView.alpha = 1.0; - } - completion:nil]; +- (void)showTemporaryStringInStatusBar:(NSString *)string +{ + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(updateStatusBar) object:nil]; + + self.statusBarOverlay.leftLabel.text = string; + self.statusBarOverlay.rightLabel.text = nil; + [self performSelector:@selector(updateStatusBar) withObject:nil afterDelay:0.75]; +} + +#pragma mark Actions + +- (void)logRecursiveDescriptionForCurrentView +{ + [self logRecursiveDescriptionForView:self.currentView]; +} + +- (void)logRecursiveDescriptionForView:(UIView *)view +{ +#ifdef DEBUG + // [UIView recursiveDescription] is a private method. This should probably be re-written to avoid any potential problems. + NSLog(@"DCIntrospect: %@", [view recursiveDescription]); +#endif +} + +- (void)forceSetNeedsDisplay +{ + [self.currentView setNeedsDisplay]; +} + +- (void)forceSetNeedsLayout +{ + [self.currentView setNeedsLayout]; +} + +- (void)forceReloadOfView +{ + if ([self.currentView class] == [UITableView class]) + [(UITableView *)self.currentView reloadData]; +} + +- (void)toggleOutlines +{ + UIWindow *mainWindow = [self mainWindow]; + self.viewOutlines = !self.viewOutlines; + + if (self.viewOutlines) + [self addOutlinesToFrameViewFromSubview:mainWindow]; + else + [self.frameView.rectsToOutline removeAllObjects]; + + [self.frameView setNeedsDisplay]; + + NSString *string = [NSString stringWithFormat:@"Showing view outlines is %@", (self.viewOutlines) ? @"on" : @"off"]; + if (self.showStatusBarOverlay) + [self showTemporaryStringInStatusBar:string]; + else + NSLog(@"DCIntrospect: %@", string); +} + +- (void)addOutlinesToFrameViewFromSubview:(UIView *)view +{ + for (UIView *subview in view.subviews) + { + if ([self shouldIgnoreView:subview]) + continue; + + CGRect rect = [subview.superview convertRect:subview.frame toView:frameView]; + + NSValue *rectValue = [NSValue valueWithCGRect:rect]; + [self.frameView.rectsToOutline addObject:rectValue]; + [self addOutlinesToFrameViewFromSubview:subview]; + } +} + +- (void)toggleNonOpaqueViews +{ + self.highlightNonOpaqueViews = !self.highlightNonOpaqueViews; + + UIWindow *mainWindow = [self mainWindow]; + [self setBackgroundColor:(self.highlightNonOpaqueViews) ? kDCIntrospectOpaqueColor : [UIColor clearColor] + ofNonOpaqueViewsInSubview:mainWindow]; + + NSString *string = [NSString stringWithFormat:@"Highlighting non-opaque views is %@", (self.highlightNonOpaqueViews) ? @"on" : @"off"]; + if (self.showStatusBarOverlay) + [self showTemporaryStringInStatusBar:string]; + else + NSLog(@"DCIntrospect: %@", string); +} + +- (void)setBackgroundColor:(UIColor *)color ofNonOpaqueViewsInSubview:(UIView *)view +{ + for (UIView *subview in view.subviews) + { + if ([self shouldIgnoreView:subview]) + continue; + + if (!subview.opaque) + subview.backgroundColor = color; + + [self setBackgroundColor:color ofNonOpaqueViewsInSubview:subview]; + } +} + +- (void)toggleRedrawFlashing +{ + self.flashOnRedraw = !self.flashOnRedraw; + NSString *string = [NSString stringWithFormat:@"Flashing on redraw is %@", (self.flashOnRedraw) ? @"on" : @"off"]; + if (self.showStatusBarOverlay) + [self showTemporaryStringInStatusBar:string]; + else + NSLog(@"DCIntrospect: %@", string); + + // flash all views to show what is working + [self callDrawRectOnViewsInSubview:[self mainWindow]]; +} + +- (void)callDrawRectOnViewsInSubview:(UIView *)subview +{ + for (UIView *view in subview.subviews) + { + if (![self shouldIgnoreView:view]) + { + [view setNeedsDisplay]; + [self callDrawRectOnViewsInSubview:view]; + } + } +} + +- (void)flashRect:(CGRect)rect inView:(UIView *)view +{ + if (self.flashOnRedraw) + { + CALayer *layer = [CALayer layer]; + layer.frame = rect; + layer.backgroundColor = kDCIntrospectFlashOnRedrawColor.CGColor; + [view.layer addSublayer:layer]; + [layer performSelector:@selector(removeFromSuperlayer) withObject:nil afterDelay:kDCIntrospectFlashOnRedrawFlashLength]; + } +} + +#pragma mark Description Methods + +- (NSString *)describeProperty:(NSString *)propertyName value:(id)value +{ + if ([propertyName isEqualToString:@"contentMode"]) + { + switch ([value intValue]) + { + case 0: return @"UIViewContentModeScaleToFill"; + case 1: return @"UIViewContentModeScaleAspectFit"; + case 2: return @"UIViewContentModeScaleAspectFill"; + case 3: return @"UIViewContentModeRedraw"; + case 4: return @"UIViewContentModeCenter"; + case 5: return @"UIViewContentModeTop"; + case 6: return @"UIViewContentModeBottom"; + case 7: return @"UIViewContentModeLeft"; + case 8: return @"UIViewContentModeRight"; + case 9: return @"UIViewContentModeTopLeft"; + case 10: return @"UIViewContentModeTopRight"; + case 11: return @"UIViewContentModeBottomLeft"; + case 12: return @"UIViewContentModeBottomRight"; + default: return nil; + } + } + else if ([propertyName isEqualToString:@"textAlignment"]) + { + switch ([value intValue]) + { + case 0: return @"UITextAlignmentLeft"; + case 1: return @"UITextAlignmentCenter"; + case 2: return @"UITextAlignmentRight"; + default: return nil; + } + } + else if ([propertyName isEqualToString:@"lineBreakMode"]) + { + switch ([value intValue]) + { + case 0: return @"UILineBreakModeWordWrap"; + case 1: return @"UILineBreakModeCharacterWrap"; + case 2: return @"UILineBreakModeClip"; + case 3: return @"UILineBreakModeHeadTruncation"; + case 4: return @"UILineBreakModeTailTruncation"; + case 5: return @"UILineBreakModeMiddleTruncation"; + default: return nil; + } + } + else if ([propertyName isEqualToString:@"activityIndicatorViewStyle"]) + { + switch ([value intValue]) + { + case 0: return @"UIActivityIndicatorViewStyleWhiteLarge"; + case 1: return @"UIActivityIndicatorViewStyleWhite"; + case 2: return @"UIActivityIndicatorViewStyleGray"; + default: return nil; + } + } + else if ([propertyName isEqualToString:@"returnKeyType"]) + { + switch ([value intValue]) + { + case 0: return @"UIReturnKeyDefault"; + case 1: return @"UIReturnKeyGo"; + case 2: return @"UIReturnKeyGoogle"; + case 3: return @"UIReturnKeyJoin"; + case 4: return @"UIReturnKeyNext"; + case 5: return @"UIReturnKeyRoute"; + case 6: return @"UIReturnKeySearch"; + case 7: return @"UIReturnKeySend"; + case 8: return @"UIReturnKeyYahoo"; + case 9: return @"UIReturnKeyDone"; + case 10: return @"UIReturnKeyEmergencyCall"; + default: return nil; + } + } + else if ([propertyName isEqualToString:@"keyboardAppearance"]) + { + switch ([value intValue]) + { + case 0: return @"UIKeyboardAppearanceDefault"; + case 1: return @"UIKeyboardAppearanceAlert"; + default: return nil; + } + } + else if ([propertyName isEqualToString:@"keyboardType"]) + { + switch ([value intValue]) + { + case 0: return @"UIKeyboardTypeDefault"; + case 1: return @"UIKeyboardTypeASCIICapable"; + case 2: return @"UIKeyboardTypeNumbersAndPunctuation"; + case 3: return @"UIKeyboardTypeURL"; + case 4: return @"UIKeyboardTypeNumberPad"; + case 5: return @"UIKeyboardTypePhonePad"; + case 6: return @"UIKeyboardTypeNamePhonePad"; + case 7: return @"UIKeyboardTypeEmailAddress"; + case 8: return @"UIKeyboardTypeDecimalPad"; + default: return nil; + } + } + else if ([propertyName isEqualToString:@"autocorrectionType"]) + { + switch ([value intValue]) + { + case 0: return @"UIKeyboardTypeDefault"; + case 1: return @"UITextAutocorrectionTypeDefault"; + case 2: return @"UITextAutocorrectionTypeNo"; + default: return nil; + } + } + else if ([propertyName isEqualToString:@"autocapitalizationType"]) + { + switch ([value intValue]) + { + case 0: return @"UITextAutocapitalizationTypeNone"; + case 1: return @"UITextAutocapitalizationTypeWords"; + case 2: return @"UITextAutocapitalizationTypeSentences"; + case 3: return @"UITextAutocapitalizationTypeAllCharacters"; + default: return nil; + } + } + else if ([propertyName isEqualToString:@"clearButtonMode"] || + [propertyName isEqualToString:@"leftViewMode"] || + [propertyName isEqualToString:@"rightViewMode"]) + { + switch ([value intValue]) + { + case 0: return @"UITextFieldViewModeNever"; + case 1: return @"UITextFieldViewModeWhileEditing"; + case 2: return @"UITextFieldViewModeUnlessEditing"; + case 3: return @"UITextFieldViewModeAlways"; + default: return nil; + } + } + else if ([propertyName isEqualToString:@"borderStyle"]) + { + switch ([value intValue]) + { + case 0: return @"UITextBorderStyleNone"; + case 1: return @"UITextBorderStyleLine"; + case 2: return @"UITextBorderStyleBezel"; + case 3: return @"UITextBorderStyleRoundedRect"; + default: return nil; + } + } + else if ([propertyName isEqualToString:@"progressViewStyle"]) + { + switch ([value intValue]) + { + case 0: return @"UIProgressViewStyleBar"; + case 1: return @"UIProgressViewStyleDefault"; + default: return nil; + } + } + else if ([propertyName isEqualToString:@"separatorStyle"]) + { + switch ([value intValue]) + { + case 0: return @"UITableViewCellSeparatorStyleNone"; + case 1: return @"UITableViewCellSeparatorStyleSingleLine"; + case 2: return @"UITableViewCellSeparatorStyleSingleLineEtched"; + default: return nil; + } + } + else if ([propertyName isEqualToString:@"selectionStyle"]) + { + switch ([value intValue]) + { + case 0: return @"UITableViewCellSelectionStyleNone"; + case 1: return @"UITableViewCellSelectionStyleBlue"; + case 2: return @"UITableViewCellSelectionStyleGray"; + default: return nil; + } + } + else if ([propertyName isEqualToString:@"editingStyle"]) + { + switch ([value intValue]) + { + case 0: return @"UITableViewCellEditingStyleNone"; + case 1: return @"UITableViewCellEditingStyleDelete"; + case 2: return @"UITableViewCellEditingStyleInsert"; + default: return nil; + } + } + else if ([propertyName isEqualToString:@"accessoryType"] || [propertyName isEqualToString:@"editingAccessoryType"]) + { + switch ([value intValue]) + { + case 0: return @"UITableViewCellAccessoryNone"; + case 1: return @"UITableViewCellAccessoryDisclosureIndicator"; + case 2: return @"UITableViewCellAccessoryDetailDisclosureButton"; + case 3: return @"UITableViewCellAccessoryCheckmark"; + default: return nil; + } + } + else if ([propertyName isEqualToString:@"style"]) + { + switch ([value intValue]) + { + case 0: return @"UITableViewStylePlain"; + case 1: return @"UITableViewStyleGrouped"; + default: return nil; + } + + } + else if ([propertyName isEqualToString:@"autoresizingMask"]) + { + UIViewAutoresizing mask = [value intValue]; + NSMutableString *string = [NSMutableString string]; + if (mask & UIViewAutoresizingFlexibleLeftMargin) + [string appendString:@"UIViewAutoresizingFlexibleLeftMargin"]; + if (mask & UIViewAutoresizingFlexibleRightMargin) + [string appendString:@" | UIViewAutoresizingFlexibleRightMargin"]; + if (mask & UIViewAutoresizingFlexibleTopMargin) + [string appendString:@" | UIViewAutoresizingFlexibleTopMargin"]; + if (mask & UIViewAutoresizingFlexibleBottomMargin) + [string appendString:@" | UIViewAutoresizingFlexibleBottomMargin"]; + if (mask & UIViewAutoresizingFlexibleWidth) + [string appendString:@" | UIViewAutoresizingFlexibleWidthMargin"]; + if (mask & UIViewAutoresizingFlexibleHeight) + [string appendString:@" | UIViewAutoresizingFlexibleHeightMargin"]; + + if ([string hasPrefix:@" | "]) + [string replaceCharactersInRange:NSMakeRange(0, 3) withString:@""]; + + return ([string length] > 0) ? string : @"UIViewAutoresizingNone"; + } + else if ([propertyName isEqualToString:@"accessibilityTraits"]) + { + UIAccessibilityTraits traits = [value intValue]; + NSMutableString *string = [NSMutableString string]; + if (traits & UIAccessibilityTraitButton) + [string appendString:@"UIAccessibilityTraitButton"]; + if (traits & UIAccessibilityTraitLink) + [string appendString:@" | UIAccessibilityTraitLink"]; + if (traits & UIAccessibilityTraitSearchField) + [string appendString:@" | UIAccessibilityTraitSearchField"]; + if (traits & UIAccessibilityTraitImage) + [string appendString:@" | UIAccessibilityTraitImage"]; + if (traits & UIAccessibilityTraitSelected) + [string appendString:@" | UIAccessibilityTraitSelected"]; + if (traits & UIAccessibilityTraitPlaysSound) + [string appendString:@" | UIAccessibilityTraitPlaysSound"]; + if (traits & UIAccessibilityTraitKeyboardKey) + [string appendString:@" | UIAccessibilityTraitKeyboardKey"]; + if (traits & UIAccessibilityTraitStaticText) + [string appendString:@" | UIAccessibilityTraitStaticText"]; + if (traits & UIAccessibilityTraitSummaryElement) + [string appendString:@" | UIAccessibilityTraitSummaryElement"]; + if (traits & UIAccessibilityTraitNotEnabled) + [string appendString:@" | UIAccessibilityTraitNotEnabled"]; + if (traits & UIAccessibilityTraitUpdatesFrequently) + [string appendString:@" | UIAccessibilityTraitUpdatesFrequently"]; + if (traits & UIAccessibilityTraitStartsMediaSession) + [string appendString:@" | UIAccessibilityTraitStartsMediaSession"]; + if (traits & UIAccessibilityTraitAdjustable) + [string appendFormat:@" | UIAccessibilityTraitAdjustable"]; + if ([string hasPrefix:@" | "]) + [string replaceCharactersInRange:NSMakeRange(0, 3) withString:@""]; + + return ([string length] > 0) ? string : @"UIAccessibilityTraitNone"; + } + + if ([value isKindOfClass:[NSValue class]]) + { + // print out the return for each value depending on type + NSString *type = [NSString stringWithUTF8String:[value objCType]]; + if ([type isEqualToString:@"c"]) + { + return ([value boolValue]) ? @"YES" : @"NO"; + } + else if ([type isEqualToString:@"{CGSize=ff}"]) + { + CGSize size = [value CGSizeValue]; + return CGSizeEqualToSize(size, CGSizeZero) ? @"CGSizeZero" : NSStringFromCGSize(size); + } + else if ([type isEqualToString:@"{UIEdgeInsets=ffff}"]) + { + UIEdgeInsets edgeInsets = [value UIEdgeInsetsValue]; + return UIEdgeInsetsEqualToEdgeInsets(edgeInsets, UIEdgeInsetsZero) ? @"UIEdgeInsetsZero" : NSStringFromUIEdgeInsets(edgeInsets); + } + } + else if ([value isKindOfClass:[UIColor class]]) + { + UIColor *color = (UIColor *)value; + return [self describeColor:color]; + } + else if ([value isKindOfClass:[UIFont class]]) + { + UIFont *font = (UIFont *)value; + return [NSString stringWithFormat:@"%.0fpx %@", font.pointSize, font.fontName]; + } + + return value ? [value description] : @"nil"; } -//////////////////// -// Helper Methods // -//////////////////// +- (NSString *)describeColor:(UIColor *)color +{ + if (!color) + return @"nil"; + + NSString *returnString = nil; + if (CGColorSpaceGetModel(CGColorGetColorSpace(color.CGColor)) == kCGColorSpaceModelRGB) + { + const CGFloat *components = CGColorGetComponents(color.CGColor); + returnString = [NSString stringWithFormat:@"R: %.0f G: %.0f B: %.0f A: %.2f", + components[0] * 256, + components[1] * 256, + components[2] * 256, + components[3]]; + } + else + { + returnString = [NSString stringWithFormat:@"%@ (incompatible color space)", color]; + } + return returnString; +} + +#pragma mark DCIntrospector Help + +- (void)toggleHelp +{ + UIWindow *mainWindow = [self mainWindow]; + self.showingHelp = !self.showingHelp; + + if (self.showingHelp) + { + self.statusBarOverlay.leftLabel.text = @"Help"; + self.statusBarOverlay.rightLabel.text = @"Any key to close"; + UIView *backingView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, mainWindow.frame.size.width, mainWindow.frame.size.height)] autorelease]; + backingView.tag = 1548; + backingView.alpha = 0; + backingView.backgroundColor = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.85f]; + [mainWindow addSubview:backingView]; + + UIWebView *webView = [[[UIWebView alloc] initWithFrame:backingView.frame] autorelease]; + webView.opaque = NO; + webView.backgroundColor = [UIColor clearColor]; + webView.delegate = self; + [backingView addSubview:webView]; + + NSMutableString *helpString = [NSMutableString stringWithString:@""]; + [helpString appendString:@"

DCIntrospect

"]; + [helpString appendString:@"

Created by Domestic Cat Software 2011.

"]; + [helpString appendString:@"

Twitter: @patr

"]; + [helpString appendString:@"

More info and full documentation: domesticcat.com.au/projects/introspect

"]; + [helpString appendString:@"

GitHub project: github.com/domesticcatsoftware/dcintrospect/

"]; + + [helpString appendString:@"

Key Bindings

"]; + [helpString appendString:@"

Edit DCIntrospectSettings.h to change key bindings.

"]; + + [helpString appendString:@"

General

"]; + + [helpString appendFormat:@"
Invoke Introspector
%@
", ([kDCIntrospectKeysInvoke isEqualToString:@" "]) ? @"spacebar" : kDCIntrospectKeysInvoke]; + [helpString appendFormat:@"
Toggle View Outlines
%@
", kDCIntrospectKeysToggleViewOutlines]; + [helpString appendFormat:@"
Toggle Highlighting Non-Opaque Views
%@
", kDCIntrospectKeysToggleNonOpaqueViews]; + [helpString appendFormat:@"
Toggle Help
%@
", kDCIntrospectKeysToggleHelp]; + [helpString appendFormat:@"
Toggle flash on drawRect: (see below)
%@
", kDCIntrospectKeysToggleFlashViewRedraws]; + [helpString appendFormat:@"
Toggle coordinates
%@
", kDCIntrospectKeysToggleShowCoordinates]; + [helpString appendString:@"
"]; + + [helpString appendString:@"

When a view is selected

"]; + [helpString appendFormat:@"
Log Properties
%@
", kDCIntrospectKeysLogProperties]; + [helpString appendFormat:@"
Log Accessibility Properties
%@
", kDCIntrospectKeysLogAccessibilityProperties]; + [helpString appendFormat:@"
Log Recursive Description for View
%@
", kDCIntrospectKeysLogViewRecursive]; + [helpString appendFormat:@"
Enter GDB
%@
", kDCIntrospectKeysEnterGDB]; + [helpString appendFormat:@"
Move up in view hierarchy
%@
", ([kDCIntrospectKeysMoveUpInViewHierarchy isEqualToString:@""]) ? @"page up" : kDCIntrospectKeysMoveUpInViewHierarchy]; + [helpString appendFormat:@"
Move back down in view hierarchy
%@
", ([kDCIntrospectKeysMoveBackInViewHierarchy isEqualToString:@""]) ? @"page down" : kDCIntrospectKeysMoveBackInViewHierarchy]; + [helpString appendString:@"
"]; + + [helpString appendFormat:@"
Nudge Left
\uE235 / %@
", kDCIntrospectKeysNudgeViewLeft]; + [helpString appendFormat:@"
Nudge Right
\uE234 / %@
", kDCIntrospectKeysNudgeViewRight]; + [helpString appendFormat:@"
Nudge Up
\uE232 / %@
", kDCIntrospectKeysNudgeViewUp]; + [helpString appendFormat:@"
Nudge Down
\uE233 / %@
", kDCIntrospectKeysNudgeViewDown]; + [helpString appendFormat:@"
Center in Superview
%@
", kDCIntrospectKeysCenterInSuperview]; + [helpString appendFormat:@"
Increase Width
alt + \uE234 / %@
", kDCIntrospectKeysIncreaseWidth]; + [helpString appendFormat:@"
Decrease Width
alt + \uE235 / %@
", kDCIntrospectKeysDecreaseWidth]; + [helpString appendFormat:@"
Increase Height
alt + \uE233 / %@
", kDCIntrospectKeysIncreaseHeight]; + [helpString appendFormat:@"
Decrease Height
alt + \uE232 / %@
", kDCIntrospectKeysDecreaseHeight]; + [helpString appendFormat:@"
Increase Alpha
%@
", kDCIntrospectKeysIncreaseViewAlpha]; + [helpString appendFormat:@"
Decrease Alpha
%@
", kDCIntrospectKeysDecreaseViewAlpha]; + [helpString appendFormat:@"
Log view code
%@
", kDCIntrospectKeysLogCodeForCurrentViewChanges]; + [helpString appendString:@"
"]; + + [helpString appendFormat:@"
Call setNeedsDisplay
%@
", kDCIntrospectKeysSetNeedsDisplay]; + [helpString appendFormat:@"
Call setNeedsLayout
%@
", kDCIntrospectKeysSetNeedsLayout]; + [helpString appendFormat:@"
Call reloadData (UITableView only)
%@
", kDCIntrospectKeysReloadData]; + [helpString appendString:@"
"]; + + [helpString appendFormat:@"

GDB

Push %@ (backtick) to jump into GDB. The currently selected view will be available as a variable named 'view'.

", kDCIntrospectKeysEnterGDB]; + + [helpString appendFormat:@"

Flash on drawRect: calls

To implement, call [[DCIntrospect sharedIntrospector] flashRect:inView:] inside the drawRect: method of any view you want to track.

When Flash on drawRect: is toggled on (binding: %@) the view will flash whenever drawRect: is called.

", kDCIntrospectKeysToggleFlashViewRedraws]; + + [helpString appendFormat:@"

Naming objects & logging code

By providing names for objects using setName:forObject:accessedWithSelf:, that name will be shown in the status bar instead of the class of the view.

This is also used when logging view code (binding: %@). Logging view code prints formatted code to the console for properties that have been changed.

For example, if you resize/move a view using the nudge keys, logging the view code will print view.frame = CGRectMake(50.0 ..etc); to the console. If a name is provided then view is replaced by the name.

", kDCIntrospectKeysLogCodeForCurrentViewChanges]; + + [helpString appendString:@"

License

DCIntrospect is made available under the MIT license.

"]; + + [helpString appendString:@"

Close Help

"]; + [helpString appendString:@"
"]; + + [UIView animateWithDuration:0.1 + animations:^{ + backingView.alpha = 1.0f; + } completion:^(BOOL finished) { + [webView loadHTMLString:helpString baseURL:nil]; + }]; + } + else + { + UIView *backingView = (UIView *)[mainWindow viewWithTag:1548]; + [UIView animateWithDuration:0.1 + animations:^{ + backingView.alpha = 0; + } completion:^(BOOL finished) { + [backingView removeFromSuperview]; + }]; + [self updateStatusBar]; + } +} + +- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType +{ + NSString *requestString = [[request URL] absoluteString]; + if ([requestString isEqualToString:@"about:blank"]) + return YES; + else if ([requestString isEqualToString:@"http://close/"]) + [self toggleHelp]; + else + [[UIApplication sharedApplication] openURL:[request URL]]; + + return NO; +} + +#pragma mark Experimental + +- (void)logPropertiesForCurrentView +{ + [self logPropertiesForObject:self.currentView]; +} + +- (void)logPropertiesForObject:(id)object +{ + Class objectClass = [object class]; + NSString *className = [NSString stringWithFormat:@"%@", objectClass]; + + NSMutableString *outputString = [NSMutableString stringWithFormat:@"\n\n** %@", className]; + + // list the class heirachy + Class superClass = [objectClass superclass]; + while (superClass) + { + [outputString appendFormat:@" : %@", superClass]; + superClass = [superClass superclass]; + } + [outputString appendString:@" ** \n"]; + + // dump properties of class and super classes, up to UIView + NSMutableString *propertyString = [NSMutableString string]; + + Class inspectClass = objectClass; + while (inspectClass) + { + NSMutableString *objectString = [NSMutableString string]; + [objectString appendFormat:@"\n ** %@ properties **\n", inspectClass]; + + if (inspectClass == UIView.class) + { + UIView *view = (UIView *)object; + // print out generic uiview properties + [objectString appendFormat:@" tag: %i\n", view.tag]; + [objectString appendFormat:@" frame: %@ | ", NSStringFromCGRect(view.frame)]; + [objectString appendFormat:@"bounds: %@ | ", NSStringFromCGRect(view.bounds)]; + [objectString appendFormat:@"center: %@\n", NSStringFromCGPoint(view.center)]; + [objectString appendFormat:@" transform: %@\n", NSStringFromCGAffineTransform(view.transform)]; + [objectString appendFormat:@" autoresizingMask: %@\n", [self describeProperty:@"autoresizingMask" value:[NSNumber numberWithInt:view.autoresizingMask]]]; + [objectString appendFormat:@" autoresizesSubviews: %@\n", (view.autoresizesSubviews) ? @"YES" : @"NO"]; + [objectString appendFormat:@" contentMode: %@ | ", [self describeProperty:@"contentMode" value:[NSNumber numberWithInt:view.contentMode]]]; + [objectString appendFormat:@"contentStretch: %@\n", NSStringFromCGRect(view.contentStretch)]; + [objectString appendFormat:@" backgroundColor: %@\n", [self describeColor:view.backgroundColor]]; + [objectString appendFormat:@" alpha: %.2f | ", view.alpha]; + [objectString appendFormat:@"opaque: %@ | ", (view.opaque) ? @"YES" : @"NO"]; + [objectString appendFormat:@"hidden: %@ | ", (view.hidden) ? @"YES" : @"NO"]; + [objectString appendFormat:@"clips to bounds: %@ | ", (view.clipsToBounds) ? @"YES" : @"NO"]; + [objectString appendFormat:@"clearsContextBeforeDrawing: %@\n", (view.clearsContextBeforeDrawing) ? @"YES" : @"NO"]; + [objectString appendFormat:@" userInteractionEnabled: %@ | ", (view.userInteractionEnabled) ? @"YES" : @"NO"]; + [objectString appendFormat:@"multipleTouchEnabled: %@\n", (view.multipleTouchEnabled) ? @"YES" : @"NO"]; + [objectString appendFormat:@" gestureRecognizers: %@\n", (view.gestureRecognizers) ? [view.gestureRecognizers description] : @"nil"]; + } + else + { + // Dump all properties of the class + unsigned int count; + objc_property_t *properties = class_copyPropertyList(inspectClass, &count); + size_t buf_size = 1024; + char *buffer = malloc(buf_size); + + for (unsigned int i = 0; i < count; ++i) + { + // get the property name and selector name + NSString *propertyName = [NSString stringWithCString:property_getName(properties[i]) encoding:NSUTF8StringEncoding]; + + SEL sel = NSSelectorFromString(propertyName); + if ([object respondsToSelector:sel]) + { + NSString *propertyDescription; + @try + { + // get the return object and type for the selector + NSString *returnType = [NSString stringWithUTF8String:[[object methodSignatureForSelector:sel] methodReturnType]]; + id returnObject = [object valueForKey:propertyName]; + if ([returnType isEqualToString:@"c"]) + returnObject = [NSNumber numberWithBool:[returnObject intValue] != 0]; + + propertyDescription = [self describeProperty:propertyName value:returnObject]; + } + @catch (NSException *exception) + { + // Non KVC compliant properties, see also +workaroundUITextInputTraitsPropertiesBug + propertyDescription = @"N/A"; + } + [objectString appendFormat:@" %@: %@\n", propertyName, propertyDescription]; + } + } + + free(properties); + free(buffer); + } + + [propertyString insertString:objectString atIndex:0]; + + if (inspectClass == UIView.class) + { + break; + } + + inspectClass = [inspectClass superclass]; + } + + [outputString appendString:propertyString]; + + // list targets if there are any + if ([object respondsToSelector:@selector(allTargets)]) + { + [outputString appendString:@"\n ** Targets & Actions **\n"]; + UIControl *control = (UIControl *)object; + UIControlEvents controlEvents = [control allControlEvents]; + NSSet *allTargets = [control allTargets]; + [allTargets enumerateObjectsUsingBlock:^(id target, BOOL *stop) + { + NSArray *actions = [control actionsForTarget:target forControlEvent:controlEvents]; + [actions enumerateObjectsUsingBlock:^(id action, NSUInteger idx, BOOL *stop2) + { + [outputString appendFormat:@" target: %@ action: %@\n", target, action]; + }]; + }]; + } + + [outputString appendString:@"\n"]; + NSLog(@"DCIntrospect: %@", outputString); +} + +- (void)logAccessabilityPropertiesForObject:(id)object +{ + Class objectClass = [object class]; + NSString *className = [NSString stringWithFormat:@"%@", objectClass]; + NSMutableString *outputString = [NSMutableString string]; + + // warn about accessibility inspector if the element count is zero + NSUInteger count = [object accessibilityElementCount]; + if (count == 0) + [outputString appendString:@"\n\n** Warning: Logging accessibility properties requires Accessibility Inspector: Settings.app -> General -> Accessibility\n"]; + + [outputString appendFormat:@"** %@ Accessibility Properties **\n", className]; + [outputString appendFormat:@" label: %@\n", [object accessibilityLabel]]; + [outputString appendFormat:@" hint: %@\n", [object accessibilityHint]]; + [outputString appendFormat:@" traits: %@\n", [self describeProperty:@"accessibilityTraits" value:[NSNumber numberWithUnsignedLongLong:[object accessibilityTraits]]]]; + [outputString appendFormat:@" value: %@\n", [object accessibilityValue]]; + [outputString appendFormat:@" frame: %@\n", NSStringFromCGRect([object accessibilityFrame])]; + [outputString appendString:@"\n"]; + + NSLog(@"DCIntrospect: %@", outputString); +} + +- (NSArray *)subclassesOfClass:(Class)parentClass +{ + // thanks to Matt Gallagher: + int numClasses = objc_getClassList(NULL, 0); + Class *classes = NULL; + + classes = malloc(sizeof(Class) * numClasses); + numClasses = objc_getClassList(classes, numClasses); + + NSMutableArray *result = [NSMutableArray array]; + for (NSInteger i = 0; i < numClasses; i++) + { + Class superClass = classes[i]; + do + { + superClass = class_getSuperclass(superClass); + } while(superClass && superClass != parentClass); + + if (superClass == nil) + { + continue; + } + + [result addObject:classes[i]]; + } + + free(classes); + + return result; +} + +#pragma mark Helper Methods - (UIWindow *)mainWindow { NSArray *windows = [[UIApplication sharedApplication] windows]; if (windows.count == 0) return nil; - + return [windows objectAtIndex:0]; } -- (NSMutableArray *)findViewsAtPoint:(CGPoint)touchPoint inView:(UIView *)view addToArray:(NSMutableArray *)views +- (NSMutableArray *)viewsAtPoint:(CGPoint)touchPoint inView:(UIView *)view { + NSMutableArray *views = [[NSMutableArray alloc] init]; for (UIView *subview in view.subviews) { - if (subview == self.frameView) + CGRect rect = subview.frame; + if ([self shouldIgnoreView:subview]) continue; - - if (CGRectContainsPoint(subview.frame, touchPoint)) + + if (CGRectContainsPoint(rect, touchPoint)) { [views addObject:subview]; - views = [self findViewsAtPoint:[subview.superview convertPoint:touchPoint toView:subview] inView:subview addToArray:views]; + + // convert the point to it's superview + CGPoint newTouchPoint = touchPoint; + newTouchPoint = [view convertPoint:newTouchPoint toView:subview]; + [views addObjectsFromArray:[self viewsAtPoint:newTouchPoint inView:subview]]; } } + + return [views autorelease]; +} + +- (void)fadeView:(UIView *)view toAlpha:(CGFloat)alpha +{ + [UIView animateWithDuration:0.1 + delay:0.0 + options:UIViewAnimationOptionAllowUserInteraction + animations:^{ + view.alpha = alpha; + } + completion:nil]; +} - return views; +- (BOOL)view:(UIView *)view containsSubview:(UIView *)subview +{ + for (UIView *aView in view.subviews) + { + if (aView == subview) + return YES; + + if ([self view:aView containsSubview:subview]) + return YES; + } + + return NO; } +- (BOOL)shouldIgnoreView:(UIView *)view +{ + if (view == self.frameView || view == self.inputTextView) + return YES; + return NO; +} @end diff --git a/DCIntrospect/DCIntrospectSettings.h b/DCIntrospect/DCIntrospectSettings.h new file mode 100644 index 0000000..cbd1985 --- /dev/null +++ b/DCIntrospect/DCIntrospectSettings.h @@ -0,0 +1,56 @@ +////////////// +// Settings // +////////////// + +#define kDCIntrospectFlashOnRedrawColor [UIColor colorWithRed:1.0f green:0.0f blue:0.0f alpha:0.4f] // UIColor +#define kDCIntrospectFlashOnRedrawFlashLength 0.03f // NSTimeInterval +#define kDCIntrospectOpaqueColor [UIColor redColor] // UIColor +#define kDCIntrospectTemporaryDisableDuration 10. // Seconds + +////////////////// +// Key Bindings // +////////////////// + +// '' is equivalent to page up (copy and paste this character to use) +// '' is equivalent to page down (copy and paste this character to use) + +// Global // +#define kDCIntrospectKeysInvoke @" " // starts introspector +#define kDCIntrospectKeysToggleViewOutlines @"o" // shows outlines for all views +#define kDCIntrospectKeysToggleNonOpaqueViews @"O" // changes all non-opaque view background colours to red (destructive) +#define kDCIntrospectKeysToggleHelp @"?" // shows help +#define kDCIntrospectKeysToggleFlashViewRedraws @"f" // toggle flashing on redraw for all views that implement [[DCIntrospect sharedIntrospector] flashRect:inView:] in drawRect: +#define kDCIntrospectKeysToggleShowCoordinates @"c" // toggles the coordinates display +#define kDCIntrospectKeysEnterBlockMode @"b" // enters block action mode + +// When introspector is invoked and a view is selected // +#define kDCIntrospectKeysNudgeViewLeft @"4" // nudges the selected view in given direction +#define kDCIntrospectKeysNudgeViewRight @"6" // +#define kDCIntrospectKeysNudgeViewUp @"8" // +#define kDCIntrospectKeysNudgeViewDown @"2" // +#define kDCIntrospectKeysCenterInSuperview @"5" // centers the selected view in it's superview +#define kDCIntrospectKeysIncreaseWidth @"9" // increases/decreases the width/height of selected view +#define kDCIntrospectKeysDecreaseWidth @"7" // +#define kDCIntrospectKeysIncreaseHeight @"3" // +#define kDCIntrospectKeysDecreaseHeight @"1" // +#define kDCIntrospectKeysLogCodeForCurrentViewChanges @"0" // prints code to the console of the changes to the current view. If the view has not been changed nothing will be printed. For example, if you nudge a view or change it's rect with the nudge keys, this will log '<#view#>.frame = CGRectMake(50.0, ..etc);'. Or if you set it's name using setName:forObject:accessedWithSelf: it will use the name provided, for example 'myView.frame = CGRectMake(...);'. Setting accessedWithSelf to YES would output 'self.myView.frame = CGRectMake(...);'. + +#define kDCIntrospectKeysIncreaseViewAlpha @"+" // increases/decreases the selected views alpha value +#define kDCIntrospectKeysDecreaseViewAlpha @"-" // + +#define kDCIntrospectKeysSetNeedsDisplay @"d" // calls setNeedsDisplay on selected view +#define kDCIntrospectKeysSetNeedsLayout @"l" // calls setNeedsLayout on selected view +#define kDCIntrospectKeysReloadData @"r" // calls reloadData on selected view if it's a UITableView +#define kDCIntrospectKeysLogProperties @"p" // logs all properties of the selected view +#define kDCIntrospectKeysLogAccessibilityProperties @"a" // logs accessibility info (useful for automated view tests - thanks to @samsoffes for the idea) +#define kDCIntrospectKeysLogViewRecursive @"v" // calls private method recursiveDescription which logs selected view heirachy + +#define kDCIntrospectKeysMoveUpInViewHierarchy @"y" // changes the selected view to it's superview +#define kDCIntrospectKeysMoveBackInViewHierarchy @"t" // changes the selected view back to the previous view selected (after using the above command) + +#define kDCIntrospectKeysMoveDownToFirstSubview @"h" +#define kDCIntrospectKeysMoveToNextSiblingView @"j" +#define kDCIntrospectKeysMoveToPrevSiblingView @"g" + +#define kDCIntrospectKeysEnterGDB @"`" // enters GDB +#define kDCIntrospectKeysDisableForPeriod @"~" // disables DCIntrospect for a given period (see kDCIntrospectTemporaryDisableDuration) diff --git a/DCIntrospect/DCStatusBarOverlay.h b/DCIntrospect/DCStatusBarOverlay.h new file mode 100644 index 0000000..cd30a44 --- /dev/null +++ b/DCIntrospect/DCStatusBarOverlay.h @@ -0,0 +1,34 @@ +// +// DCStatusBarOverlay.h +// +// Copyright 2011 Domestic Cat. All rights reserved. +// + +// Based mainly on @myellow's excellent MTStatusBarOverlay: https://github.com/myell0w/MTStatusBarOverlay + + +#import "DCIntrospectSettings.h" + +#define kDCIntrospectNotificationStatusBarTapped @"kDCIntrospectNotificationStatusBarTapped" + +@interface DCStatusBarOverlay : UIWindow +{ +} + +@property (nonatomic, retain) UILabel *leftLabel; +@property (nonatomic, retain) UILabel *rightLabel; + +/////////// +// Setup // +/////////// + +- (id)init; +- (void)updateBarFrame; + +///////////// +// Actions // +///////////// + +- (void)tapped; + +@end diff --git a/DCIntrospect/DCStatusBarOverlay.m b/DCIntrospect/DCStatusBarOverlay.m new file mode 100644 index 0000000..7be771e --- /dev/null +++ b/DCIntrospect/DCStatusBarOverlay.m @@ -0,0 +1,107 @@ +// +// DCStatusBarOverlay.m +// +// Copyright 2011 Domestic Cat. All rights reserved. +// + +#import "DCStatusBarOverlay.h" + +@implementation DCStatusBarOverlay +@synthesize leftLabel, rightLabel; + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; + + [leftLabel release]; + [rightLabel release]; + + [super dealloc]; +} + +#pragma mark Setup + +- (id)init +{ + if ((self = [super initWithFrame:CGRectZero])) + { + self.windowLevel = UIWindowLevelStatusBar + 1.0f; + UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; + CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width; + CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height; + const CGFloat bar_size = 20; + if (UIInterfaceOrientationIsLandscape(orientation)) + self.frame = CGRectMake(0, 0, screenHeight, bar_size); + else + self.frame = CGRectMake(0, 0, screenWidth, bar_size); + self.backgroundColor = [UIColor blackColor]; + + UIImageView *backgroundImageView = [[UIImageView alloc] initWithFrame:self.frame]; + backgroundImageView.image = [[UIImage imageNamed:@"statusBarBackground.png"] stretchableImageWithLeftCapWidth:2.0f topCapHeight:0.0f]; + [self addSubview:backgroundImageView]; + [backgroundImageView release]; + + self.leftLabel = [[[UILabel alloc] initWithFrame:CGRectOffset(self.frame, 2.0f, 0.0f)] autorelease]; + self.leftLabel.backgroundColor = [UIColor clearColor]; + self.leftLabel.textAlignment = UITextAlignmentLeft; + self.leftLabel.font = [UIFont boldSystemFontOfSize:12.0f]; + self.leftLabel.textColor = [UIColor colorWithWhite:0.97f alpha:1.0f]; + self.leftLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth; + [self addSubview:self.leftLabel]; + + self.rightLabel = [[[UILabel alloc] initWithFrame:CGRectOffset(self.frame, -2.0f, 0.0f)] autorelease]; + self.rightLabel.backgroundColor = [UIColor clearColor]; + self.rightLabel.font = [UIFont boldSystemFontOfSize:12.0f]; + self.rightLabel.textAlignment = UITextAlignmentRight; + self.rightLabel.textColor = [UIColor colorWithWhite:0.9f alpha:1.0f]; + self.rightLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth; + [self addSubview:self.rightLabel]; + + UITapGestureRecognizer *gestureRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped)] autorelease]; + [self addGestureRecognizer:gestureRecognizer]; + + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateBarFrame) name:UIDeviceOrientationDidChangeNotification object:nil]; + } + + return self; +} + +- (void)updateBarFrame +{ + // current interface orientation + UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; + CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width; + CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height; + + CGFloat pi = (CGFloat)M_PI; + if (orientation == UIDeviceOrientationPortrait) + { + self.transform = CGAffineTransformIdentity; + self.frame = CGRectMake(0, 0, screenWidth, self.frame.size.height); + } + else if (orientation == UIDeviceOrientationLandscapeLeft) + { + self.transform = CGAffineTransformMakeRotation(pi * (90) / 180.0f); + self.frame = CGRectMake(screenWidth - self.frame.size.width, 0, self.frame.size.width, screenHeight); + } + else if (orientation == UIDeviceOrientationLandscapeRight) + { + self.transform = CGAffineTransformMakeRotation(pi * (-90) / 180.0f); + self.frame = CGRectMake(0, 0, self.frame.size.width, screenHeight); + } + else if (orientation == UIDeviceOrientationPortraitUpsideDown) + { + self.transform = CGAffineTransformMakeRotation(pi); + self.frame = CGRectMake(0, screenHeight - self.frame.size.height, screenWidth, self.frame.size.height); + } +} + +#pragma mark Actions + +- (void)tapped +{ + [[NSNotificationCenter defaultCenter] postNotificationName:kDCIntrospectNotificationStatusBarTapped object:nil]; +} + +@end diff --git a/DCIntrospectDemo/.DS_Store b/DCIntrospectDemo/.DS_Store deleted file mode 100644 index 74dc7d5..0000000 Binary files a/DCIntrospectDemo/.DS_Store and /dev/null differ diff --git a/DCIntrospectDemo/DCIntrospectDemo.xcodeproj/project.pbxproj b/DCIntrospectDemo/DCIntrospectDemo.xcodeproj/project.pbxproj index 6037a74..771f774 100644 --- a/DCIntrospectDemo/DCIntrospectDemo.xcodeproj/project.pbxproj +++ b/DCIntrospectDemo/DCIntrospectDemo.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 625780B0138A052F004DA77B /* circle.png in Resources */ = {isa = PBXBuildFile; fileRef = 625780AF138A052F004DA77B /* circle.png */; }; + 625780B2138A0EBD004DA77B /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625780B1138A0EBC004DA77B /* QuartzCore.framework */; }; AB0D01D5136A778000962171 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB0D01D4136A778000962171 /* UIKit.framework */; }; AB0D01D7136A778000962171 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB0D01D6136A778000962171 /* Foundation.framework */; }; AB0D01D9136A778000962171 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB0D01D8136A778000962171 /* CoreGraphics.framework */; }; @@ -15,13 +17,15 @@ AB0D01E5136A778000962171 /* DCIntrospectDemoAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AB0D01E4136A778000962171 /* DCIntrospectDemoAppDelegate.m */; }; AB0D01E8136A778000962171 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB0D01E6136A778000962171 /* MainWindow.xib */; }; AB0D01EB136A778000962171 /* DCIntrospectDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AB0D01EA136A778000962171 /* DCIntrospectDemoViewController.m */; }; - AB0D01EE136A778000962171 /* DCIntrospectDemoViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB0D01EC136A778000962171 /* DCIntrospectDemoViewController.xib */; }; - AB0D0201136A841400962171 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB0D0200136A841400962171 /* QuartzCore.framework */; }; AB0D0214136A9E8D00962171 /* DCIntrospect.m in Sources */ = {isa = PBXBuildFile; fileRef = AB0D0213136A9E8D00962171 /* DCIntrospect.m */; }; AB0D021F136A9FE000962171 /* DCFrameView.m in Sources */ = {isa = PBXBuildFile; fileRef = AB0D021E136A9FE000962171 /* DCFrameView.m */; }; + ABDA505A136E0FDD00339835 /* DCStatusBarOverlay.m in Sources */ = {isa = PBXBuildFile; fileRef = ABDA5059136E0FDD00339835 /* DCStatusBarOverlay.m */; }; + ABDA50A0136FDD9400339835 /* DCCrossHairView.m in Sources */ = {isa = PBXBuildFile; fileRef = ABDA509F136FDD9300339835 /* DCCrossHairView.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 625780AF138A052F004DA77B /* circle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = circle.png; sourceTree = ""; }; + 625780B1138A0EBC004DA77B /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; AB0D01D0136A778000962171 /* DCIntrospectDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DCIntrospectDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; AB0D01D4136A778000962171 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; AB0D01D6136A778000962171 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -35,12 +39,15 @@ AB0D01E7136A778000962171 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; AB0D01E9136A778000962171 /* DCIntrospectDemoViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DCIntrospectDemoViewController.h; sourceTree = ""; }; AB0D01EA136A778000962171 /* DCIntrospectDemoViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DCIntrospectDemoViewController.m; sourceTree = ""; }; - AB0D01ED136A778000962171 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/DCIntrospectDemoViewController.xib; sourceTree = ""; }; - AB0D0200136A841400962171 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; AB0D0212136A9E8D00962171 /* DCIntrospect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DCIntrospect.h; path = ../../DCIntrospect/DCIntrospect.h; sourceTree = ""; }; AB0D0213136A9E8D00962171 /* DCIntrospect.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DCIntrospect.m; path = ../../DCIntrospect/DCIntrospect.m; sourceTree = ""; }; AB0D021D136A9FE000962171 /* DCFrameView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DCFrameView.h; path = ../../DCIntrospect/DCFrameView.h; sourceTree = ""; }; AB0D021E136A9FE000962171 /* DCFrameView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DCFrameView.m; path = ../../DCIntrospect/DCFrameView.m; sourceTree = ""; }; + ABDA5058136E0FDD00339835 /* DCStatusBarOverlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DCStatusBarOverlay.h; path = ../../DCIntrospect/DCStatusBarOverlay.h; sourceTree = ""; }; + ABDA5059136E0FDD00339835 /* DCStatusBarOverlay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DCStatusBarOverlay.m; path = ../../DCIntrospect/DCStatusBarOverlay.m; sourceTree = ""; }; + ABDA509E136FDD9300339835 /* DCCrossHairView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DCCrossHairView.h; path = ../../DCIntrospect/DCCrossHairView.h; sourceTree = ""; }; + ABDA509F136FDD9300339835 /* DCCrossHairView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DCCrossHairView.m; path = ../../DCIntrospect/DCCrossHairView.m; sourceTree = ""; }; + ABDA51091370E79100339835 /* DCIntrospectSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DCIntrospectSettings.h; path = ../../DCIntrospect/DCIntrospectSettings.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -48,7 +55,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - AB0D0201136A841400962171 /* QuartzCore.framework in Frameworks */, + 625780B2138A0EBD004DA77B /* QuartzCore.framework in Frameworks */, AB0D01D5136A778000962171 /* UIKit.framework in Frameworks */, AB0D01D7136A778000962171 /* Foundation.framework in Frameworks */, AB0D01D9136A778000962171 /* CoreGraphics.framework in Frameworks */, @@ -78,7 +85,7 @@ AB0D01D3136A778000962171 /* Frameworks */ = { isa = PBXGroup; children = ( - AB0D0200136A841400962171 /* QuartzCore.framework */, + 625780B1138A0EBC004DA77B /* QuartzCore.framework */, AB0D01D4136A778000962171 /* UIKit.framework */, AB0D01D6136A778000962171 /* Foundation.framework */, AB0D01D8136A778000962171 /* CoreGraphics.framework */, @@ -93,9 +100,9 @@ AB0D01E3136A778000962171 /* DCIntrospectDemoAppDelegate.h */, AB0D01E4136A778000962171 /* DCIntrospectDemoAppDelegate.m */, AB0D01E6136A778000962171 /* MainWindow.xib */, + 625780AF138A052F004DA77B /* circle.png */, AB0D01E9136A778000962171 /* DCIntrospectDemoViewController.h */, AB0D01EA136A778000962171 /* DCIntrospectDemoViewController.m */, - AB0D01EC136A778000962171 /* DCIntrospectDemoViewController.xib */, AB0D01DB136A778000962171 /* Supporting Files */, ); path = DCIntrospectDemo; @@ -115,10 +122,15 @@ AB0D01F7136A79A800962171 /* DCIntrospect */ = { isa = PBXGroup; children = ( + ABDA51091370E79100339835 /* DCIntrospectSettings.h */, AB0D0212136A9E8D00962171 /* DCIntrospect.h */, AB0D0213136A9E8D00962171 /* DCIntrospect.m */, + ABDA5058136E0FDD00339835 /* DCStatusBarOverlay.h */, + ABDA5059136E0FDD00339835 /* DCStatusBarOverlay.m */, AB0D021D136A9FE000962171 /* DCFrameView.h */, AB0D021E136A9FE000962171 /* DCFrameView.m */, + ABDA509E136FDD9300339835 /* DCCrossHairView.h */, + ABDA509F136FDD9300339835 /* DCCrossHairView.m */, ); name = DCIntrospect; sourceTree = ""; @@ -148,6 +160,9 @@ /* Begin PBXProject section */ AB0D01C7136A778000962171 /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0410; + }; buildConfigurationList = AB0D01CA136A778000962171 /* Build configuration list for PBXProject "DCIntrospectDemo" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; @@ -172,7 +187,7 @@ files = ( AB0D01DF136A778000962171 /* InfoPlist.strings in Resources */, AB0D01E8136A778000962171 /* MainWindow.xib in Resources */, - AB0D01EE136A778000962171 /* DCIntrospectDemoViewController.xib in Resources */, + 625780B0138A052F004DA77B /* circle.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -188,6 +203,8 @@ AB0D01EB136A778000962171 /* DCIntrospectDemoViewController.m in Sources */, AB0D0214136A9E8D00962171 /* DCIntrospect.m in Sources */, AB0D021F136A9FE000962171 /* DCFrameView.m in Sources */, + ABDA505A136E0FDD00339835 /* DCStatusBarOverlay.m in Sources */, + ABDA50A0136FDD9400339835 /* DCCrossHairView.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -210,14 +227,6 @@ name = MainWindow.xib; sourceTree = ""; }; - AB0D01EC136A778000962171 /* DCIntrospectDemoViewController.xib */ = { - isa = PBXVariantGroup; - children = ( - AB0D01ED136A778000962171 /* en */, - ); - name = DCIntrospectDemoViewController.xib; - sourceTree = ""; - }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -231,10 +240,14 @@ GCC_PREPROCESSOR_DEFINITIONS = DEBUG; GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_VERSION = com.apple.compilers.llvmgcc42; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 4.3; + OTHER_CFLAGS = ""; + RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = 1; }; name = Debug; }; @@ -245,11 +258,14 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_VERSION = com.apple.compilers.llvmgcc42; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 4.3; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = 1; }; name = Release; }; @@ -261,6 +277,8 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "DCIntrospectDemo/DCIntrospectDemo-Prefix.pch"; + GCC_WARN_SHADOW = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; INFOPLIST_FILE = "DCIntrospectDemo/DCIntrospectDemo-Info.plist"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; @@ -274,6 +292,8 @@ COPY_PHASE_STRIP = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "DCIntrospectDemo/DCIntrospectDemo-Prefix.pch"; + GCC_WARN_SHADOW = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; INFOPLIST_FILE = "DCIntrospectDemo/DCIntrospectDemo-Info.plist"; PRODUCT_NAME = "$(TARGET_NAME)"; VALIDATE_PRODUCT = YES; @@ -300,6 +320,7 @@ AB0D01F3136A778000962171 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/DCIntrospectDemo/DCIntrospectDemo.xcodeproj/project.xcworkspace/xcuserdata/domesticcat.xcuserdatad/UserInterfaceState.xcuserstate b/DCIntrospectDemo/DCIntrospectDemo.xcodeproj/project.xcworkspace/xcuserdata/domesticcat.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index b583a93..0000000 --- a/DCIntrospectDemo/DCIntrospectDemo.xcodeproj/project.xcworkspace/xcuserdata/domesticcat.xcuserdatad/UserInterfaceState.xcuserstate +++ /dev/null @@ -1,7280 +0,0 @@ - - - - - $archiver - NSKeyedArchiver - $objects - - $null - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 2 - - - CF$UID - 3 - - - CF$UID - 4 - - - NS.objects - - - CF$UID - 5 - - - CF$UID - 187 - - - CF$UID - 367 - - - - 3C6797AE-3EFF-4736-8FA8-3D6F81AE8EFA - 15FF3AFA-ACC9-4BE2-926B-2189B4E337E7 - IDEWorkspaceDocument - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 6 - - - CF$UID - 7 - - - CF$UID - 8 - - - CF$UID - 9 - - - CF$UID - 10 - - - CF$UID - 11 - - - NS.objects - - - CF$UID - 2 - - - CF$UID - 12 - - - CF$UID - 14 - - - CF$UID - 11 - - - CF$UID - 15 - - - CF$UID - 16 - - - - IDEWorkspaceWindowControllerUniqueIdentifier - IDEOrderedWorkspaceTabControllers - IDEWindowToolbarIsVisible - IDEActiveWorkspaceTabController - IDEWindowFrame - IDEWorkspaceTabController_9575D895-DABE-4C96-904E-CFE2C1A524E8 - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 11 - - - - - $classes - - NSArray - NSObject - - $classname - NSArray - - - {{306, 400}, {600, 624}} - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 17 - - - CF$UID - 18 - - - CF$UID - 19 - - - CF$UID - 20 - - - CF$UID - 21 - - - CF$UID - 22 - - - CF$UID - 23 - - - CF$UID - 24 - - - NS.objects - - - CF$UID - 25 - - - CF$UID - 14 - - - CF$UID - 26 - - - CF$UID - 27 - - - CF$UID - 40 - - - CF$UID - 64 - - - CF$UID - 14 - - - CF$UID - 73 - - - - IDETabLabel - IDEShowNavigator - AssistantEditorsLayout - IDEWorkspaceTabControllerUtilityAreaSplitView - IDENavigatorArea - IDEWorkspaceTabControllerDesignAreaSplitView - IDEShowUtilities - IDEEditorArea - DCIntrospectDemoViewController.xib - 0 - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 28 - - - NS.objects - - - CF$UID - 29 - - - - DVTSplitViewItems - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 30 - - - CF$UID - 36 - - - - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 33 - - - CF$UID - 34 - - - - DVTIdentifier - DVTViewMagnitude - - 389 - - $classes - - NSDictionary - NSObject - - $classname - NSDictionary - - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 33 - - - CF$UID - 37 - - - - 211 - - $classes - - NSMutableArray - NSArray - NSObject - - $classname - NSMutableArray - - - $classes - - NSMutableDictionary - NSDictionary - NSObject - - $classname - NSMutableDictionary - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 41 - - - CF$UID - 42 - - - NS.objects - - - CF$UID - 42 - - - CF$UID - 43 - - - - SelectedNavigator - Xcode.IDEKit.Navigator.Structure - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 44 - - - CF$UID - 45 - - - CF$UID - 46 - - - CF$UID - 47 - - - CF$UID - 48 - - - CF$UID - 49 - - - CF$UID - 50 - - - NS.objects - - - CF$UID - 51 - - - CF$UID - 14 - - - CF$UID - 52 - - - CF$UID - 14 - - - CF$UID - 14 - - - CF$UID - 54 - - - CF$UID - 59 - - - - IDEVisibleRect - IDEUnsavedDocumentFilteringEnabled - IDENavigatorExpandedItemsBeforeFilteringSet - IDERecentDocumentFilteringEnabled - IDESCMStatusFilteringEnabled - IDESelectedObjects - IDEExpandedItemsSet - {{0, 0}, {0, 0}} - - $class - - CF$UID - 53 - - NS.objects - - - - $classes - - NSSet - NSObject - - $classname - NSSet - - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 55 - - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 56 - - - CF$UID - 57 - - - CF$UID - 58 - - - - DCIntrospectDemo - DCIntrospectDemo - DCIntrospectDemoViewController.xib - - $class - - CF$UID - 53 - - NS.objects - - - CF$UID - 60 - - - CF$UID - 62 - - - CF$UID - 63 - - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 56 - - - CF$UID - 57 - - - CF$UID - 61 - - - - DCIntrospect - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 56 - - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 56 - - - CF$UID - 57 - - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 28 - - - NS.objects - - - CF$UID - 65 - - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 66 - - - CF$UID - 68 - - - CF$UID - 70 - - - - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 21 - - - CF$UID - 67 - - - - 260 - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 24 - - - CF$UID - 69 - - - - 1582 - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 71 - - - CF$UID - 72 - - - - IDEUtilitiesArea - 260 - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 74 - - - CF$UID - 75 - - - CF$UID - 76 - - - CF$UID - 77 - - - CF$UID - 78 - - - CF$UID - 79 - - - CF$UID - 80 - - - CF$UID - 81 - - - NS.objects - - - CF$UID - 82 - - - CF$UID - 102 - - - CF$UID - 150 - - - CF$UID - 177 - - - CF$UID - 26 - - - CF$UID - 178 - - - CF$UID - 186 - - - CF$UID - 14 - - - - layoutTree - IDEEditorMode_Standard - IDEEDitorArea_DebugArea - IDEShowEditor - EditorMode - DebuggerSplitView - DefaultPersistentRepresentations - ShowDebuggerArea - - $class - - CF$UID - 101 - - geniusEditorContextNode - - CF$UID - 0 - - primaryEditorContextNode - - CF$UID - 83 - - rootLayoutTreeNode - - CF$UID - 98 - - - - $class - - CF$UID - 100 - - children - - CF$UID - 0 - - contentType - 1 - documentArchivableRepresentation - - CF$UID - 84 - - orientation - 0 - parent - - CF$UID - 98 - - - - $class - - CF$UID - 97 - - DocumentLocation - - CF$UID - 93 - - DomainIdentifier - - CF$UID - 85 - - IdentifierPath - - CF$UID - 86 - - IndexOfDocumentIdentifier - - CF$UID - 92 - - - Xcode.IDENavigableItemDomain.WorkspaceStructure - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 87 - - - CF$UID - 89 - - - CF$UID - 90 - - - - - $class - - CF$UID - 88 - - Identifier - - CF$UID - 58 - - - - $classes - - IDEArchivableStringIndexPair - NSObject - - $classname - IDEArchivableStringIndexPair - - - $class - - CF$UID - 88 - - Identifier - - CF$UID - 57 - - - - $class - - CF$UID - 88 - - Identifier - - CF$UID - 91 - - - DCIntrospectDemo - 9223372036854775807 - - $class - - CF$UID - 96 - - documentURL - - CF$UID - 94 - - timestamp - - CF$UID - 0 - - - - $class - - CF$UID - 95 - - NS.string - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospectDemo/DCIntrospectDemo/en.lproj/DCIntrospectDemoViewController.xib - - - $classes - - NSMutableString - NSString - NSObject - - $classname - NSMutableString - - - $classes - - DVTDocumentLocation - NSObject - - $classname - DVTDocumentLocation - - - $classes - - IDENavigableItemArchivableRepresentation - NSObject - - $classname - IDENavigableItemArchivableRepresentation - - - $class - - CF$UID - 100 - - children - - CF$UID - 99 - - contentType - 0 - documentArchivableRepresentation - - CF$UID - 0 - - orientation - 0 - parent - - CF$UID - 0 - - - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 83 - - - - - $classes - - IDEWorkspaceTabControllerLayoutTreeNode - NSObject - - $classname - IDEWorkspaceTabControllerLayoutTreeNode - - - $classes - - IDEWorkspaceTabControllerLayoutTree - NSObject - - $classname - IDEWorkspaceTabControllerLayoutTree - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 103 - - - NS.objects - - - CF$UID - 104 - - - - EditorLayout_PersistentRepresentation - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 105 - - - NS.objects - - - CF$UID - 106 - - - - Main - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 107 - - - CF$UID - 108 - - - CF$UID - 109 - - - NS.objects - - - CF$UID - 110 - - - CF$UID - 26 - - - CF$UID - 148 - - - - EditorLayout_StateSavingStateDictionaries - EditorLayout_Selected - EditorLayout_Geometry - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 111 - - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 112 - - - CF$UID - 113 - - - CF$UID - 114 - - - CF$UID - 115 - - - CF$UID - 116 - - - CF$UID - 117 - - - CF$UID - 118 - - - NS.objects - - - CF$UID - 119 - - - CF$UID - 120 - - - CF$UID - 128 - - - CF$UID - 143 - - - CF$UID - 58 - - - CF$UID - 144 - - - CF$UID - 145 - - - - FileDataType - ArchivableRepresentation - EditorState - NavigableItemName - DocumentNavigableItemName - DocumentExtensionIdentifier - DocumentURL - com.apple.InterfaceBuilder3.CocoaTouch.XIB - - $class - - CF$UID - 97 - - DocumentLocation - - CF$UID - 127 - - DomainIdentifier - - CF$UID - 85 - - IdentifierPath - - CF$UID - 121 - - IndexOfDocumentIdentifier - - CF$UID - 126 - - - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 122 - - - CF$UID - 123 - - - CF$UID - 124 - - - - - $class - - CF$UID - 88 - - Identifier - - CF$UID - 58 - - - - $class - - CF$UID - 88 - - Identifier - - CF$UID - 57 - - - - $class - - CF$UID - 88 - - Identifier - - CF$UID - 125 - - - DCIntrospectDemo - 9223372036854775807 - - $class - - CF$UID - 96 - - documentURL - - CF$UID - 94 - - timestamp - - CF$UID - 0 - - - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 129 - - - CF$UID - 130 - - - CF$UID - 131 - - - CF$UID - 132 - - - NS.objects - - - CF$UID - 133 - - - CF$UID - 136 - - - CF$UID - 132 - - - CF$UID - 138 - - - - IBDockViewController - SelectedObjectIDs - SelectionProvider - IBCanvasViewController - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 134 - - - NS.objects - - - CF$UID - 135 - - - - LastKnownOutlineViewWidth - 270 - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 137 - - - - 6 - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 139 - - - CF$UID - 140 - - - NS.objects - - - CF$UID - 141 - - - CF$UID - 142 - - - - ObjectIDToLastKnownCanvasPositionMap - EditedTopLevelObjectIDs - - $class - - CF$UID - 39 - - NS.keys - - NS.objects - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 137 - - - - View - Xcode.IDEKit.CocoaTouchIntegration.EditorDocument.CocoaTouch - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 146 - - - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospectDemo/DCIntrospectDemo/en.lproj/DCIntrospectDemoViewController.xib - - $classes - - NSURL - NSObject - - $classname - NSURL - - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 149 - - - - {{0, 0}, {600, 600}} - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 151 - - - CF$UID - 152 - - - CF$UID - 153 - - - CF$UID - 154 - - - CF$UID - 155 - - - CF$UID - 156 - - - NS.objects - - - CF$UID - 157 - - - CF$UID - 158 - - - CF$UID - 160 - - - CF$UID - 157 - - - CF$UID - 163 - - - CF$UID - 171 - - - - LayoutFocusMode - console - variables - LayoutMode - IDEDebugArea_SplitView - IDEDebuggerAreaSplitView - 1 - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 159 - - - NS.objects - - - CF$UID - 26 - - - - ConsoleFilterMode - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 161 - - - NS.objects - - - CF$UID - 162 - - - - DBGVariablesViewFilterMode - 2 - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 28 - - - NS.objects - - - CF$UID - 164 - - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 165 - - - CF$UID - 168 - - - - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 166 - - - CF$UID - 167 - - - - VariablesView - 298 - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 169 - - - CF$UID - 170 - - - - ConsoleArea - 301 - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 28 - - - NS.objects - - - CF$UID - 172 - - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 173 - - - CF$UID - 175 - - - - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 166 - - - CF$UID - 174 - - - - 298 - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 169 - - - CF$UID - 176 - - - - 301 - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 28 - - - NS.objects - - - CF$UID - 179 - - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 180 - - - CF$UID - 183 - - - - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 181 - - - CF$UID - 182 - - - - IDEEditor - 203 - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 184 - - - CF$UID - 185 - - - - IDEDebuggerArea - 115 - - $class - - CF$UID - 39 - - NS.keys - - NS.objects - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 6 - - - CF$UID - 7 - - - CF$UID - 8 - - - CF$UID - 9 - - - CF$UID - 188 - - - CF$UID - 10 - - - NS.objects - - - CF$UID - 3 - - - CF$UID - 189 - - - CF$UID - 177 - - - CF$UID - 188 - - - CF$UID - 190 - - - CF$UID - 366 - - - - IDEWorkspaceTabController_A0B74693-FCED-49A6-98D3-9D8399293539 - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 188 - - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 19 - - - CF$UID - 18 - - - CF$UID - 17 - - - CF$UID - 20 - - - CF$UID - 21 - - - CF$UID - 22 - - - CF$UID - 23 - - - CF$UID - 24 - - - NS.objects - - - CF$UID - 26 - - - CF$UID - 177 - - - CF$UID - 191 - - - CF$UID - 192 - - - CF$UID - 198 - - - CF$UID - 235 - - - CF$UID - 14 - - - CF$UID - 243 - - - - DCFrameView.m - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 28 - - - NS.objects - - - CF$UID - 193 - - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 194 - - - CF$UID - 196 - - - - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 33 - - - CF$UID - 195 - - - - 747 - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 33 - - - CF$UID - 197 - - - - 346 - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 42 - - - CF$UID - 199 - - - CF$UID - 41 - - - CF$UID - 200 - - - NS.objects - - - CF$UID - 201 - - - CF$UID - 213 - - - CF$UID - 42 - - - CF$UID - 217 - - - - Xcode.DebuggerKit.ThreadsStacksNavigator - Xcode.IDEKit.Navigator.Issues - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 44 - - - CF$UID - 45 - - - CF$UID - 46 - - - CF$UID - 47 - - - CF$UID - 48 - - - CF$UID - 49 - - - CF$UID - 50 - - - NS.objects - - - CF$UID - 202 - - - CF$UID - 14 - - - CF$UID - 52 - - - CF$UID - 14 - - - CF$UID - 14 - - - CF$UID - 203 - - - CF$UID - 207 - - - - {{0, 0}, {259, 1049}} - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 204 - - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 205 - - - CF$UID - 57 - - - CF$UID - 61 - - - CF$UID - 206 - - - - DCIntrospectDemo - DCFrameView.m - - $class - - CF$UID - 53 - - NS.objects - - - CF$UID - 208 - - - CF$UID - 209 - - - CF$UID - 211 - - - CF$UID - 212 - - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 205 - - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 205 - - - CF$UID - 210 - - - - Frameworks - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 205 - - - CF$UID - 57 - - - CF$UID - 61 - - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 205 - - - CF$UID - 57 - - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 214 - - - CF$UID - 215 - - - CF$UID - 216 - - - NS.objects - - - CF$UID - 162 - - - CF$UID - 26 - - - CF$UID - 14 - - - - IDEStackCompressionValue - IDEThreadsOrQueuesMode - IDEHideAncestorForNonInterestingFrames - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 218 - - - CF$UID - 219 - - - CF$UID - 220 - - - CF$UID - 221 - - - CF$UID - 222 - - - CF$UID - 223 - - - CF$UID - 224 - - - CF$UID - 225 - - - CF$UID - 226 - - - CF$UID - 227 - - - NS.objects - - - CF$UID - 14 - - - CF$UID - 228 - - - CF$UID - 229 - - - CF$UID - 231 - - - CF$UID - 232 - - - CF$UID - 14 - - - CF$UID - 14 - - - CF$UID - 233 - - - CF$UID - 14 - - - CF$UID - 234 - - - - IDEErrorFilteringEnabled - IDEVisibleRect - IDECollapsedFiles - IDEExpandedIssues - IDESelectedNavigables - IDEShowsByType - IDESchemeFilteringEnabled - IDECollapsedTypes - IDERecentFilteringEnabled - IDECollapsedGroups - {{0, 0}, {259, 1027}} - - $class - - CF$UID - 230 - - NS.objects - - - - $classes - - NSMutableSet - NSSet - NSObject - - $classname - NSMutableSet - - - $class - - CF$UID - 230 - - NS.objects - - - - $class - - CF$UID - 38 - - NS.objects - - - - $class - - CF$UID - 230 - - NS.objects - - - - $class - - CF$UID - 230 - - NS.objects - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 28 - - - NS.objects - - - CF$UID - 236 - - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 237 - - - CF$UID - 239 - - - CF$UID - 241 - - - - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 21 - - - CF$UID - 238 - - - - 260 - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 24 - - - CF$UID - 240 - - - - 1582 - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 71 - - - CF$UID - 242 - - - - 260 - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 74 - - - CF$UID - 76 - - - CF$UID - 75 - - - CF$UID - 77 - - - CF$UID - 78 - - - CF$UID - 79 - - - CF$UID - 80 - - - CF$UID - 244 - - - CF$UID - 81 - - - NS.objects - - - CF$UID - 245 - - - CF$UID - 271 - - - CF$UID - 286 - - - CF$UID - 177 - - - CF$UID - 157 - - - CF$UID - 316 - - - CF$UID - 322 - - - CF$UID - 323 - - - CF$UID - 14 - - - - IDEEditorMode_Genius - - $class - - CF$UID - 101 - - geniusEditorContextNode - - CF$UID - 258 - - primaryEditorContextNode - - CF$UID - 246 - - rootLayoutTreeNode - - CF$UID - 256 - - - - $class - - CF$UID - 100 - - children - - CF$UID - 0 - - contentType - 1 - documentArchivableRepresentation - - CF$UID - 247 - - orientation - 0 - parent - - CF$UID - 256 - - - - $class - - CF$UID - 97 - - DocumentLocation - - CF$UID - 254 - - DomainIdentifier - - CF$UID - 85 - - IdentifierPath - - CF$UID - 248 - - IndexOfDocumentIdentifier - - CF$UID - 26 - - - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 249 - - - CF$UID - 250 - - - CF$UID - 251 - - - CF$UID - 252 - - - - - $class - - CF$UID - 88 - - Identifier - - CF$UID - 206 - - - - $class - - CF$UID - 88 - - Identifier - - CF$UID - 61 - - - - $class - - CF$UID - 88 - - Identifier - - CF$UID - 57 - - - - $class - - CF$UID - 88 - - Identifier - - CF$UID - 253 - - - DCIntrospectDemo - - $class - - CF$UID - 96 - - documentURL - - CF$UID - 255 - - timestamp - - CF$UID - 0 - - - - $class - - CF$UID - 95 - - NS.string - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospect/DCFrameView.m - - - $class - - CF$UID - 100 - - children - - CF$UID - 257 - - contentType - 0 - documentArchivableRepresentation - - CF$UID - 0 - - orientation - 0 - parent - - CF$UID - 0 - - - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 246 - - - CF$UID - 258 - - - - - $class - - CF$UID - 100 - - children - - CF$UID - 259 - - contentType - 0 - documentArchivableRepresentation - - CF$UID - 0 - - orientation - 1 - parent - - CF$UID - 256 - - - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 260 - - - - - $class - - CF$UID - 100 - - children - - CF$UID - 0 - - contentType - 2 - documentArchivableRepresentation - - CF$UID - 261 - - orientation - 0 - parent - - CF$UID - 258 - - - - $class - - CF$UID - 97 - - DocumentLocation - - CF$UID - 269 - - DomainIdentifier - - CF$UID - 0 - - IdentifierPath - - CF$UID - 262 - - IndexOfDocumentIdentifier - - CF$UID - 26 - - - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 263 - - - CF$UID - 266 - - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 264 - - - NS.objects - - - CF$UID - 265 - - - - navigableItem_name - DCFrameView.h - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 267 - - - NS.objects - - - CF$UID - 268 - - - - identifier - Xcode.IDEKit.GeniusCategory.Counterparts - - $class - - CF$UID - 96 - - documentURL - - CF$UID - 270 - - timestamp - - CF$UID - 0 - - - - $class - - CF$UID - 95 - - NS.string - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospect/DCFrameView.h - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 151 - - - CF$UID - 152 - - - CF$UID - 153 - - - CF$UID - 154 - - - CF$UID - 155 - - - CF$UID - 156 - - - NS.objects - - - CF$UID - 157 - - - CF$UID - 272 - - - CF$UID - 273 - - - CF$UID - 157 - - - CF$UID - 274 - - - CF$UID - 280 - - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 159 - - - NS.objects - - - CF$UID - 26 - - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 161 - - - NS.objects - - - CF$UID - 162 - - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 28 - - - NS.objects - - - CF$UID - 275 - - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 276 - - - CF$UID - 278 - - - - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 166 - - - CF$UID - 277 - - - - 414 - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 169 - - - CF$UID - 279 - - - - 1167 - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 28 - - - NS.objects - - - CF$UID - 281 - - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 282 - - - CF$UID - 284 - - - - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 166 - - - CF$UID - 283 - - - - 414 - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 169 - - - CF$UID - 285 - - - - 1167 - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 103 - - - NS.objects - - - CF$UID - 287 - - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 105 - - - NS.objects - - - CF$UID - 288 - - - - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 107 - - - CF$UID - 108 - - - CF$UID - 109 - - - NS.objects - - - CF$UID - 289 - - - CF$UID - 26 - - - CF$UID - 314 - - - - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 290 - - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 112 - - - CF$UID - 113 - - - CF$UID - 114 - - - CF$UID - 115 - - - CF$UID - 116 - - - CF$UID - 117 - - - CF$UID - 118 - - - NS.objects - - - CF$UID - 291 - - - CF$UID - 292 - - - CF$UID - 302 - - - CF$UID - 310 - - - CF$UID - 295 - - - CF$UID - 311 - - - CF$UID - 312 - - - - public.objective-c-source - - $class - - CF$UID - 97 - - DocumentLocation - - CF$UID - 300 - - DomainIdentifier - - CF$UID - 85 - - IdentifierPath - - CF$UID - 293 - - IndexOfDocumentIdentifier - - CF$UID - 26 - - - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 294 - - - CF$UID - 296 - - - CF$UID - 297 - - - CF$UID - 298 - - - - - $class - - CF$UID - 88 - - Identifier - - CF$UID - 295 - - - DCIntrospect.m - - $class - - CF$UID - 88 - - Identifier - - CF$UID - 61 - - - - $class - - CF$UID - 88 - - Identifier - - CF$UID - 57 - - - - $class - - CF$UID - 88 - - Identifier - - CF$UID - 299 - - - DCIntrospectDemo - - $class - - CF$UID - 96 - - documentURL - - CF$UID - 301 - - timestamp - - CF$UID - 0 - - - - $class - - CF$UID - 95 - - NS.string - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospect/DCIntrospect.m - - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 303 - - - CF$UID - 304 - - - CF$UID - 305 - - - CF$UID - 306 - - - NS.objects - - - CF$UID - 307 - - - CF$UID - 308 - - - CF$UID - 14 - - - CF$UID - 309 - - - - PrimaryDocumentTimestamp - PrimaryDocumentVisibleCharacterRange - HideAllIssues - PrimaryDocumentSelectedCharacterRange - 325745970.99256402 - {0, 1292} - {1022, 24} - -mainWindow - Xcode.IDEKit.EditorDocument.SourceCode - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 313 - - - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospect/DCIntrospect.m - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 315 - - - - {{0, 0}, {1582, 869}} - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 28 - - - NS.objects - - - CF$UID - 317 - - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 318 - - - CF$UID - 320 - - - - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 181 - - - CF$UID - 319 - - - - 765 - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 184 - - - CF$UID - 321 - - - - 328 - - $class - - CF$UID - 39 - - NS.keys - - NS.objects - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 324 - - - CF$UID - 103 - - - NS.objects - - - CF$UID - 325 - - - CF$UID - 326 - - - - SplitPosition - 0.50063210725784302 - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 327 - - - CF$UID - 105 - - - NS.objects - - - CF$UID - 328 - - - CF$UID - 347 - - - - Alternate - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 107 - - - CF$UID - 108 - - - CF$UID - 109 - - - NS.objects - - - CF$UID - 329 - - - CF$UID - 26 - - - CF$UID - 345 - - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 330 - - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 112 - - - CF$UID - 113 - - - CF$UID - 114 - - - CF$UID - 115 - - - CF$UID - 116 - - - CF$UID - 117 - - - CF$UID - 118 - - - NS.objects - - - CF$UID - 331 - - - CF$UID - 332 - - - CF$UID - 337 - - - CF$UID - 341 - - - CF$UID - 342 - - - CF$UID - 311 - - - CF$UID - 343 - - - - public.c-header - - $class - - CF$UID - 97 - - DocumentLocation - - CF$UID - 269 - - DomainIdentifier - - CF$UID - 0 - - IdentifierPath - - CF$UID - 333 - - IndexOfDocumentIdentifier - - CF$UID - 26 - - - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 334 - - - CF$UID - 336 - - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 264 - - - NS.objects - - - CF$UID - 335 - - - - DCFrameView.h - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 267 - - - NS.objects - - - CF$UID - 268 - - - - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 303 - - - CF$UID - 304 - - - CF$UID - 305 - - - CF$UID - 306 - - - NS.objects - - - CF$UID - 338 - - - CF$UID - 339 - - - CF$UID - 14 - - - CF$UID - 340 - - - - 325758038.37877101 - {0, 213} - {157, 8} - mainRect - DCFrameView.h - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 344 - - - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospect/DCFrameView.h - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 346 - - - - {{0, 0}, {789, 1093}} - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 107 - - - CF$UID - 108 - - - CF$UID - 109 - - - NS.objects - - - CF$UID - 348 - - - CF$UID - 26 - - - CF$UID - 364 - - - - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 349 - - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 112 - - - CF$UID - 113 - - - CF$UID - 114 - - - CF$UID - 115 - - - CF$UID - 116 - - - CF$UID - 117 - - - CF$UID - 118 - - - NS.objects - - - CF$UID - 291 - - - CF$UID - 350 - - - CF$UID - 357 - - - CF$UID - 361 - - - CF$UID - 206 - - - CF$UID - 311 - - - CF$UID - 362 - - - - - $class - - CF$UID - 97 - - DocumentLocation - - CF$UID - 254 - - DomainIdentifier - - CF$UID - 85 - - IdentifierPath - - CF$UID - 351 - - IndexOfDocumentIdentifier - - CF$UID - 26 - - - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 352 - - - CF$UID - 353 - - - CF$UID - 354 - - - CF$UID - 355 - - - - - $class - - CF$UID - 88 - - Identifier - - CF$UID - 206 - - - - $class - - CF$UID - 88 - - Identifier - - CF$UID - 61 - - - - $class - - CF$UID - 88 - - Identifier - - CF$UID - 57 - - - - $class - - CF$UID - 88 - - Identifier - - CF$UID - 356 - - - DCIntrospectDemo - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 303 - - - CF$UID - 304 - - - CF$UID - 305 - - - CF$UID - 306 - - - NS.objects - - - CF$UID - 358 - - - CF$UID - 359 - - - CF$UID - 14 - - - CF$UID - 360 - - - - 325758038.37864798 - {449, 2864} - {3020, 0} - -drawRect: - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 363 - - - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospect/DCFrameView.m - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 365 - - - - {{0, 0}, {1582, 1093}} - {{66, 6}, {1842, 1169}} - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 368 - - - CF$UID - 369 - - - CF$UID - 370 - - - CF$UID - 371 - - - CF$UID - 372 - - - CF$UID - 373 - - - CF$UID - 374 - - - CF$UID - 375 - - - CF$UID - 376 - - - CF$UID - 377 - - - CF$UID - 378 - - - NS.objects - - - CF$UID - 14 - - - CF$UID - 379 - - - CF$UID - 26 - - - CF$UID - 512 - - - CF$UID - 517 - - - CF$UID - 520 - - - CF$UID - 551 - - - CF$UID - 552 - - - CF$UID - 559 - - - CF$UID - 14 - - - CF$UID - 14 - - - - BreakpointsActivated - DefaultEditorStatesForURLs - DebuggingWindowBehavior - ActiveRunDestination - ActiveScheme - LastCompletedPersistentSchemeBasedActivityReport - DocumentWindows - DefaultEditorFrameSizeForURLs - RecentEditorDocumentURLs - AppFocusInMiniDebugging - MiniDebuggingConsole - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 144 - - - CF$UID - 380 - - - CF$UID - 311 - - - NS.objects - - - CF$UID - 381 - - - CF$UID - 393 - - - CF$UID - 439 - - - - Xcode.Xcode3ProjectSupport.EditorDocument.Xcode3Project - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 382 - - - NS.objects - - - CF$UID - 384 - - - - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 383 - - - - $class - - CF$UID - 95 - - NS.string - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospectDemo/DCIntrospectDemo/en.lproj/DCIntrospectDemoViewController.xib - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 129 - - - CF$UID - 130 - - - CF$UID - 131 - - - CF$UID - 132 - - - NS.objects - - - CF$UID - 385 - - - CF$UID - 387 - - - CF$UID - 389 - - - CF$UID - 390 - - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 134 - - - NS.objects - - - CF$UID - 386 - - - - 270 - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 388 - - - - 12 - IBStructureViewController - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 139 - - - CF$UID - 140 - - - NS.objects - - - CF$UID - 391 - - - CF$UID - 392 - - - - - $class - - CF$UID - 39 - - NS.keys - - NS.objects - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 137 - - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 394 - - - NS.objects - - - CF$UID - 396 - - - - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 395 - - - - $class - - CF$UID - 95 - - NS.string - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospectDemo/DCIntrospectDemo.xcodeproj/ - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 397 - - - CF$UID - 398 - - - CF$UID - 399 - - - CF$UID - 400 - - - CF$UID - 401 - - - NS.objects - - - CF$UID - 402 - - - CF$UID - 403 - - - CF$UID - 409 - - - CF$UID - 410 - - - CF$UID - 423 - - - - Xcode3ProjectEditorPreviousProjectEditorClass - Xcode3ProjectEditor.sourceList.splitview - Xcode3ProjectEditorPreviousTargetEditorClass - Xcode3ProjectEditorSelectedDocumentLocations - Xcode3ProjectEditor_Xcode3BuildPhasesEditor - Xcode3ProjectInfoEditor - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 28 - - - NS.objects - - - CF$UID - 404 - - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 405 - - - CF$UID - 407 - - - - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 33 - - - CF$UID - 406 - - - - 153 - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 31 - - - CF$UID - 32 - - - NS.objects - - - CF$UID - 33 - - - CF$UID - 408 - - - - 508 - Xcode3BuildPhasesEditor - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 411 - - - - - $class - - CF$UID - 422 - - documentURL - - CF$UID - 412 - - selection - - CF$UID - 414 - - timestamp - - CF$UID - 413 - - - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospectDemo/DCIntrospectDemo.xcodeproj/ - 325747733.140028 - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 415 - - - CF$UID - 416 - - - CF$UID - 417 - - - NS.objects - - - CF$UID - 418 - - - CF$UID - 419 - - - CF$UID - 420 - - - - Editor - Target - Xcode3BuildPhasesEditorLocations - Xcode3BuildPhasesEditor - DCIntrospectDemo - - $class - - CF$UID - 13 - - NS.objects - - - CF$UID - 421 - - - - - $class - - CF$UID - 39 - - NS.keys - - NS.objects - - - - $classes - - Xcode3ProjectDocumentLocation - DVTDocumentLocation - NSObject - - $classname - Xcode3ProjectDocumentLocation - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 424 - - - CF$UID - 425 - - - CF$UID - 426 - - - CF$UID - 427 - - - CF$UID - 428 - - - CF$UID - 429 - - - CF$UID - 430 - - - NS.objects - - - CF$UID - 431 - - - CF$UID - 432 - - - CF$UID - 433 - - - CF$UID - 434 - - - CF$UID - 436 - - - CF$UID - 437 - - - CF$UID - 438 - - - - Xcode3BuildPhasesEditorFilterKey - AB0D01CF136A778000962171 - AB0D01CD136A778000962171 - Xcode3BuildPhasesEditorDisclosedNamesKey - AB0D01CC136A778000962171 - kXcode3BuildPhasesEditorScrollPointKey - AB0D01CE136A778000962171 - - - $class - - CF$UID - 39 - - NS.keys - - NS.objects - - - - $class - - CF$UID - 39 - - NS.keys - - NS.objects - - - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 435 - - - CF$UID - 435 - - - CF$UID - 435 - - - CF$UID - 435 - - - CF$UID - 435 - - - - Link Binary With Libraries - - $class - - CF$UID - 39 - - NS.keys - - NS.objects - - - {0, 0} - - $class - - CF$UID - 39 - - NS.keys - - NS.objects - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 440 - - - CF$UID - 442 - - - CF$UID - 444 - - - CF$UID - 446 - - - CF$UID - 448 - - - CF$UID - 450 - - - CF$UID - 452 - - - CF$UID - 454 - - - CF$UID - 456 - - - CF$UID - 458 - - - CF$UID - 460 - - - CF$UID - 462 - - - NS.objects - - - CF$UID - 464 - - - CF$UID - 468 - - - CF$UID - 472 - - - CF$UID - 475 - - - CF$UID - 479 - - - CF$UID - 483 - - - CF$UID - 486 - - - CF$UID - 490 - - - CF$UID - 494 - - - CF$UID - 500 - - - CF$UID - 504 - - - CF$UID - 508 - - - - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 441 - - - - $class - - CF$UID - 95 - - NS.string - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospect/DCIntrospect.h - - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 443 - - - - $class - - CF$UID - 95 - - NS.string - file://localhost/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSValue.h - - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 445 - - - - $class - - CF$UID - 95 - - NS.string - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoViewController.m - - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 447 - - - - $class - - CF$UID - 95 - - NS.string - file://localhost/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIWindow.h - - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 449 - - - - $class - - CF$UID - 95 - - NS.string - file://localhost/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIGestureRecognizer.h - - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 451 - - - - $class - - CF$UID - 95 - - NS.string - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospectDemo/DCIntrospectDemo/main.m - - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 453 - - - - $class - - CF$UID - 95 - - NS.string - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospect/DCFrameView.m - - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 455 - - - - $class - - CF$UID - 95 - - NS.string - file://localhost/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIView.h - - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 457 - - - - $class - - CF$UID - 95 - - NS.string - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospect/DCIntrospect.m - - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 459 - - - - $class - - CF$UID - 95 - - NS.string - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoAppDelegate.m - - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 461 - - - - $class - - CF$UID - 95 - - NS.string - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospect/DCFrameView.h - - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 463 - - - - $class - - CF$UID - 95 - - NS.string - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoAppDelegate.h - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 303 - - - CF$UID - 304 - - - CF$UID - 305 - - - CF$UID - 306 - - - NS.objects - - - CF$UID - 465 - - - CF$UID - 466 - - - CF$UID - 14 - - - CF$UID - 467 - - - - 325755231.77792197 - {0, 438} - {194, 0} - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 303 - - - CF$UID - 304 - - - CF$UID - 305 - - - CF$UID - 306 - - - NS.objects - - - CF$UID - 469 - - - CF$UID - 470 - - - CF$UID - 14 - - - CF$UID - 471 - - - - 325748375.24916101 - {0, 1523} - {808, 0} - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 303 - - - CF$UID - 304 - - - CF$UID - 305 - - - CF$UID - 306 - - - NS.objects - - - CF$UID - 473 - - - CF$UID - 474 - - - CF$UID - 14 - - - CF$UID - 437 - - - - 325755114.88090199 - {0, 1041} - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 303 - - - CF$UID - 304 - - - CF$UID - 305 - - - CF$UID - 306 - - - NS.objects - - - CF$UID - 476 - - - CF$UID - 477 - - - CF$UID - 14 - - - CF$UID - 478 - - - - 325746170.03192902 - {0, 2524} - {344, 58} - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 303 - - - CF$UID - 304 - - - CF$UID - 305 - - - CF$UID - 306 - - - NS.objects - - - CF$UID - 480 - - - CF$UID - 481 - - - CF$UID - 14 - - - CF$UID - 482 - - - - 325746610.37175798 - {4117, 3863} - {6618, 169} - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 303 - - - CF$UID - 304 - - - CF$UID - 305 - - - CF$UID - 306 - - - NS.objects - - - CF$UID - 484 - - - CF$UID - 485 - - - CF$UID - 14 - - - CF$UID - 437 - - - - 325755538.20431203 - {0, 353} - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 303 - - - CF$UID - 304 - - - CF$UID - 305 - - - CF$UID - 306 - - - NS.objects - - - CF$UID - 487 - - - CF$UID - 488 - - - CF$UID - 14 - - - CF$UID - 489 - - - - 325758038.377765 - {449, 2864} - {3020, 0} - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 303 - - - CF$UID - 304 - - - CF$UID - 305 - - - CF$UID - 306 - - - NS.objects - - - CF$UID - 491 - - - CF$UID - 492 - - - CF$UID - 14 - - - CF$UID - 493 - - - - 325755415.12887597 - {6080, 3562} - {3554, 71} - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 495 - - - CF$UID - 303 - - - CF$UID - 305 - - - CF$UID - 304 - - - CF$UID - 306 - - - NS.objects - - - CF$UID - 496 - - - CF$UID - 497 - - - CF$UID - 14 - - - CF$UID - 498 - - - CF$UID - 499 - - - - CodeFolds - - $class - - CF$UID - 95 - - NS.string - { - c = ( - { - l = "(UIView *)"; - r = "{1496, 14}"; - s = 1; - }, - { - l = "(NSMutableArray *)"; - r = "{1522, 22}"; - s = 1; - } - ); - r = "{0, 1794}"; - s = 0; -} - - 325756810.07773602 - {1063, 1622} - {3018, 0} - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 303 - - - CF$UID - 304 - - - CF$UID - 305 - - - CF$UID - 306 - - - NS.objects - - - CF$UID - 501 - - - CF$UID - 502 - - - CF$UID - 14 - - - CF$UID - 503 - - - - 325755113.53931499 - {0, 978} - {493, 18} - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 303 - - - CF$UID - 304 - - - CF$UID - 305 - - - CF$UID - 306 - - - NS.objects - - - CF$UID - 505 - - - CF$UID - 506 - - - CF$UID - 14 - - - CF$UID - 507 - - - - 325755818.89896798 - {0, 213} - {157, 8} - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 303 - - - CF$UID - 304 - - - CF$UID - 305 - - - CF$UID - 306 - - - NS.objects - - - CF$UID - 509 - - - CF$UID - 510 - - - CF$UID - 14 - - - CF$UID - 511 - - - - 325755004.89657003 - {0, 614} - {608, 0} - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 513 - - - CF$UID - 514 - - - NS.objects - - - CF$UID - 515 - - - CF$UID - 516 - - - - IDEDeviceLocation - IDEDeviceArchitecture - dvtdevice-iphonesimulator:/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk-iPhone - i386 - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 518 - - - NS.objects - - - CF$UID - 519 - - - - IDENameString - DCIntrospectDemo - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 521 - - - CF$UID - 522 - - - CF$UID - 523 - - - NS.objects - - - CF$UID - 524 - - - CF$UID - 550 - - - CF$UID - 531 - - - - IDEActivityReportCompletionSummaryStringSegments - IDEActivityReportOptions - IDEActivityReportTitle - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 525 - - - CF$UID - 532 - - - CF$UID - 536 - - - CF$UID - 541 - - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 526 - - - CF$UID - 527 - - - CF$UID - 528 - - - NS.objects - - - CF$UID - 529 - - - CF$UID - 530 - - - CF$UID - 531 - - - - IDEActivityReportStringSegmentPriority - IDEActivityReportStringSegmentBackSeparator - IDEActivityReportStringSegmentStringValue - 2 - - Build - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 526 - - - CF$UID - 527 - - - CF$UID - 528 - - - NS.objects - - - CF$UID - 533 - - - CF$UID - 534 - - - CF$UID - 535 - - - - 4 - : - DCIntrospectDemo - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 526 - - - CF$UID - 527 - - - CF$UID - 528 - - - NS.objects - - - CF$UID - 537 - - - CF$UID - 538 - - - CF$UID - 539 - - - - 1 - - - $class - - CF$UID - 540 - - NS.data - - YnBsaXN0MDDUAQIDBAUGOzxYJHZlcnNpb25YJG9iamVjdHNZJGFy - Y2hpdmVyVCR0b3ASAAGGoK0HCA8QGhscJCUrMTQ3VSRudWxs0wkK - CwwNDlxOU0F0dHJpYnV0ZXNWJGNsYXNzWE5TU3RyaW5ngAOADIAC - WVN1Y2NlZWRlZNMKERITFBdXTlMua2V5c1pOUy5vYmplY3RzgAui - FRaABIAFohgZgAaACVZOU0ZvbnRXTlNDb2xvctQKHR4fICEiI1ZO - U05hbWVWTlNTaXplWE5TZkZsYWdzgAiAByNAJgAAAAAAABENEF8Q - EUx1Y2lkYUdyYW5kZS1Cb2xk0iYnKClaJGNsYXNzbmFtZVgkY2xh - c3Nlc1ZOU0ZvbnSiKCpYTlNPYmplY3TTCiwtLi8wXE5TQ29sb3JT - cGFjZVdOU1doaXRlgAoQA0IwANImJzIzV05TQ29sb3KiMirSJic1 - NlxOU0RpY3Rpb25hcnmiNSrSJic4OV8QEk5TQXR0cmlidXRlZFN0 - cmluZ6I6Kl8QEk5TQXR0cmlidXRlZFN0cmluZ18QD05TS2V5ZWRB - cmNoaXZlctE9PlRyb290gAEACAARABoAIwAtADIANwBFAEsAUgBf - AGYAbwBxAHMAdQB/AIYAjgCZAJsAngCgAKIApQCnAKkAsAC4AMEA - yADPANgA2gDcAOUA6AD8AQEBDAEVARwBHwEoAS8BPAFEAUYBSAFL - AVABWAFbAWABbQFwAXUBigGNAaIBtAG3AbwAAAAAAAACAQAAAAAA - AAA/AAAAAAAAAAAAAAAAAAABvg== - - - - $classes - - NSMutableData - NSData - NSObject - - $classname - NSMutableData - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 526 - - - CF$UID - 542 - - - CF$UID - 543 - - - CF$UID - 528 - - - CF$UID - 544 - - - CF$UID - 545 - - - NS.objects - - - CF$UID - 546 - - - CF$UID - 157 - - - CF$UID - 547 - - - CF$UID - 549 - - - CF$UID - 157 - - - CF$UID - 157 - - - - IDEActivityReportStringSegmentType - IDEActivityReportStringSegmentDate - IDEActivityReportStringSegmentDateStyle - IDEActivityReportStringSegmentTimeStyle - 3 - - $class - - CF$UID - 548 - - NS.time - 325758018.42077798 - - - $classes - - NSDate - NSObject - - $classname - NSDate - - Today at 6:20 PM - 106 - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 3 - - - - - $class - - CF$UID - 39 - - NS.keys - - - CF$UID - 553 - - - NS.objects - - - CF$UID - 554 - - - - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 94 - - - - $class - - CF$UID - 35 - - NS.keys - - - CF$UID - 555 - - - CF$UID - 556 - - - NS.objects - - - CF$UID - 557 - - - CF$UID - 558 - - - - width - height - 600 - 600 - - $class - - CF$UID - 38 - - NS.objects - - - CF$UID - 560 - - - CF$UID - 562 - - - CF$UID - 564 - - - CF$UID - 566 - - - CF$UID - 568 - - - CF$UID - 570 - - - CF$UID - 572 - - - CF$UID - 574 - - - CF$UID - 576 - - - CF$UID - 578 - - - - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 561 - - - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospect/DCFrameView.h - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 563 - - - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospect/DCFrameView.m - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 565 - - - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospect/DCIntrospect.h - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 567 - - - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospect/DCIntrospect.m - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 569 - - - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospectDemo/DCIntrospectDemo/main.m - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 571 - - - file://localhost/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIView.h - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 573 - - - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoViewController.h - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 575 - - - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoViewController.m - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 577 - - - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoAppDelegate.h - - $class - - CF$UID - 147 - - NS.base - - CF$UID - 0 - - NS.relative - - CF$UID - 579 - - - file://localhost/Users/domesticcat/Projects/Open%20Source/DCIntrospect/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoAppDelegate.m - - $top - - State - - CF$UID - 1 - - - $version - 100000 - - diff --git a/DCIntrospectDemo/DCIntrospectDemo.xcodeproj/xcuserdata/domesticcat.xcuserdatad/xcschemes/DCIntrospectDemo.xcscheme b/DCIntrospectDemo/DCIntrospectDemo.xcodeproj/xcuserdata/domesticcat.xcuserdatad/xcschemes/DCIntrospectDemo.xcscheme deleted file mode 100644 index 58e6076..0000000 --- a/DCIntrospectDemo/DCIntrospectDemo.xcodeproj/xcuserdata/domesticcat.xcuserdatad/xcschemes/DCIntrospectDemo.xcscheme +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/DCIntrospectDemo/DCIntrospectDemo.xcodeproj/xcuserdata/domesticcat.xcuserdatad/xcschemes/xcschememanagement.plist b/DCIntrospectDemo/DCIntrospectDemo.xcodeproj/xcuserdata/domesticcat.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index 7c312dd..0000000 --- a/DCIntrospectDemo/DCIntrospectDemo.xcodeproj/xcuserdata/domesticcat.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - SchemeUserState - - DCIntrospectDemo.xcscheme - - orderHint - 0 - - - SuppressBuildableAutocreation - - AB0D01CF136A778000962171 - - primary - - - - - diff --git a/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemo-Info.plist b/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemo-Info.plist index ec7530f..0efc7b2 100644 --- a/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemo-Info.plist +++ b/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemo-Info.plist @@ -33,6 +33,7 @@ UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortraitUpsideDown diff --git a/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoAppDelegate.h b/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoAppDelegate.h index 136513c..434bb72 100644 --- a/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoAppDelegate.h +++ b/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoAppDelegate.h @@ -1,21 +1,18 @@ // // DCIntrospectDemoAppDelegate.h -// DCIntrospectDemo // // Created by Domestic Cat on 29/04/11. -// Copyright 2011 __MyCompanyName__. All rights reserved. // #import @class DCIntrospectDemoViewController; -@interface DCIntrospectDemoAppDelegate : NSObject { - +@interface DCIntrospectDemoAppDelegate : NSObject +{ } @property (nonatomic, retain) IBOutlet UIWindow *window; - @property (nonatomic, retain) IBOutlet DCIntrospectDemoViewController *viewController; @end diff --git a/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoAppDelegate.m b/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoAppDelegate.m index 2e0a756..4135c01 100644 --- a/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoAppDelegate.m +++ b/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoAppDelegate.m @@ -15,10 +15,22 @@ @implementation DCIntrospectDemoAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // create a custom tap gesture recognizer so introspection can be invoked from a device + // this one is a two finger triple tap + UITapGestureRecognizer *defaultGestureRecognizer = [[[UITapGestureRecognizer alloc] init] autorelease]; + defaultGestureRecognizer.cancelsTouchesInView = NO; + defaultGestureRecognizer.delaysTouchesBegan = NO; + defaultGestureRecognizer.delaysTouchesEnded = NO; + defaultGestureRecognizer.numberOfTapsRequired = 3; + defaultGestureRecognizer.numberOfTouchesRequired = 2; + [DCIntrospect sharedIntrospector].invokeGestureRecognizer = defaultGestureRecognizer; + self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible]; - + + // always insert this AFTER makeKeyAndVisible so statusBarOrientation is reported correctly. [[DCIntrospect sharedIntrospector] start]; + return YES; } @@ -46,6 +58,7 @@ - (void)dealloc { [window release]; [viewController release]; + [super dealloc]; } diff --git a/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoViewController.h b/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoViewController.h index 0419337..cd062d4 100644 --- a/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoViewController.h +++ b/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoViewController.h @@ -3,13 +3,20 @@ // DCIntrospectDemo // // Created by Domestic Cat on 29/04/11. -// Copyright 2011 __MyCompanyName__. All rights reserved. +// Copyright 2011 Domestic Cat Software. All rights reserved. // #import -@interface DCIntrospectDemoViewController : UIViewController { - +@interface DCIntrospectDemoViewController : UIViewController +{ } +@property (nonatomic, retain) IBOutlet UIActivityIndicatorView *activityIndicator; +@property (nonatomic, retain) IBOutlet UILabel *label; + +- (IBAction)buttonTapped:(id)sender; +- (IBAction)switchChanged:(id)sender; +- (IBAction)sliderChanged:(id)sender; + @end diff --git a/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoViewController.m b/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoViewController.m index 204bd6d..2706df3 100644 --- a/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoViewController.m +++ b/DCIntrospectDemo/DCIntrospectDemo/DCIntrospectDemoViewController.m @@ -3,47 +3,109 @@ // DCIntrospectDemo // // Created by Domestic Cat on 29/04/11. -// Copyright 2011 __MyCompanyName__. All rights reserved. +// Copyright 2011 Domestic Cat Software. All rights reserved. // #import "DCIntrospectDemoViewController.h" +#import "DCIntrospect.h" @implementation DCIntrospectDemoViewController +@synthesize activityIndicator; +@synthesize label; - (void)dealloc { + [[DCIntrospect sharedIntrospector] removeNamesForViewsInView:self.view]; + + [activityIndicator release]; + [label release]; [super dealloc]; } - (void)didReceiveMemoryWarning { - // Releases the view if it doesn't have a superview. - [super didReceiveMemoryWarning]; - - // Release any cached data, images, etc that aren't in use. + [super didReceiveMemoryWarning]; } #pragma mark - View lifecycle -/* -// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. - (void)viewDidLoad { - [super viewDidLoad]; + [super viewDidLoad]; + + // set the activity indicator to a non-integer frame for demonstration + self.activityIndicator.frame = CGRectOffset(self.activityIndicator.frame, 0.5, 0.0); + [[DCIntrospect sharedIntrospector] setName:@"activityIndicator" forObject:self.activityIndicator accessedWithSelf:YES]; } -*/ - (void)viewDidUnload { - [super viewDidUnload]; - // Release any retained subviews of the main view. - // e.g. self.myOutlet = nil; + [self setActivityIndicator:nil]; + [self setLabel:nil]; + + [super viewDidUnload]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { - // Return YES for supported orientations - return (interfaceOrientation == UIInterfaceOrientationPortrait); + return YES; +} + +- (BOOL)textFieldShouldReturn:(UITextField *)textField +{ + [textField resignFirstResponder]; + return YES; +} + +#pragma mark Table View Methods + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *CellIdentifier = @"Cell"; + + UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease]; + } + + cell.textLabel.text = [NSString stringWithFormat:@"Row %i", indexPath.row]; + cell.detailTextLabel.text = @"Detailed Text"; + cell.accessoryType = UITableViewCellAccessoryCheckmark; + + return cell; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return 2; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 3; +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + return [NSString stringWithFormat:@"Section %i", section]; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; +} + +- (IBAction)buttonTapped:(id)sender +{ +} + +- (IBAction)switchChanged:(id)sender +{ +} + +- (IBAction)sliderChanged:(id)sender +{ } @end diff --git a/DCIntrospectDemo/DCIntrospectDemo/circle.png b/DCIntrospectDemo/DCIntrospectDemo/circle.png new file mode 100644 index 0000000..196ae1c Binary files /dev/null and b/DCIntrospectDemo/DCIntrospectDemo/circle.png differ diff --git a/DCIntrospectDemo/DCIntrospectDemo/en.lproj/DCIntrospectDemoViewController.xib b/DCIntrospectDemo/DCIntrospectDemo/en.lproj/DCIntrospectDemoViewController.xib deleted file mode 100644 index 2550f89..0000000 --- a/DCIntrospectDemo/DCIntrospectDemo/en.lproj/DCIntrospectDemoViewController.xib +++ /dev/null @@ -1,298 +0,0 @@ - - - - 1056 - 10J869 - 1306 - 1038.35 - 461.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 301 - - - YES - IBUIScrollView - IBUIButton - IBUIActivityIndicatorView - IBUIView - IBUILabel - IBProxyObject - - - YES - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - YES - - YES - - - - - YES - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - - YES - - - 292 - {{72, 53}, {96, 42}} - - - NO - YES - 7 - NO - IBCocoaTouchFramework - Label - - 1 - MCAwIDAAA - - - 1 - 10 - 1 - - - - 268 - - YES - - - 292 - {{155, 174}, {72, 37}} - - - NO - IBCocoaTouchFramework - 0 - 0 - - Helvetica-Bold - 15 - 16 - - 1 - - 3 - MQA - - - 1 - MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA - - - 3 - MC41AA - - - - - 292 - - YES - - - 292 - {{53, 40}, {20, 20}} - - - NO - IBCocoaTouchFramework - NO - YES - 2 - - - {{37, 170}, {110, 116}} - - - - 3 - MQA - - 2 - - - IBCocoaTouchFramework - - - {{11, 77}, {240, 292}} - - - - 3 - MC44MTg1NDgzODcxAA - - YES - YES - IBCocoaTouchFramework - - - {{0, 20}, {320, 460}} - - - - - NO - - IBCocoaTouchFramework - - - - - YES - - - view - - - - 7 - - - - - YES - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 6 - - - YES - - - - - - - 8 - - - - - 9 - - - YES - - - - - - - 10 - - - - - 11 - - - YES - - - - - - 12 - - - - - - - YES - - YES - -1.CustomClassName - -2.CustomClassName - 10.IBPluginDependency - 11.IBPluginDependency - 12.IBPluginDependency - 6.IBEditorWindowLastContentRect - 6.IBPluginDependency - 8.IBPluginDependency - 9.IBPluginDependency - - - YES - DCIntrospectDemoViewController - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - {{239, 654}, {320, 480}} - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - YES - - - - - - YES - - - - - 12 - - - - YES - - DCIntrospectDemoViewController - UIViewController - - IBProjectSource - ./Classes/DCIntrospectDemoViewController.h - - - - - 0 - IBCocoaTouchFramework - - com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 - - - YES - 3 - 301 - - diff --git a/DCIntrospectDemo/DCIntrospectDemo/en.lproj/MainWindow.xib b/DCIntrospectDemo/DCIntrospectDemo/en.lproj/MainWindow.xib index 8498b16..6b2247a 100644 --- a/DCIntrospectDemo/DCIntrospectDemo/en.lproj/MainWindow.xib +++ b/DCIntrospectDemo/DCIntrospectDemo/en.lproj/MainWindow.xib @@ -2,17 +2,32 @@ 1024 - 10D571 - 786 - 1038.29 - 460.00 + 11A430e + 1565 + 1117 + 552.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 112 + 521 - + YES - + IBUITableView + IBUIButton + IBUIPageControl + IBUISlider + IBUISegmentedControl + IBUISwitch + IBUILabel + IBUITextField + IBProxyObject + IBUICustomObject + IBUIWindow + IBUIView + IBUIProgressView + IBUIImageView + IBUIViewController + IBUIActivityIndicatorView YES @@ -23,9 +38,7 @@ YES - - YES - + YES @@ -41,9 +54,293 @@ IBCocoaTouchFramework - DCIntrospectDemoViewController + + + 274 + + YES + + + 268 + {{20, 113}, {279, 209}} + + + + + 3 + MQA + + YES + IBCocoaTouchFramework + YES + 1 + 0 + YES + 42 + 22 + 22 + + + + 292 + {{235, 20}, {64, 64}} + + + + + 3 + MCAwAA + + NO + NO + + ImageAccessibilityHint + ImageAccessibilityLabel + + + IBCocoaTouchFramework + + NSImage + circle.png + + + + + 268 + {{28, 376}, {150, 9}} + + + + NO + IBCocoaTouchFramework + 0.5 + + + + 292 + {{26, 394}, {118, 23}} + + + + NO + IBCocoaTouchFramework + 0 + 0 + 0.5 + + + + 292 + {{158, 395}, {20, 20}} + + + + NO + IBCocoaTouchFramework + NO + YES + 2 + + + + 268 + {{21, 331}, {278, 37}} + + + + NO + 1 + + Hint + Button + + IBCocoaTouchFramework + 0 + 0 + + Helvetica-Bold + 15 + 16 + + 1 + Button w/ Actions + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + 3 + MC41AA + + + + + 268 + {{20, 424}, {145, 23}} + + + + NO + YES + 7 + NO + IBCocoaTouchFramework + Non-opaque label + + Helvetica + 17 + 16 + + + 1 + MCAwIDAAA + + + 1 + 10 + 1 + + + + 268 + {{195, 424}, {108, 23}} + + + + + 1 + MC45NzI4MjYwODcgMC45NzI4MjYwODcgMC45NzI4MjYwODcAA + + YES + 7 + NO + IBCocoaTouchFramework + Opaque label + + + + 1 + 10 + 1 + + + + 268 + {{197, 386}, {94, 27}} + + + + NO + IBCocoaTouchFramework + 0 + 0 + YES + + + + 292 + {{20, 20}, {97, 31}} + + + + NO + YES + + Accessibility Hint + Accessibility Label + + + IBCocoaTouchFramework + 0 + Text Field + 3 + Placeholder + + 3 + MAA + + 2 + + + + Helvetica + 12 + 16 + + YES + 17 + + IBCocoaTouchFramework + + + + + 292 + {{20, 66}, {207, 30}} + + + + NO + IBCocoaTouchFramework + 2 + 2 + 0 + + YES + First + Second + + + YES + + + + + YES + + + + + YES + {0, 0} + {0, 0} + + + YES + + + + + + + 1316 + + {{149, 10}, {38, 36}} + + + + NO + IBCocoaTouchFramework + 0 + 0 + 3 + + + {{0, 20}, {320, 460}} + + + + + 3 + MQA + + + IBCocoaTouchFramework + + 1 1 IBCocoaTouchFramework @@ -91,6 +388,73 @@ 14 + + + activityIndicator + + + + 27 + + + + label + + + + 29 + + + + sliderChanged: + + + 13 + + 31 + + + + dataSource + + + + 35 + + + + delegate + + + + 36 + + + + buttonTapped: + + + 7 + + 39 + + + + switchChanged: + + + 13 + + 40 + + + + delegate + + + + 50 + @@ -121,8 +485,95 @@ 10 + + YES + + + + 16 + + + YES + + + + + + + + + + + + + + + + + 17 + + + YES + + + + + 18 + + + + + 19 + + + + + 20 + + + + + 21 + + + + + 22 + + + + + 23 + + + + + 24 + + + + + 25 + + + + + 41 + + + + + 42 + + + + + 43 + + + 12 @@ -141,8 +592,21 @@ 10.IBPluginDependency 12.IBEditorWindowLastContentRect 12.IBPluginDependency + 16.IBPluginDependency + 17.IBPluginDependency + 18.IBPluginDependency + 19.IBPluginDependency + 20.IBPluginDependency + 21.IBPluginDependency + 22.IBPluginDependency + 23.IBPluginDependency + 24.IBPluginDependency + 25.IBPluginDependency 3.CustomClassName 3.IBPluginDependency + 41.IBPluginDependency + 42.IBPluginDependency + 43.IBPluginDependency YES @@ -153,39 +617,40 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin {{525, 346}, {320, 480}} com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin DCIntrospectDemoAppDelegate com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin YES - - YES - + YES - - YES - + - 15 + 49 YES - - UIWindow - UIView - - IBUserSource - - - DCIntrospectDemoAppDelegate NSObject @@ -223,205 +688,79 @@ IBProjectSource - DCIntrospectDemoAppDelegate.h - - - - DCIntrospectDemoAppDelegate - NSObject - - IBUserSource - + ./Classes/DCIntrospectDemoAppDelegate.h DCIntrospectDemoViewController UIViewController - - IBProjectSource - DCIntrospectDemoViewController.h - - - - - YES - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - UIKit.framework/Headers/UIAccessibility.h - - - - NSObject - - IBFrameworkSource - UIKit.framework/Headers/UINibLoading.h - - - - NSObject - - IBFrameworkSource - UIKit.framework/Headers/UIResponder.h - - - - UIApplication - UIResponder - - IBFrameworkSource - UIKit.framework/Headers/UIApplication.h - - - - UIResponder - NSObject - - - - UISearchBar - UIView - - IBFrameworkSource - UIKit.framework/Headers/UISearchBar.h - - - - UISearchDisplayController - NSObject - - IBFrameworkSource - UIKit.framework/Headers/UISearchDisplayController.h - - - - UIView - - IBFrameworkSource - UIKit.framework/Headers/UITextField.h - - - - UIView - UIResponder - - IBFrameworkSource - UIKit.framework/Headers/UIView.h - - - - UIViewController - - IBFrameworkSource - UIKit.framework/Headers/UINavigationController.h - - - - UIViewController - - IBFrameworkSource - UIKit.framework/Headers/UIPopoverController.h + + YES + + YES + buttonTapped: + switchChanged: + + + YES + id + id + - - - UIViewController - - IBFrameworkSource - UIKit.framework/Headers/UISplitViewController.h + + YES + + YES + buttonTapped: + switchChanged: + + + YES + + buttonTapped: + id + + + switchChanged: + id + + - - - UIViewController - - IBFrameworkSource - UIKit.framework/Headers/UITabBarController.h + + YES + + YES + activityIndicator + label + + + YES + UIActivityIndicatorView + UILabel + - - - UIViewController - UIResponder - - IBFrameworkSource - UIKit.framework/Headers/UIViewController.h + + YES + + YES + activityIndicator + label + + + YES + + activityIndicator + UIActivityIndicatorView + + + label + UILabel + + - - - UIWindow - UIView - IBFrameworkSource - UIKit.framework/Headers/UIWindow.h + IBProjectSource + ./Classes/DCIntrospectDemoViewController.h @@ -437,8 +776,11 @@ YES - DCIntrospectDemo.xcodeproj 3 - 112 + + circle.png + {70, 70} + + 521 diff --git a/DCIntrospectDemo/DCIntrospectDemo/main.m b/DCIntrospectDemo/DCIntrospectDemo/main.m index 7962f2e..f8f901d 100644 --- a/DCIntrospectDemo/DCIntrospectDemo/main.m +++ b/DCIntrospectDemo/DCIntrospectDemo/main.m @@ -3,7 +3,7 @@ // DCIntrospectDemo // // Created by Domestic Cat on 29/04/11. -// Copyright 2011 __MyCompanyName__. All rights reserved. +// Copyright 2011 Domestic Cat Software. All rights reserved. // #import diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..5844bc8 --- /dev/null +++ b/license.txt @@ -0,0 +1,19 @@ +Copyright (C) 2011 by Patrick Richards domesticcatsoftware.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..32dae15 --- /dev/null +++ b/readme.md @@ -0,0 +1,101 @@ +DCIntrospect +============ + +Twitter: [@patr](http://twitter.com/patr) + +Our commercial apps: [domesticcat.com.au](http://domesticcat.com.au/apps) + +Introspect is small set of tools for iOS that aid in debugging user interfaces built with UIKit. It's especially useful for UI layouts that are dynamically created or can change during runtime, or for tuning performance by finding non-opaque views or views that are re-drawing unnecessarily. It's designed for use in the iPhone simulator, but can also be used on a device. + + +![Introspect Demo Image](http://domesticcat.com.au/projects/introspect/introspectdemo.png) + + +It uses keyboard shortcuts to handle starting, ending and other commands. It can also be invoked via an app-wide `UIGestureRecognizer` if it is to be used on the device. + +Features: +-------------- +* Simple to setup and use +* Controlled via app-wide keyboard commands +* Highlighting of view frames +* Displays a views origin & size, including distances to edges of main window +* Move and resize view frames during runtime using shortcut keys +* Logging of properties of a view, including subclass properties, actions and targets (see below for an example) +* Logging of accessibility properties — useful for UI automation scripts +* Manually call setNeedsDisplay, setNeedsLayout and reloadData (for UITableView) +* Highlight all view outlines +* Highlight all views that are non-opaque +* Shows warning for views that are positioned on non-integer origins (will cause blurriness when drawn) +* Print a views hierarchy to console (via private method `recursiveDescription`) to console + +Usage +----- + +Before you start make sure the `DEBUG` environment variable is set. DCIntrospect will not run without that set to prevent it being left in for production use. + +Add the `DCIntrospect` class files to your project, add the QuartzCore framework if needed. To start: + + [window makeKeyAndDisplay] + + // always call after makeKeyAndDisplay. + #if TARGET_IPHONE_SIMULATOR + [[DCIntrospect sharedIntrospector] start]; + #endif + +The `#if` to target the simulator is not required but is a good idea to further prevent leaving it on in production code. + +Once setup, simply push the space bar to invoke the introspect or then start clicking on views to get info. You can also tap and drag around the interface. + +A a small demo app is included to test it out. + +Selected keyboard shortcuts +----------------------------------------- + +* Start/Stop: `spacebar` +* Help: `?` +* Print properties and actions of selected view to console: `p` +* Print accessibility properties and actions of selected view to console: `a` +* Toggle all view outlines: `o` +* Toggle highlighting non-opaque views: `O` +* Nudge view left, right, up & down: `4 6 8 2` (use the numeric pad) or `← → ↑ ↓` +* Print out the selected views' new frame to console after nudge/resize: `0` +* Print selected views recursive description to console: `v` + +Logging selected views properties +------------------------------------------------- + +Pushing `p` will log out the available properties about the selected view. DCIntrospect will try to make sense of the values it can and show more useful info. An example from a `UIButton`: + + ** UIRoundedRectButton : UIButton : UIControl : UIView : UIResponder : NSObject ** + + ** UIView properties ** + tag: 1 + frame: {{21, 331}, {278, 37}} | bounds: {{0, 0}, {278, 37}} | center: {160, 349.5} + transform: [1, 0, 0, 1, 0, 0] + autoresizingMask: UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin + autoresizesSubviews: YES + contentMode: UIViewContentModeScaleToFill | contentStretch: {{0, 0}, {1, 1}} backgroundColor: nil + alpha: 1.00 | opaque: NO | hidden: NO | clips to bounds: NO | + clearsContextBeforeDrawing: YES + userInteractionEnabled: YES | multipleTouchEnabled: NO + gestureRecognizers: nil + + ** UIRoundedRectButton properties ** + + ** Targets & Actions ** + target: action: buttonTapped: + +Customizing Key Bindings +-------------------------------------- + +Edit the file `DCIntrospectSettings.h` to change key bindings. You might want to change the key bindings if your using a laptop/wireless keyboard for development. + +License +----------- + +Made available under the MIT License. + +Collaboration +------------- + +If you have any feature requests/bugfixes etc. feel free to help out and send a pull request, or create a new issue.