├── screenshot.jpg ├── CXAMenuItemDemo ├── en.lproj │ └── InfoPlist.strings ├── broom.png ├── camera.png ├── Default.png ├── broom@2x.png ├── camera@2x.png ├── Default@2x.png ├── Default-568h@2x.png ├── CXADemoViewController.h ├── CXAAppDelegate.h ├── CXAMenuItem-Prefix.pch ├── main.m ├── CXAAppDelegate.m ├── CXAMenuItem-Info.plist └── CXADemoViewController.m ├── .gitignore ├── UIMenuItem+CXAImageMenuItem.h ├── LICENSE ├── README.md ├── UIMenuItem+CXAImageMenuItem.m └── CXAMenuItem.xcodeproj └── project.pbxproj /screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gamma/CXAImageMenuItem/master/screenshot.jpg -------------------------------------------------------------------------------- /CXAMenuItemDemo/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /CXAMenuItemDemo/broom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gamma/CXAImageMenuItem/master/CXAMenuItemDemo/broom.png -------------------------------------------------------------------------------- /CXAMenuItemDemo/camera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gamma/CXAImageMenuItem/master/CXAMenuItemDemo/camera.png -------------------------------------------------------------------------------- /CXAMenuItemDemo/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gamma/CXAImageMenuItem/master/CXAMenuItemDemo/Default.png -------------------------------------------------------------------------------- /CXAMenuItemDemo/broom@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gamma/CXAImageMenuItem/master/CXAMenuItemDemo/broom@2x.png -------------------------------------------------------------------------------- /CXAMenuItemDemo/camera@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gamma/CXAImageMenuItem/master/CXAMenuItemDemo/camera@2x.png -------------------------------------------------------------------------------- /CXAMenuItemDemo/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gamma/CXAImageMenuItem/master/CXAMenuItemDemo/Default@2x.png -------------------------------------------------------------------------------- /CXAMenuItemDemo/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gamma/CXAImageMenuItem/master/CXAMenuItemDemo/Default-568h@2x.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.xcworkspacedata 3 | 4 | *.xcuserstate 5 | 6 | CXAMenuItem.xcodeproj/xcuserdata/gamma.xcuserdatad/xcschemes/CXAMenuItem.xcscheme 7 | 8 | CXAMenuItem.xcodeproj/xcuserdata/gamma.xcuserdatad/xcschemes/xcschememanagement.plist 9 | 10 | .DS_Store 11 | -------------------------------------------------------------------------------- /CXAMenuItemDemo/CXADemoViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CXADemoViewController.h 3 | // CXAMenuItem 4 | // 5 | // Created by Chen Xian'an on 1/3/13. 6 | // Copyright (c) 2013 lazyapps. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CXADemoViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /CXAMenuItemDemo/CXAAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // CXAAppDelegate.h 3 | // CXAMenuItem 4 | // 5 | // Created by Chen Xian'an on 1/3/13. 6 | // Copyright (c) 2013 lazyapps. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CXAAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /CXAMenuItemDemo/CXAMenuItem-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'CXAMenuItem' target in the 'CXAMenuItem' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_3_0 8 | #warning "This project uses features only available in iOS SDK 3.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /CXAMenuItemDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // CXAMenuItem 4 | // 5 | // Created by Chen Xian'an on 1/3/13. 6 | // Copyright (c) 2013 lazyapps. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CXAAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([CXAAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /CXAMenuItemDemo/CXAAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // CXAAppDelegate.m 3 | // CXAMenuItem 4 | // 5 | // Created by Chen Xian'an on 1/3/13. 6 | // Copyright (c) 2013 lazyapps. All rights reserved. 7 | // 8 | 9 | #import "CXAAppDelegate.h" 10 | #import "CXADemoViewController.h" 11 | 12 | @implementation CXAAppDelegate 13 | 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 15 | { 16 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 17 | self.window.rootViewController = [[CXADemoViewController alloc] init]; 18 | [self.window makeKeyAndVisible]; 19 | 20 | return YES; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /UIMenuItem+CXAImageMenuItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIMenuItem+CXAImageMenuItem.h 3 | // CXAMenuItem 4 | // 5 | // Created by Chen Xian'an on 1/3/13. 6 | // Copyright (c) 2013 lazyapps. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIMenuItem (CXAImageMenuItem) 12 | 13 | - (id)cxa_initWithTitle:(NSString *)title action:(SEL)action image:(UIImage *)image; 14 | - (id)cxa_initWithTitle:(NSString *)title action:(SEL)action image:(UIImage *)image hidesShadow:(BOOL)hidesShadow; 15 | - (id)cxa_initWithTitle:(NSString *)title font:(UIFont *)font action:(SEL)action; 16 | - (void)cxa_setImage:(UIImage *)image forTitle:(NSString *)title; 17 | - (void)cxa_setImage:(UIImage *)image hidesShadow:(BOOL)hidesShadow forTitle:(NSString *)title; 18 | - (void)cxa_setFont:(UIFont *)font forTitle:(NSString *)title; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 CHEN Xian'an 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /CXAMenuItemDemo/CXAMenuItem-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | im.cxa.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UIMenuItem with Image Support 2 | 3 | ![Image item screenshot](https://raw.github.com/gamma/CXAImageMenuItem/master/screenshot.jpg) 4 | 5 | `UIMenuItem` uses `UILabel` to display its title, that means we can swizzle `-drawTextInRect:` to support image. 6 | 7 | `CXAImageMenuItem` category for `UIMenuItem` is a dirty hack but safe in most cases. 8 | 9 | Make category instead of subclassing `UIMenuItem` gains more flexibility. Yes, I mean you can add image to awsome [PSMenuItem](https://github.com/steipete/PSMenuItem) too! 10 | 11 | ## How to use 12 | 13 | Add `UIMenuItem+CXAImageMenuItem.h` and `UIMenuItem+CXAImageMenuItem.m` to your project. 14 | 15 | The method names describe all. Default draws shadow as the text title. If you want to hide shadow, set `hidesShadow` to `YES`. 16 | 17 | - (id)cxa_initWithTitle:(NSString *)title action:(SEL)action image:(UIImage *)image; 18 | - (id)cxa_initWithTitle:(NSString *)title action:(SEL)action image:(UIImage *)image hidesShadow:(BOOL)hidesShadow; 19 | - (void)cxa_setImage:(UIImage *)image forTitle:(NSString *)title; 20 | - (void)cxa_setImage:(UIImage *)image hidesShadow:(BOOL)hidesShadow forTitle:(NSString *)title; 21 | 22 | # additional Font settings 23 | - (id)cxa_initWithTitle:(NSString *)title font:(UIFont *)font action:(SEL)action; 24 | - (void)cxa_setFont:(UIFont *)font forTitle:(NSString *)title; 25 | 26 | 27 | ## Limitation 28 | 29 | `CXAImageMenuItem` uses `UIMenuItem`'s title to map related image since there is no any other clue of `UIMenuItem` I can find to connect to `UILabel`. 30 | 31 | When using an image you cannot use the `UIFont` option. 32 | 33 | ## Creator 34 | 35 | * GitHub: 36 | * Twitter: [@_cxa](https://twitter.com/_cxa) 37 | * Apps available in App Store: 38 | 39 | ### UIFont extension 40 | 41 | * GitHub: 42 | * Twitter: [@gammaproduction](https://twitter.com/gammaproduction) 43 | 44 | ## License 45 | 46 | Under the MIT license. See the LICENSE file for more information. 47 | -------------------------------------------------------------------------------- /CXAMenuItemDemo/CXADemoViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CXADemoViewController.m 3 | // CXAMenuItem 4 | // 5 | // Created by Chen Xian'an on 1/3/13. 6 | // Copyright (c) 2013 lazyapps. All rights reserved. 7 | // 8 | 9 | #import "CXADemoViewController.h" 10 | #import "UIMenuItem+CXAImageMenuItem.h" 11 | 12 | @interface CXADemoViewController(){ 13 | UIButton *_button; 14 | UILabel *_label; 15 | } 16 | 17 | - (void)pressme:(id)sender; 18 | - (void)cameraAction:(id)sender; 19 | - (void)broomAction:(id)sender; 20 | - (void)textAction:(id)sender; 21 | 22 | @end 23 | 24 | @implementation CXADemoViewController 25 | 26 | - (id)init 27 | { 28 | if (self = [super initWithNibName:nil bundle:nil]){ 29 | 30 | } 31 | 32 | return self; 33 | } 34 | 35 | - (void)loadView 36 | { 37 | [super loadView]; 38 | 39 | self.view.backgroundColor = [UIColor darkGrayColor]; 40 | _button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 41 | [_button setTitle:NSLocalizedString(@"Press Me", nil) forState:UIControlStateNormal]; 42 | [_button addTarget:self action:@selector(pressme:) forControlEvents:UIControlEventTouchUpInside]; 43 | [self.view addSubview:_button]; 44 | _label = [[UILabel alloc] initWithFrame:CGRectZero]; 45 | _label.font = [UIFont fontWithName:@"AvenirNext-Bold" size:15.]; 46 | _label.textAlignment = NSTextAlignmentCenter; 47 | _label.textColor = [UIColor whiteColor]; 48 | _label.backgroundColor = [UIColor clearColor]; 49 | _label.shadowColor = [[UIColor blackColor] colorWithAlphaComponent:.75]; 50 | _label.shadowOffset = CGSizeMake(0, -1); 51 | _label.numberOfLines = 0; 52 | _label.text = NSLocalizedString(@"Under MIT License.\n(c) 2013 CHEN Xian'an\n", nil); 53 | [self.view addSubview:_label]; 54 | UIMenuItem *cameraItem = [[UIMenuItem alloc] initWithTitle:nil action:@selector(cameraAction:)]; 55 | [cameraItem cxa_setImage:[UIImage imageNamed:@"camera"] hidesShadow:YES forTitle:NSLocalizedString(@"Camera", nil)]; 56 | UIMenuItem *broomItem = [[UIMenuItem alloc] cxa_initWithTitle:NSLocalizedString(@"Broom", nil) action:@selector(broomAction:) image:[UIImage imageNamed:@"broom"]]; 57 | UIMenuItem *textItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"No Image", nil) action:@selector(textAction:)]; 58 | 59 | UIMenuItem *attributedTextItem = [[UIMenuItem alloc] cxa_initWithTitle:NSLocalizedString(@"Font", nil) font:[UIFont fontWithName:@"Chalkduster" size:17] action:@selector(textAction:)]; 60 | 61 | [UIMenuController sharedMenuController].menuItems = @[cameraItem, broomItem, textItem, attributedTextItem]; 62 | } 63 | 64 | - (void)viewWillLayoutSubviews 65 | { 66 | [_button sizeToFit]; 67 | _button.center = self.view.center; 68 | [_label sizeToFit]; 69 | CGRect r = _label.bounds; 70 | r.origin.y = CGRectGetHeight(self.view.bounds) - CGRectGetHeight(r) - 10; 71 | r.size.width = CGRectGetWidth(self.view.bounds); 72 | _label.frame = r; 73 | } 74 | 75 | #pragma mark - 76 | - (BOOL)canBecomeFirstResponder 77 | { 78 | return YES; 79 | } 80 | 81 | - (BOOL)canPerformAction:(SEL)action 82 | withSender:(id)sender 83 | { 84 | if (action == @selector(cameraAction:) || 85 | action == @selector(broomAction:) || 86 | action == @selector(textAction:)) 87 | return YES; 88 | 89 | return [super canPerformAction:action withSender:sender]; 90 | } 91 | 92 | #pragma mark - privates 93 | - (void)pressme:(id)sender 94 | { 95 | [[UIMenuController sharedMenuController] setTargetRect:[sender frame] inView:self.view]; 96 | [[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES]; 97 | } 98 | 99 | - (void)cameraAction:(id)sender 100 | { 101 | [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Camera Item Pressed", nil) message:nil delegate:nil cancelButtonTitle:NSLocalizedString(@"Dismiss", nil) otherButtonTitles:nil] show]; 102 | } 103 | 104 | - (void)broomAction:(id)sender 105 | { 106 | [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Broom Item Pressed", nil) message:nil delegate:nil cancelButtonTitle:NSLocalizedString(@"Dismiss", nil) otherButtonTitles:nil] show]; 107 | } 108 | 109 | - (void)textAction:(id)sender 110 | { 111 | [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Text Item Pressed", nil) message:nil delegate:nil cancelButtonTitle:NSLocalizedString(@"Dismiss", nil) otherButtonTitles:nil] show]; 112 | } 113 | 114 | @end 115 | -------------------------------------------------------------------------------- /UIMenuItem+CXAImageMenuItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIMenuItem+CXAImageMenuItem.m 3 | // CXAMenuItem 4 | // 5 | // Created by Chen Xian'an on 1/3/13. 6 | // Copyright (c) 2013 lazyapps. All rights reserved. 7 | // 8 | 9 | #import "UIMenuItem+CXAImageMenuItem.h" 10 | #import 11 | 12 | #define INVISIBLE_IDENTIFER @"\uFEFF\u200B" 13 | 14 | @interface CXAImageMenuItem : NSObject 15 | @property (nonatomic, strong) UIImage * image; 16 | @property (nonatomic, assign) BOOL hidesShadow; 17 | @property (nonatomic, strong) UIFont *font; 18 | @end 19 | 20 | @implementation CXAImageMenuItem 21 | @end 22 | 23 | static NSMutableDictionary *titleImagePairs; 24 | 25 | @interface NSString (CXAImageMenuItem) 26 | 27 | - (NSString *)cxa_stringByWrappingInvisibleIdentifiers; 28 | - (BOOL)cxa_doesWrapInvisibleIdentifiers; 29 | 30 | @end 31 | 32 | #pragma mark - 33 | @implementation UIMenuItem (CXAImageMenuItem) 34 | 35 | + (void)load 36 | { 37 | static dispatch_once_t once; 38 | dispatch_once(&once, ^{ 39 | titleImagePairs = [@{} mutableCopy]; 40 | }); 41 | } 42 | 43 | + (void)dealloc 44 | { 45 | titleImagePairs = nil; 46 | } 47 | 48 | - (id)cxa_initWithTitle:(NSString *)title 49 | action:(SEL)action 50 | image:(UIImage *)image 51 | { 52 | return [self cxa_initWithTitle:title action:action image:image hidesShadow:NO]; 53 | } 54 | 55 | - (id)cxa_initWithTitle:(NSString *)title 56 | action:(SEL)action 57 | image:(UIImage *)image 58 | hidesShadow:(BOOL)hidesShadow 59 | { 60 | if ([self initWithTitle:nil action:action] && 61 | title){ 62 | [self cxa_setImage:image hidesShadow:hidesShadow forTitle:title]; 63 | } 64 | 65 | return self; 66 | 67 | } 68 | 69 | - (id)cxa_initWithTitle:(NSString *)title 70 | font:(UIFont *)font 71 | action:(SEL)action 72 | { 73 | if ([self initWithTitle:nil action:action] ){ 74 | [self cxa_setFont:font forTitle:title]; 75 | } 76 | 77 | return self; 78 | } 79 | 80 | - (void)cxa_setImage:(UIImage *)image 81 | forTitle:(NSString *)title 82 | { 83 | [self cxa_setImage:image hidesShadow:NO forTitle:title]; 84 | } 85 | 86 | - (void)cxa_setImage:(UIImage *)image 87 | hidesShadow:(BOOL)hidesShadow 88 | forTitle:(NSString *)title 89 | { 90 | if (!title) 91 | @throw [NSException exceptionWithName:@"CXAImageMenuItem" reason:@"title can't be nil" userInfo:nil]; 92 | 93 | title = [title cxa_stringByWrappingInvisibleIdentifiers]; 94 | CXAImageMenuItem *item = titleImagePairs[title]; 95 | if (!item) 96 | { 97 | item = [[CXAImageMenuItem alloc] init]; 98 | titleImagePairs[title] = item; 99 | } 100 | 101 | self.title = title; 102 | item.image = image; 103 | item.hidesShadow = hidesShadow; 104 | } 105 | 106 | - (void)cxa_setFont:(UIFont *)font 107 | forTitle:(NSString *)title 108 | { 109 | if (!title) 110 | @throw [NSException exceptionWithName:@"CXAImageMenuItem" reason:@"title can't be nil" userInfo:nil]; 111 | 112 | title = [title cxa_stringByWrappingInvisibleIdentifiers]; 113 | CXAImageMenuItem *item = titleImagePairs[title]; 114 | if (!item) 115 | { 116 | item = [[CXAImageMenuItem alloc] init]; 117 | titleImagePairs[title] = item; 118 | } 119 | 120 | self.title = title; 121 | item.font = font; 122 | } 123 | 124 | @end 125 | 126 | #pragma mark - 127 | @implementation NSString (CXAImageMenuItem) 128 | 129 | - (NSString *)cxa_stringByWrappingInvisibleIdentifiers 130 | { 131 | return [NSString stringWithFormat:@"%@%@%@", INVISIBLE_IDENTIFER, self, INVISIBLE_IDENTIFER]; 132 | } 133 | 134 | - (BOOL)cxa_doesWrapInvisibleIdentifiers 135 | { 136 | BOOL doesStartMatch = [self rangeOfString:INVISIBLE_IDENTIFER options:NSAnchoredSearch].location != NSNotFound; 137 | if (!doesStartMatch) 138 | return NO; 139 | 140 | BOOL doesEndMatch = [self rangeOfString:INVISIBLE_IDENTIFER options:NSAnchoredSearch | NSBackwardsSearch].location != NSNotFound; 141 | return doesEndMatch; 142 | } 143 | 144 | @end 145 | 146 | #pragma mark - 147 | 148 | static void (*origDrawTextInRect)(id, SEL, CGRect); 149 | static void newDrawTextInRect(id, SEL, CGRect); 150 | static void (*origSetFrame)(id, SEL, CGRect); 151 | static void newSetFrame(id, SEL, CGRect); 152 | static CGSize (*origSizeWithFont)(id, SEL, id); 153 | static CGSize newSizeWithFont(id, SEL, id); 154 | static void (*origSetText)(id, SEL, NSString*); 155 | static void newSetText(id, SEL, NSString*); 156 | 157 | @interface UILabel (CXAImageMenuItem) @end 158 | 159 | @implementation UILabel (CXAImageMenuItem) 160 | 161 | + (void)load 162 | { 163 | Method origMethod = class_getInstanceMethod(self, @selector(drawTextInRect:)); 164 | origDrawTextInRect = (void *)method_getImplementation(origMethod); 165 | if (!class_addMethod(self, @selector(drawTextInRect:), (IMP)newDrawTextInRect, method_getTypeEncoding(origMethod))) 166 | method_setImplementation(origMethod, (IMP)newDrawTextInRect); 167 | 168 | origMethod = class_getInstanceMethod(self, @selector(setFrame:)); 169 | origSetFrame = (void *)method_getImplementation(origMethod); 170 | if (!class_addMethod(self, @selector(setFrame:), (IMP)newSetFrame, method_getTypeEncoding(origMethod))) 171 | method_setImplementation(origMethod, (IMP)newSetFrame); 172 | 173 | origMethod = class_getInstanceMethod([NSString class], @selector(sizeWithFont:)); 174 | origSizeWithFont = (void *)method_getImplementation(origMethod); 175 | if (!class_addMethod([NSString class], @selector(sizeWithFont:), (IMP)newSizeWithFont, method_getTypeEncoding(origMethod))) 176 | method_setImplementation(origMethod, (IMP)newSizeWithFont); 177 | 178 | origMethod = class_getInstanceMethod([UILabel class], @selector(setText:)); 179 | origSetText = (void *)method_getImplementation(origMethod); 180 | if (!class_addMethod([UILabel class], @selector(setText:), (IMP)newSetText, method_getTypeEncoding(origMethod))) 181 | method_setImplementation(origMethod, (IMP)newSetText); 182 | } 183 | 184 | @end 185 | 186 | static void newDrawTextInRect(UILabel *self, SEL _cmd, CGRect rect) 187 | { 188 | if (![self.text cxa_doesWrapInvisibleIdentifiers] || 189 | !((CXAImageMenuItem *)titleImagePairs[self.text]).image){ 190 | origDrawTextInRect(self, @selector(drawTextInRect:), rect); 191 | return; 192 | } 193 | 194 | CXAImageMenuItem *item = titleImagePairs[self.text]; 195 | CGSize size = item.image.size; 196 | CGPoint point = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)); 197 | point.x -= size.width/2; 198 | point.y -= size.height/2; 199 | point.x = ceilf(point.x); 200 | point.y = ceilf(point.y); 201 | 202 | BOOL drawsShadow = !item.hidesShadow; 203 | CGContextRef context; 204 | if (drawsShadow){ 205 | context = UIGraphicsGetCurrentContext(); 206 | CGContextSaveGState(context); 207 | CGContextSetShadowWithColor(context, CGSizeMake(0, -1), 0, [[UIColor blackColor] colorWithAlphaComponent:1./3.].CGColor); 208 | } 209 | 210 | [item.image drawAtPoint:point]; 211 | if (drawsShadow) 212 | CGContextRestoreGState(context); 213 | } 214 | 215 | static void newSetFrame(UILabel *self, SEL _cmd, CGRect rect) 216 | { 217 | if ([self.text cxa_doesWrapInvisibleIdentifiers]) 218 | rect = self.superview.bounds; 219 | 220 | origSetFrame(self, @selector(setFrame:), rect); 221 | } 222 | 223 | static CGSize newSizeWithFont(NSString *self, SEL _cmd, UIFont *font) 224 | { 225 | if ([self cxa_doesWrapInvisibleIdentifiers] && 226 | ((CXAImageMenuItem *)titleImagePairs[self]).image ) 227 | return [((CXAImageMenuItem *)titleImagePairs[self]).image size]; 228 | 229 | if ([self cxa_doesWrapInvisibleIdentifiers] && 230 | ((CXAImageMenuItem *)titleImagePairs[self]).font ) 231 | return origSizeWithFont(self, _cmd, ((CXAImageMenuItem *)titleImagePairs[self]).font); 232 | 233 | return origSizeWithFont(self, _cmd, font); 234 | } 235 | 236 | static void newSetText(UILabel *self, SEL _cmd, NSString *text) 237 | { 238 | if ([self.text cxa_doesWrapInvisibleIdentifiers] && 239 | ((CXAImageMenuItem *)titleImagePairs[self.text]).font) 240 | { 241 | self.font = ((CXAImageMenuItem *)titleImagePairs[self.text]).font; 242 | } 243 | 244 | return origSetText(self, _cmd, text); 245 | } 246 | -------------------------------------------------------------------------------- /CXAMenuItem.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | E058E156169493BD009A0BCE /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E058E155169493BD009A0BCE /* UIKit.framework */; }; 11 | E058E158169493BD009A0BCE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E058E157169493BD009A0BCE /* Foundation.framework */; }; 12 | E058E15A169493BD009A0BCE /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E058E159169493BD009A0BCE /* CoreGraphics.framework */; }; 13 | E058E160169493BD009A0BCE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = E058E15E169493BD009A0BCE /* InfoPlist.strings */; }; 14 | E058E162169493BD009A0BCE /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E058E161169493BD009A0BCE /* main.m */; }; 15 | E058E166169493BD009A0BCE /* CXAAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E058E165169493BD009A0BCE /* CXAAppDelegate.m */; }; 16 | E058E168169493BD009A0BCE /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = E058E167169493BD009A0BCE /* Default.png */; }; 17 | E058E16A169493BD009A0BCE /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E058E169169493BD009A0BCE /* Default@2x.png */; }; 18 | E058E16C169493BD009A0BCE /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E058E16B169493BD009A0BCE /* Default-568h@2x.png */; }; 19 | E058E17516949402009A0BCE /* CXADemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E058E17416949402009A0BCE /* CXADemoViewController.m */; }; 20 | E058E18A1694A40D009A0BCE /* broom.png in Resources */ = {isa = PBXBuildFile; fileRef = E058E1861694A40D009A0BCE /* broom.png */; }; 21 | E058E18B1694A40D009A0BCE /* broom@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E058E1871694A40D009A0BCE /* broom@2x.png */; }; 22 | E058E18C1694A40D009A0BCE /* camera.png in Resources */ = {isa = PBXBuildFile; fileRef = E058E1881694A40D009A0BCE /* camera.png */; }; 23 | E058E18D1694A40D009A0BCE /* camera@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E058E1891694A40D009A0BCE /* camera@2x.png */; }; 24 | E058E1A0169583B2009A0BCE /* UIMenuItem+CXAImageMenuItem.m in Sources */ = {isa = PBXBuildFile; fileRef = E058E19F169583B2009A0BCE /* UIMenuItem+CXAImageMenuItem.m */; }; 25 | /* End PBXBuildFile section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | E058E151169493BD009A0BCE /* CXAMenuItem.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CXAMenuItem.app; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | E058E155169493BD009A0BCE /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 30 | E058E157169493BD009A0BCE /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 31 | E058E159169493BD009A0BCE /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 32 | E058E15D169493BD009A0BCE /* CXAMenuItem-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "CXAMenuItem-Info.plist"; sourceTree = ""; }; 33 | E058E15F169493BD009A0BCE /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 34 | E058E161169493BD009A0BCE /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 35 | E058E163169493BD009A0BCE /* CXAMenuItem-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CXAMenuItem-Prefix.pch"; sourceTree = ""; }; 36 | E058E164169493BD009A0BCE /* CXAAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CXAAppDelegate.h; sourceTree = ""; }; 37 | E058E165169493BD009A0BCE /* CXAAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CXAAppDelegate.m; sourceTree = ""; }; 38 | E058E167169493BD009A0BCE /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 39 | E058E169169493BD009A0BCE /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 40 | E058E16B169493BD009A0BCE /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 41 | E058E17316949402009A0BCE /* CXADemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CXADemoViewController.h; sourceTree = ""; }; 42 | E058E17416949402009A0BCE /* CXADemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CXADemoViewController.m; sourceTree = ""; }; 43 | E058E1861694A40D009A0BCE /* broom.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = broom.png; sourceTree = ""; }; 44 | E058E1871694A40D009A0BCE /* broom@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "broom@2x.png"; sourceTree = ""; }; 45 | E058E1881694A40D009A0BCE /* camera.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = camera.png; sourceTree = ""; }; 46 | E058E1891694A40D009A0BCE /* camera@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "camera@2x.png"; sourceTree = ""; }; 47 | E058E19E169583B2009A0BCE /* UIMenuItem+CXAImageMenuItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIMenuItem+CXAImageMenuItem.h"; sourceTree = ""; }; 48 | E058E19F169583B2009A0BCE /* UIMenuItem+CXAImageMenuItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIMenuItem+CXAImageMenuItem.m"; sourceTree = ""; }; 49 | /* End PBXFileReference section */ 50 | 51 | /* Begin PBXFrameworksBuildPhase section */ 52 | E058E14E169493BD009A0BCE /* Frameworks */ = { 53 | isa = PBXFrameworksBuildPhase; 54 | buildActionMask = 2147483647; 55 | files = ( 56 | E058E156169493BD009A0BCE /* UIKit.framework in Frameworks */, 57 | E058E158169493BD009A0BCE /* Foundation.framework in Frameworks */, 58 | E058E15A169493BD009A0BCE /* CoreGraphics.framework in Frameworks */, 59 | ); 60 | runOnlyForDeploymentPostprocessing = 0; 61 | }; 62 | /* End PBXFrameworksBuildPhase section */ 63 | 64 | /* Begin PBXGroup section */ 65 | E058E146169493BD009A0BCE = { 66 | isa = PBXGroup; 67 | children = ( 68 | E058E172169493DB009A0BCE /* CXAMenuItem */, 69 | E058E15B169493BD009A0BCE /* CXAMenuItemDemo */, 70 | E058E154169493BD009A0BCE /* Frameworks */, 71 | E058E152169493BD009A0BCE /* Products */, 72 | ); 73 | sourceTree = ""; 74 | }; 75 | E058E152169493BD009A0BCE /* Products */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | E058E151169493BD009A0BCE /* CXAMenuItem.app */, 79 | ); 80 | name = Products; 81 | sourceTree = ""; 82 | }; 83 | E058E154169493BD009A0BCE /* Frameworks */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | E058E155169493BD009A0BCE /* UIKit.framework */, 87 | E058E157169493BD009A0BCE /* Foundation.framework */, 88 | E058E159169493BD009A0BCE /* CoreGraphics.framework */, 89 | ); 90 | name = Frameworks; 91 | sourceTree = ""; 92 | }; 93 | E058E15B169493BD009A0BCE /* CXAMenuItemDemo */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | E058E164169493BD009A0BCE /* CXAAppDelegate.h */, 97 | E058E165169493BD009A0BCE /* CXAAppDelegate.m */, 98 | E058E17316949402009A0BCE /* CXADemoViewController.h */, 99 | E058E17416949402009A0BCE /* CXADemoViewController.m */, 100 | E058E15C169493BD009A0BCE /* Supporting Files */, 101 | ); 102 | path = CXAMenuItemDemo; 103 | sourceTree = ""; 104 | }; 105 | E058E15C169493BD009A0BCE /* Supporting Files */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | E058E1861694A40D009A0BCE /* broom.png */, 109 | E058E1871694A40D009A0BCE /* broom@2x.png */, 110 | E058E1881694A40D009A0BCE /* camera.png */, 111 | E058E1891694A40D009A0BCE /* camera@2x.png */, 112 | E058E15D169493BD009A0BCE /* CXAMenuItem-Info.plist */, 113 | E058E15E169493BD009A0BCE /* InfoPlist.strings */, 114 | E058E161169493BD009A0BCE /* main.m */, 115 | E058E163169493BD009A0BCE /* CXAMenuItem-Prefix.pch */, 116 | E058E167169493BD009A0BCE /* Default.png */, 117 | E058E169169493BD009A0BCE /* Default@2x.png */, 118 | E058E16B169493BD009A0BCE /* Default-568h@2x.png */, 119 | ); 120 | name = "Supporting Files"; 121 | sourceTree = ""; 122 | }; 123 | E058E172169493DB009A0BCE /* CXAMenuItem */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | E058E19E169583B2009A0BCE /* UIMenuItem+CXAImageMenuItem.h */, 127 | E058E19F169583B2009A0BCE /* UIMenuItem+CXAImageMenuItem.m */, 128 | ); 129 | name = CXAMenuItem; 130 | sourceTree = ""; 131 | }; 132 | /* End PBXGroup section */ 133 | 134 | /* Begin PBXNativeTarget section */ 135 | E058E150169493BD009A0BCE /* CXAMenuItem */ = { 136 | isa = PBXNativeTarget; 137 | buildConfigurationList = E058E16F169493BD009A0BCE /* Build configuration list for PBXNativeTarget "CXAMenuItem" */; 138 | buildPhases = ( 139 | E058E14D169493BD009A0BCE /* Sources */, 140 | E058E14E169493BD009A0BCE /* Frameworks */, 141 | E058E14F169493BD009A0BCE /* Resources */, 142 | ); 143 | buildRules = ( 144 | ); 145 | dependencies = ( 146 | ); 147 | name = CXAMenuItem; 148 | productName = CXAMenuItem; 149 | productReference = E058E151169493BD009A0BCE /* CXAMenuItem.app */; 150 | productType = "com.apple.product-type.application"; 151 | }; 152 | /* End PBXNativeTarget section */ 153 | 154 | /* Begin PBXProject section */ 155 | E058E148169493BD009A0BCE /* Project object */ = { 156 | isa = PBXProject; 157 | attributes = { 158 | CLASSPREFIX = CXA; 159 | LastUpgradeCheck = 0450; 160 | ORGANIZATIONNAME = lazyapps; 161 | }; 162 | buildConfigurationList = E058E14B169493BD009A0BCE /* Build configuration list for PBXProject "CXAMenuItem" */; 163 | compatibilityVersion = "Xcode 3.2"; 164 | developmentRegion = English; 165 | hasScannedForEncodings = 0; 166 | knownRegions = ( 167 | en, 168 | ); 169 | mainGroup = E058E146169493BD009A0BCE; 170 | productRefGroup = E058E152169493BD009A0BCE /* Products */; 171 | projectDirPath = ""; 172 | projectRoot = ""; 173 | targets = ( 174 | E058E150169493BD009A0BCE /* CXAMenuItem */, 175 | ); 176 | }; 177 | /* End PBXProject section */ 178 | 179 | /* Begin PBXResourcesBuildPhase section */ 180 | E058E14F169493BD009A0BCE /* Resources */ = { 181 | isa = PBXResourcesBuildPhase; 182 | buildActionMask = 2147483647; 183 | files = ( 184 | E058E160169493BD009A0BCE /* InfoPlist.strings in Resources */, 185 | E058E168169493BD009A0BCE /* Default.png in Resources */, 186 | E058E16A169493BD009A0BCE /* Default@2x.png in Resources */, 187 | E058E16C169493BD009A0BCE /* Default-568h@2x.png in Resources */, 188 | E058E18A1694A40D009A0BCE /* broom.png in Resources */, 189 | E058E18B1694A40D009A0BCE /* broom@2x.png in Resources */, 190 | E058E18C1694A40D009A0BCE /* camera.png in Resources */, 191 | E058E18D1694A40D009A0BCE /* camera@2x.png in Resources */, 192 | ); 193 | runOnlyForDeploymentPostprocessing = 0; 194 | }; 195 | /* End PBXResourcesBuildPhase section */ 196 | 197 | /* Begin PBXSourcesBuildPhase section */ 198 | E058E14D169493BD009A0BCE /* Sources */ = { 199 | isa = PBXSourcesBuildPhase; 200 | buildActionMask = 2147483647; 201 | files = ( 202 | E058E162169493BD009A0BCE /* main.m in Sources */, 203 | E058E166169493BD009A0BCE /* CXAAppDelegate.m in Sources */, 204 | E058E17516949402009A0BCE /* CXADemoViewController.m in Sources */, 205 | E058E1A0169583B2009A0BCE /* UIMenuItem+CXAImageMenuItem.m in Sources */, 206 | ); 207 | runOnlyForDeploymentPostprocessing = 0; 208 | }; 209 | /* End PBXSourcesBuildPhase section */ 210 | 211 | /* Begin PBXVariantGroup section */ 212 | E058E15E169493BD009A0BCE /* InfoPlist.strings */ = { 213 | isa = PBXVariantGroup; 214 | children = ( 215 | E058E15F169493BD009A0BCE /* en */, 216 | ); 217 | name = InfoPlist.strings; 218 | sourceTree = ""; 219 | }; 220 | /* End PBXVariantGroup section */ 221 | 222 | /* Begin XCBuildConfiguration section */ 223 | E058E16D169493BD009A0BCE /* Debug */ = { 224 | isa = XCBuildConfiguration; 225 | buildSettings = { 226 | ALWAYS_SEARCH_USER_PATHS = NO; 227 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 228 | CLANG_CXX_LIBRARY = "libc++"; 229 | CLANG_ENABLE_OBJC_ARC = YES; 230 | CLANG_WARN_EMPTY_BODY = YES; 231 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 232 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 233 | COPY_PHASE_STRIP = NO; 234 | GCC_C_LANGUAGE_STANDARD = gnu99; 235 | GCC_DYNAMIC_NO_PIC = NO; 236 | GCC_OPTIMIZATION_LEVEL = 0; 237 | GCC_PREPROCESSOR_DEFINITIONS = ( 238 | "DEBUG=1", 239 | "$(inherited)", 240 | ); 241 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 242 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 243 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 244 | GCC_WARN_UNUSED_VARIABLE = YES; 245 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 246 | ONLY_ACTIVE_ARCH = YES; 247 | SDKROOT = iphoneos; 248 | }; 249 | name = Debug; 250 | }; 251 | E058E16E169493BD009A0BCE /* Release */ = { 252 | isa = XCBuildConfiguration; 253 | buildSettings = { 254 | ALWAYS_SEARCH_USER_PATHS = NO; 255 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 256 | CLANG_CXX_LIBRARY = "libc++"; 257 | CLANG_ENABLE_OBJC_ARC = YES; 258 | CLANG_WARN_EMPTY_BODY = YES; 259 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 260 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 261 | COPY_PHASE_STRIP = YES; 262 | GCC_C_LANGUAGE_STANDARD = gnu99; 263 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 264 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 265 | GCC_WARN_UNUSED_VARIABLE = YES; 266 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 267 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 268 | SDKROOT = iphoneos; 269 | VALIDATE_PRODUCT = YES; 270 | }; 271 | name = Release; 272 | }; 273 | E058E170169493BD009A0BCE /* Debug */ = { 274 | isa = XCBuildConfiguration; 275 | buildSettings = { 276 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 277 | INFOPLIST_FILE = "$(SRCROOT)/CXAMenuItemDemo/CXAMenuItem-Info.plist"; 278 | PRODUCT_NAME = "$(TARGET_NAME)"; 279 | WRAPPER_EXTENSION = app; 280 | }; 281 | name = Debug; 282 | }; 283 | E058E171169493BD009A0BCE /* Release */ = { 284 | isa = XCBuildConfiguration; 285 | buildSettings = { 286 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 287 | INFOPLIST_FILE = "$(SRCROOT)/CXAMenuItemDemo/CXAMenuItem-Info.plist"; 288 | PRODUCT_NAME = "$(TARGET_NAME)"; 289 | WRAPPER_EXTENSION = app; 290 | }; 291 | name = Release; 292 | }; 293 | /* End XCBuildConfiguration section */ 294 | 295 | /* Begin XCConfigurationList section */ 296 | E058E14B169493BD009A0BCE /* Build configuration list for PBXProject "CXAMenuItem" */ = { 297 | isa = XCConfigurationList; 298 | buildConfigurations = ( 299 | E058E16D169493BD009A0BCE /* Debug */, 300 | E058E16E169493BD009A0BCE /* Release */, 301 | ); 302 | defaultConfigurationIsVisible = 0; 303 | defaultConfigurationName = Release; 304 | }; 305 | E058E16F169493BD009A0BCE /* Build configuration list for PBXNativeTarget "CXAMenuItem" */ = { 306 | isa = XCConfigurationList; 307 | buildConfigurations = ( 308 | E058E170169493BD009A0BCE /* Debug */, 309 | E058E171169493BD009A0BCE /* Release */, 310 | ); 311 | defaultConfigurationIsVisible = 0; 312 | defaultConfigurationName = Release; 313 | }; 314 | /* End XCConfigurationList section */ 315 | }; 316 | rootObject = E058E148169493BD009A0BCE /* Project object */; 317 | } 318 | --------------------------------------------------------------------------------