├── .gitignore ├── .travis.yml ├── Classes └── ios │ ├── FUIAlertView.h │ ├── FUIAlertView.m │ ├── FUIButton.h │ ├── FUIButton.m │ ├── FUICellBackgroundView.h │ ├── FUICellBackgroundView.m │ ├── FUIPopoverBackgroundView.h │ ├── FUIPopoverBackgroundView.m │ ├── FUISegmentedControl.h │ ├── FUISegmentedControl.m │ ├── FUISwitch.h │ ├── FUISwitch.m │ ├── FUITextField.h │ ├── FUITextField.m │ ├── FlatUIKit.h │ ├── NSString+Icons.h │ ├── NSString+Icons.m │ ├── UIBarButtonItem+FlatUI.h │ ├── UIBarButtonItem+FlatUI.m │ ├── UIColor+FlatUI.h │ ├── UIColor+FlatUI.m │ ├── UIFont+FlatUI.h │ ├── UIFont+FlatUI.m │ ├── UIImage+FlatUI.h │ ├── UIImage+FlatUI.m │ ├── UINavigationBar+FlatUI.h │ ├── UINavigationBar+FlatUI.m │ ├── UIPopoverController+FlatUI.h │ ├── UIPopoverController+FlatUI.m │ ├── UIProgressView+FlatUI.h │ ├── UIProgressView+FlatUI.m │ ├── UISlider+FlatUI.h │ ├── UISlider+FlatUI.m │ ├── UIStepper+FlatUI.h │ ├── UIStepper+FlatUI.m │ ├── UITabBar+FlatUI.h │ ├── UITabBar+FlatUI.m │ ├── UITableViewCell+FlatUI.h │ ├── UITableViewCell+FlatUI.m │ ├── UIToolbar+FlatUI.h │ └── UIToolbar+FlatUI.m ├── Example ├── .gitignore ├── FlatUIKitExample.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── FlatUIKitExample │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Default-568h@2x.png │ ├── Default.png │ ├── Default@2x.png │ ├── FlatUIKitExample-Info.plist │ ├── FlatUIKitExample-Prefix.pch │ ├── IconViewController.h │ ├── IconViewController.m │ ├── TableViewController.h │ ├── TableViewController.m │ ├── ViewController.h │ ├── ViewController.m │ ├── ViewController_iPad.xib │ ├── ViewController_iPhone.xib │ ├── en.lproj │ │ └── InfoPlist.strings │ └── main.m └── README images │ ├── fuialertview-small.gif │ ├── fuialertview.gif │ ├── fuibutton-small.gif │ ├── fuibutton.gif │ ├── fuinavbar-small.gif │ ├── fuipopovercontroller-small.gif │ ├── fuislider-small.gif │ ├── fuistepper-small.gif │ ├── fuiswitch-small.gif │ ├── fuiswitch.gif │ ├── fuitableview-small.png │ ├── fuitableview.png │ └── fuitextfield-small.gif ├── FlatUIKit.podspec ├── LICENSE ├── README.markdown ├── Rakefile ├── Resources ├── Lato-Bold.ttf ├── Lato-Italic.ttf ├── Lato-Light.ttf ├── Lato-Regular.ttf └── flat-ui-icons-regular.ttf └── Tests ├── FUIKitTests.xcodeproj ├── project.pbxproj └── xcshareddata │ └── xcschemes │ └── FUIKitTests.xcscheme ├── FUIKitTests ├── Default-568h@2x.png ├── Default.png ├── Default@2x.png ├── FUIAppDelegate.h ├── FUIAppDelegate.m ├── FUIKitTests-Info.plist ├── FUIKitTests-Prefix.pch ├── en.lproj │ └── InfoPlist.strings └── main.m ├── FUIKitTestsTests ├── FUIAlertViewTests.m ├── FUIKitTestsTests-Info.plist ├── FUITableViewCellTests.m ├── SenTestCase+FUITestHelpers.h ├── SenTestCase+FUITestHelpers.m └── en.lproj │ └── InfoPlist.strings ├── Podfile └── Schemes └── FUIKitTests.xcscheme /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.swp 3 | *~.nib 4 | .idea 5 | build/ 6 | bin/ 7 | .idea/ 8 | *.pbxuser 9 | *.perspective 10 | *.perspectivev3 11 | xcuserdata 12 | objects 13 | Settings.bundle 14 | Pods 15 | Podfile.lock 16 | *.xcworkspace 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | before_install: 3 | - brew update 4 | - brew install xctool --HEAD 5 | - gem install cocoapods 6 | - cd Tests && pod install && cd $TRAVIS_BUILD_DIR 7 | script: "rake test" 8 | 9 | -------------------------------------------------------------------------------- /Classes/ios/FUIAlertView.h: -------------------------------------------------------------------------------- 1 | // 2 | // FUIAlertView.h 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/7/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FUITextField.h" 11 | 12 | typedef NS_ENUM(NSInteger, FUIAlertViewStyle) { 13 | FUIAlertViewStyleDefault = 0, 14 | FUIAlertViewStyleSecureTextInput, 15 | FUIAlertViewStylePlainTextInput, 16 | FUIAlertViewStyleLoginAndPasswordInput 17 | }; 18 | 19 | @protocol FUIAlertViewDelegate; 20 | 21 | @interface FUIAlertView : UIView 22 | 23 | - (id)initWithTitle:(NSString *)title 24 | message:(NSString *)message 25 | delegate:(id)delegate 26 | cancelButtonTitle:(NSString *)cancelButtonTitle 27 | otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION; 28 | 29 | @property(nonatomic,assign) id delegate; // weak reference 30 | 31 | @property (nonatomic, copy) void(^onOkAction)(void); //called if dismissed with other button 32 | @property (nonatomic, copy) void(^onCancelAction)(void);//called if dismissed with cancel button 33 | @property (nonatomic, copy) void(^onDismissAction)(void);//called after onOkAction or onCancelAction. Useful if alert has more than 2 buttons 34 | 35 | @property (nonatomic, assign, readonly) NSInteger dismissButtonIndex;//index of button that was tapped to dismiss the alert 36 | 37 | 38 | @property(nonatomic,copy) NSString *title; 39 | @property(nonatomic,copy) NSString *message; // secondary explanation text 40 | 41 | // adds a button with the title. returns the index (0 based) of where it was added. buttons are displayed in the order added except for the 42 | // cancel button which will be positioned based on HI requirements. Buttons cannot be customized. If you pass nil as a title no button will be added. 43 | - (NSInteger)addButtonWithTitle:(NSString *)title; // returns index of button. 0 based. 44 | - (NSString *)buttonTitleAtIndex:(NSInteger)buttonIndex; 45 | @property(nonatomic,readonly) NSInteger numberOfButtons; 46 | @property(nonatomic) NSInteger cancelButtonIndex; // if the delegate does not implement -alertViewCancel:, we pretend this button was clicked on. default is -1 47 | 48 | //max height of the alert, if set 49 | @property(nonatomic) NSInteger maxHeight; 50 | 51 | // TODO: not implemented 52 | //@property(nonatomic,readonly) NSInteger firstOtherButtonIndex; // -1 if no otherButtonTitles or initWithTitle:... not used 53 | 54 | @property(nonatomic,readonly,getter=isVisible) BOOL visible; 55 | 56 | // Flat Alert view style - defaults to FUIAlertViewStyleDefault 57 | @property(nonatomic,assign) FUIAlertViewStyle alertViewStyle; 58 | 59 | // shows popup alert animated. 60 | - (void)show; 61 | 62 | // hides alert sheet or popup. use this method when you need to explicitly dismiss the alert. 63 | // it does not need to be called if the user presses on a button 64 | - (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated; 65 | 66 | - (void)clickButtonAtIndex:(NSInteger)buttonIndex; 67 | 68 | /* Retrieve a text field at an index - raises NSRangeException when textFieldIndex is out-of-bounds. 69 | The field at index 0 will be the first text field (the single field or the login field), the field at index 1 will be the password field. */ 70 | - (FUITextField *)textFieldAtIndex:(NSInteger)textFieldIndex; 71 | 72 | @property(nonatomic, strong) NSMutableArray *buttons; 73 | @property(nonatomic, weak, readonly) UILabel *titleLabel; 74 | @property(nonatomic, weak, readonly) UILabel *messageLabel; 75 | @property(nonatomic, weak, readonly) UIView *backgroundOverlay; 76 | @property(nonatomic, weak, readonly) UIView *alertContainer; 77 | @property(nonatomic) CGFloat buttonSpacing UI_APPEARANCE_SELECTOR; 78 | @property(nonatomic) CGFloat animationDuration UI_APPEARANCE_SELECTOR; 79 | @property(nonatomic) BOOL hasCancelButton; 80 | 81 | //setting these properties overwrites any other button colors/fonts that have already been set 82 | @property(nonatomic, strong) UIFont *defaultButtonFont UI_APPEARANCE_SELECTOR; 83 | @property(nonatomic, strong) UIColor *defaultButtonTitleColor UI_APPEARANCE_SELECTOR; 84 | @property(nonatomic, strong) UIColor *defaultButtonColor UI_APPEARANCE_SELECTOR; 85 | @property(nonatomic, strong) UIColor *defaultButtonShadowColor UI_APPEARANCE_SELECTOR; 86 | @property(nonatomic, readwrite) CGFloat defaultButtonCornerRadius UI_APPEARANCE_SELECTOR; 87 | @property(nonatomic, readwrite) CGFloat defaultButtonShadowHeight UI_APPEARANCE_SELECTOR; 88 | 89 | @end 90 | 91 | 92 | @protocol FUIAlertViewDelegate 93 | @optional 94 | 95 | // Called when a button is clicked. The view will be automatically dismissed after this call returns 96 | - (void)alertView:(FUIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex; 97 | 98 | // Called when we cancel a view (eg. the user clicks the Home button). This is not called when the user clicks the cancel button. 99 | // If not defined in the delegate, we simulate a click in the cancel button 100 | // TODO: not implemented 101 | //- (void)alertViewCancel:(FUIAlertView *)alertView; 102 | 103 | - (void)willPresentAlertView:(FUIAlertView *)alertView; // before animation and showing view 104 | - (void)didPresentAlertView:(FUIAlertView *)alertView; // after animation 105 | 106 | - (void)alertView:(FUIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex; // before animation and hiding view 107 | - (void)alertView:(FUIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex; // after animation 108 | 109 | // Called after edits in any of the default fields added by the style 110 | // TODO: not implemented 111 | //- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView; 112 | 113 | @end 114 | -------------------------------------------------------------------------------- /Classes/ios/FUIAlertView.m: -------------------------------------------------------------------------------- 1 | // 2 | // FUIAlertView.m 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/7/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import "FUIAlertView.h" 10 | #import "FUIButton.h" 11 | 12 | @interface FUIAlertView() 13 | 14 | @property(nonatomic, weak) UIView *alertContentContainer; 15 | @property(nonatomic, strong) NSMutableArray* textFields; 16 | 17 | @end 18 | 19 | @implementation FUIAlertView 20 | 21 | + (void)initialize { 22 | if (self == [FUIAlertView class]) { 23 | FUIAlertView *appearance = [self appearance]; 24 | [appearance setButtonSpacing:10.0f]; 25 | [appearance setAnimationDuration:0.2f]; 26 | } 27 | } 28 | 29 | - (id)init 30 | { 31 | return [self initWithFrame:CGRectZero]; 32 | } 33 | 34 | - (id)initWithCoder:(NSCoder *)aDecoder 35 | { 36 | return [self initWithFrame:CGRectZero]; 37 | } 38 | 39 | - (id)initWithFrame:(CGRect)frame 40 | { 41 | self = [super initWithFrame:frame]; 42 | if (self) { 43 | self.textFields = [@[] mutableCopy]; 44 | 45 | // This mask is set to force lay out of subviews when superview's bounds change 46 | self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 47 | 48 | UIView *backgroundOverlay = [[UIView alloc] init]; 49 | backgroundOverlay.backgroundColor = [UIColor blueColor]; 50 | [self addSubview:backgroundOverlay]; 51 | backgroundOverlay.alpha = 0; 52 | _backgroundOverlay = backgroundOverlay; 53 | 54 | UIView *alertContainer = [[UIView alloc] init]; 55 | alertContainer.backgroundColor = [UIColor yellowColor]; 56 | [self addSubview:alertContainer]; 57 | [self bringSubviewToFront:alertContainer]; 58 | _alertContainer = alertContainer; 59 | 60 | UIView *alertContentContainer = [[UIView alloc] init]; 61 | alertContentContainer.backgroundColor = [UIColor clearColor]; 62 | [self.alertContainer addSubview:alertContentContainer]; 63 | [self.alertContainer bringSubviewToFront:alertContentContainer]; 64 | _alertContentContainer = alertContentContainer; 65 | 66 | UILabel *titleLabel = [[UILabel alloc] init]; 67 | titleLabel.numberOfLines = 0; 68 | titleLabel.backgroundColor = [UIColor clearColor]; 69 | titleLabel.textAlignment = NSTextAlignmentCenter; 70 | titleLabel.text = self.title; 71 | [alertContentContainer addSubview:titleLabel]; 72 | _titleLabel = titleLabel; 73 | 74 | UILabel *messageLabel = [[UILabel alloc] init]; 75 | messageLabel.numberOfLines = 0; 76 | messageLabel.backgroundColor = [UIColor clearColor]; 77 | messageLabel.textAlignment = NSTextAlignmentCenter; 78 | messageLabel.text = self.message; 79 | [alertContentContainer addSubview:messageLabel]; 80 | _messageLabel = messageLabel; 81 | 82 | FUITextField* firstTextField = [[FUITextField alloc] init]; 83 | [firstTextField setTextAlignment:NSTextAlignmentCenter]; 84 | [self.textFields addObject:firstTextField]; 85 | [alertContentContainer addSubview:firstTextField]; 86 | 87 | FUITextField* secureTextField = [[FUITextField alloc] init]; 88 | [secureTextField setSecureTextEntry:YES]; 89 | [secureTextField setTextAlignment:NSTextAlignmentCenter]; 90 | [self.textFields addObject:secureTextField]; 91 | [alertContentContainer addSubview:secureTextField]; 92 | 93 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow) name:UIKeyboardWillShowNotification object:nil]; 94 | } 95 | return self; 96 | } 97 | 98 | - (id)initWithTitle:(NSString *)title 99 | message:(NSString *)message 100 | delegate:(id)delegate 101 | cancelButtonTitle:(NSString *)cancelButtonTitle 102 | otherButtonTitles:(NSString *)otherButtonTitles, ... { 103 | self = [self initWithFrame:CGRectZero]; 104 | if (self) { 105 | self.title = title; 106 | self.message = message; 107 | self.delegate = delegate; 108 | 109 | if (cancelButtonTitle) { 110 | [self addButtonWithTitle:cancelButtonTitle]; 111 | [self setHasCancelButton:YES]; 112 | } 113 | va_list args; 114 | va_start(args, otherButtonTitles); 115 | for (NSString *arg = otherButtonTitles; arg != nil; arg = va_arg(args, NSString*)) { 116 | [self addButtonWithTitle:arg]; 117 | } 118 | va_end(args); 119 | } 120 | return self; 121 | } 122 | 123 | - (void)keyboardWillShow 124 | { 125 | [self.alertContainer setTransform:CGAffineTransformMakeTranslation(0, - self.alertContainer.frame.origin.y + [[UIApplication sharedApplication] statusBarFrame].size.height)]; 126 | } 127 | 128 | - (void) layoutSubviews { 129 | [super layoutSubviews]; 130 | if (CGAffineTransformIsIdentity(self.alertContainer.transform)) { 131 | self.backgroundOverlay.frame = self.bounds; 132 | CGFloat padding = 15; 133 | CGRect contentContainerFrame = CGRectMake(padding, padding, 0, 0); 134 | contentContainerFrame.size = [self calculateSize]; 135 | self.alertContentContainer.frame = contentContainerFrame; 136 | CGRect alertContainerFrame = CGRectInset(contentContainerFrame, -padding, -padding); 137 | alertContainerFrame.origin = CGPointMake(floorf((self.frame.size.width - alertContainerFrame.size.width) / 2), 138 | floorf((self.frame.size.height - alertContainerFrame.size.height) / 2)); 139 | alertContainerFrame.origin.y = MAX(30, alertContainerFrame.origin.y - 30); 140 | self.alertContainer.frame = alertContainerFrame; 141 | CGRect titleFrame = self.titleLabel.frame; 142 | titleFrame.size.width = self.alertContentContainer.frame.size.width; 143 | self.titleLabel.frame = titleFrame; 144 | [self.titleLabel sizeToFit]; 145 | titleFrame = self.titleLabel.frame; 146 | CGPoint titleOrigin = CGPointMake(floorf((self.alertContentContainer.frame.size.width - self.titleLabel.frame.size.width)/2), 0); 147 | titleFrame.origin = titleOrigin; 148 | self.titleLabel.frame = titleFrame; 149 | CGRect messageFrame = self.messageLabel.frame; 150 | messageFrame.size.width = self.alertContentContainer.frame.size.width; 151 | self.messageLabel.frame = messageFrame; 152 | [self.messageLabel sizeToFit]; 153 | messageFrame = self.messageLabel.frame; 154 | CGPoint messageOrigin = CGPointMake(floorf((self.alertContentContainer.frame.size.width - self.messageLabel.frame.size.width)/2), CGRectGetMaxY(titleFrame) + 10); 155 | messageFrame.origin = messageOrigin; 156 | self.messageLabel.frame = messageFrame; 157 | 158 | if (self.alertViewStyle == FUIAlertViewStylePlainTextInput || self.alertViewStyle == FUIAlertViewStyleSecureTextInput) { 159 | if (self.alertViewStyle == FUIAlertViewStyleSecureTextInput) { 160 | [self.textFields[0] setSecureTextEntry:YES]; 161 | } 162 | [self.textFields[0] setFrame:(CGRect){{0, self.messageLabel.frame.origin.y + self.messageLabel.frame.size.height + 10},{self.alertContentContainer.frame.size.width, 40}}]; 163 | } 164 | if (self.alertViewStyle == FUIAlertViewStyleLoginAndPasswordInput) { 165 | [self.textFields[0] setFrame:(CGRect){{0, self.messageLabel.frame.origin.y + self.messageLabel.frame.size.height + 10},{self.alertContentContainer.frame.size.width, 40}}]; 166 | [self.textFields[1] setFrame:(CGRect){{0, ((FUITextField*)self.textFields[0]).frame.origin.y + ((FUITextField*)self.textFields[0]).frame.size.height + 5},{self.alertContentContainer.frame.size.width, 40}}]; 167 | } 168 | 169 | __block CGFloat startingButtonY = self.alertContentContainer.frame.size.height - [self totalButtonHeight]; 170 | [self.buttons enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 171 | UIButton *button = obj; 172 | if (self.hasCancelButton && idx == 0) { 173 | CGFloat lastButtonY = self.alertContentContainer.frame.size.height - button.frame.size.height; 174 | [self setButton:obj atHeight:lastButtonY]; 175 | } else { 176 | [self setButton:obj atHeight:startingButtonY]; 177 | startingButtonY += (button.frame.size.height + self.buttonSpacing); 178 | } 179 | }]; 180 | if(self.messageLabel.superview&&![self.messageLabel.superview isEqual:self.alertContentContainer]) { 181 | [self.messageLabel removeFromSuperview]; 182 | [self.alertContentContainer addSubview:self.messageLabel]; 183 | } 184 | if(self.maxHeight) { 185 | CGSize originalSize = messageFrame.size; 186 | messageFrame.size.height = self.alertContentContainer.frame.size.height-self.titleLabel.frame.size.height-[self totalButtonHeight]-20; 187 | if(messageFrame.size.heightself.maxHeight) 265 | return CGSizeMake(contentWidth, MAX(titleHeight + 10 + buttonHeight, self.maxHeight)); 266 | else 267 | return CGSizeMake(contentWidth, contentHeight); 268 | } 269 | 270 | - (NSInteger) numberOfButtons { 271 | return (NSInteger)self.buttons.count; 272 | } 273 | 274 | - (void)show { 275 | self.alertContainer.alpha = 0; 276 | self.alertContainer.transform = CGAffineTransformMakeScale(1.3, 1.3); 277 | UIViewController *topController = [[[[UIApplication sharedApplication] windows] firstObject] rootViewController]; 278 | 279 | while (topController.presentedViewController && !topController.presentedViewController.isBeingDismissed) { 280 | topController = topController.presentedViewController; 281 | } 282 | UIView *rootView = topController.view; 283 | self.frame = rootView.bounds; 284 | 285 | [rootView addSubview:self]; 286 | [rootView bringSubviewToFront:self]; 287 | if ([self.delegate respondsToSelector:@selector(willPresentAlertView:)]) { 288 | [self.delegate willPresentAlertView:self]; 289 | } 290 | [UIView animateWithDuration:self.animationDuration animations:^{ 291 | self.backgroundOverlay.alpha = 1; 292 | self.alertContainer.alpha = 1; 293 | self.alertContainer.transform = CGAffineTransformIdentity; 294 | } completion:^(BOOL finished0) { 295 | _visible = YES; 296 | if ([self.delegate respondsToSelector:@selector(didPresentAlertView:)]) { 297 | [self.delegate didPresentAlertView:self]; 298 | } 299 | }]; 300 | } 301 | 302 | - (NSString *)buttonTitleAtIndex:(NSInteger)buttonIndex { 303 | if (buttonIndex < 0 || buttonIndex > (NSInteger)self.buttons.count) { 304 | return nil; 305 | } 306 | return [[self.buttons objectAtIndex:(NSUInteger)buttonIndex] titleForState:UIControlStateNormal]; 307 | } 308 | 309 | - (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated { 310 | //todo delegate 311 | 312 | _dismissButtonIndex = buttonIndex; 313 | 314 | self.alertContainer.transform = CGAffineTransformIdentity; 315 | if ([self.delegate respondsToSelector:@selector(alertView:willDismissWithButtonIndex:)]) { 316 | [self.delegate alertView:self willDismissWithButtonIndex:buttonIndex]; 317 | } 318 | 319 | if (self.onDismissAction) { 320 | self.onDismissAction(); 321 | } 322 | 323 | [UIView animateWithDuration:self.animationDuration animations:^{ 324 | self.backgroundOverlay.alpha = 0; 325 | self.alertContainer.alpha = 0; 326 | self.alertContainer.transform = CGAffineTransformMakeScale(0.7, 0.7); 327 | } completion:^(BOOL finished) { 328 | [self removeFromSuperview]; 329 | _visible = NO; 330 | if ([self.delegate respondsToSelector:@selector(alertView:didDismissWithButtonIndex:)]) { 331 | [self.delegate alertView:self didDismissWithButtonIndex:buttonIndex]; 332 | } 333 | }]; 334 | } 335 | 336 | - (NSInteger)addButtonWithTitle:(NSString *)title { 337 | if (!title) return -1; 338 | if (!self.buttons) { 339 | self.buttons = [NSMutableArray array]; 340 | } 341 | FUIButton *button = [[FUIButton alloc] initWithFrame:CGRectMake(0, 0, 250, 44)]; 342 | button.cornerRadius = 3; 343 | button.buttonColor = [UIColor greenColor]; 344 | button.shadowColor = [UIColor brownColor]; 345 | button.shadowHeight = 3; 346 | [button setTitle:title forState:UIControlStateNormal]; 347 | [button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside]; 348 | [self.alertContentContainer addSubview:button]; 349 | [self.buttons addObject:button]; 350 | return (NSInteger)self.buttons.count-1; 351 | } 352 | 353 | - (void) buttonPressed:(FUIButton *)sender { 354 | NSUInteger index = [self.buttons indexOfObject:sender]; 355 | if ([self.delegate respondsToSelector:@selector(alertView:clickedButtonAtIndex:)]) { 356 | [self.delegate alertView:self clickedButtonAtIndex:(NSInteger)index]; 357 | } 358 | 359 | if (index == self.cancelButtonIndex && self.onCancelAction) { 360 | self.onCancelAction(); 361 | } else if (index != self.cancelButtonIndex && self.onOkAction) { 362 | self.onOkAction(); 363 | } 364 | 365 | [self dismissWithClickedButtonIndex:(NSInteger)index animated:YES]; 366 | } 367 | 368 | - (void)clickButtonAtIndex:(NSInteger)buttonIndex { 369 | [[self.buttons objectAtIndex:(NSUInteger)buttonIndex] sendActionsForControlEvents:UIControlEventTouchUpInside]; 370 | } 371 | 372 | - (void) setDefaultButtonFont:(UIFont *)defaultButtonFont { 373 | _defaultButtonFont = defaultButtonFont; 374 | [self.buttons enumerateObjectsUsingBlock:^(FUIButton *button, NSUInteger idx, BOOL *stop) { 375 | button.titleLabel.font = defaultButtonFont; 376 | }]; 377 | } 378 | 379 | - (void) setDefaultButtonTitleColor:(UIColor *)defaultButtonTitleColor { 380 | _defaultButtonTitleColor = defaultButtonTitleColor; 381 | [self.buttons enumerateObjectsUsingBlock:^(FUIButton *button, NSUInteger idx, BOOL *stop) { 382 | [button setTitleColor:defaultButtonTitleColor forState:UIControlStateNormal & UIControlStateHighlighted]; 383 | }]; 384 | } 385 | 386 | - (void) setDefaultButtonColor:(UIColor *)defaultButtonColor { 387 | _defaultButtonColor = defaultButtonColor; 388 | [self.buttons enumerateObjectsUsingBlock:^(FUIButton *button, NSUInteger idx, BOOL *stop) { 389 | button.buttonColor = defaultButtonColor; 390 | }]; 391 | } 392 | 393 | - (void) setDefaultButtonShadowColor:(UIColor *)defaultButtonShadowColor { 394 | _defaultButtonShadowColor = defaultButtonShadowColor; 395 | [self.buttons enumerateObjectsUsingBlock:^(FUIButton *button, NSUInteger idx, BOOL *stop) { 396 | button.shadowColor = defaultButtonShadowColor; 397 | }]; 398 | } 399 | 400 | - (void) setDefaultButtonCornerRadius:(CGFloat)defaultButtonCornerRadius { 401 | _defaultButtonCornerRadius = defaultButtonCornerRadius; 402 | [self.buttons enumerateObjectsUsingBlock:^(FUIButton *button, NSUInteger idx, BOOL *stop) { 403 | button.cornerRadius = defaultButtonCornerRadius; 404 | }]; 405 | } 406 | 407 | - (void) setDefaultButtonShadowHeight:(CGFloat)defaultButtonShadowHeight { 408 | _defaultButtonShadowHeight = defaultButtonShadowHeight; 409 | [self.buttons enumerateObjectsUsingBlock:^(FUIButton *button, NSUInteger idx, BOOL *stop) { 410 | button.shadowHeight = defaultButtonShadowHeight; 411 | }]; 412 | } 413 | 414 | - (FUITextField *)textFieldAtIndex:(NSInteger)textFieldIndex 415 | { 416 | return (textFieldIndex < 2) ? self.textFields[textFieldIndex] : nil; 417 | } 418 | 419 | - (void)dealloc 420 | { 421 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; 422 | } 423 | 424 | @end 425 | -------------------------------------------------------------------------------- /Classes/ios/FUIButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // FUIButton.h 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/7/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FUIButton : UIButton 12 | 13 | @property(nonatomic, strong, readwrite) UIColor *buttonColor UI_APPEARANCE_SELECTOR; 14 | @property(nonatomic, strong, readwrite) UIColor *shadowColor UI_APPEARANCE_SELECTOR; 15 | @property(nonatomic, strong, readwrite) UIColor *highlightedColor UI_APPEARANCE_SELECTOR; 16 | @property(nonatomic, strong, readwrite) UIColor *disabledColor UI_APPEARANCE_SELECTOR; 17 | @property(nonatomic, strong, readwrite) UIColor *disabledShadowColor UI_APPEARANCE_SELECTOR; 18 | @property(nonatomic, readwrite) CGFloat shadowHeight UI_APPEARANCE_SELECTOR; 19 | @property(nonatomic, readwrite) CGFloat cornerRadius UI_APPEARANCE_SELECTOR; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Classes/ios/FUIButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // FUIButton.m 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/7/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import "FUIButton.h" 10 | #import "UIImage+FlatUI.h" 11 | 12 | @interface FUIButton() 13 | @property(nonatomic) UIEdgeInsets defaultEdgeInsets; 14 | @property(nonatomic) UIEdgeInsets normalEdgeInsets; 15 | @property(nonatomic) UIEdgeInsets highlightedEdgeInsets; 16 | @end 17 | 18 | @implementation FUIButton 19 | 20 | - (id)initWithFrame:(CGRect)frame { 21 | self = [super initWithFrame:frame]; 22 | if (self) { 23 | self.defaultEdgeInsets = self.titleEdgeInsets; 24 | } 25 | return self; 26 | } 27 | 28 | - (void) setTitleEdgeInsets:(UIEdgeInsets)titleEdgeInsets { 29 | [super setTitleEdgeInsets:titleEdgeInsets]; 30 | self.defaultEdgeInsets = titleEdgeInsets; 31 | [self setShadowHeight:self.shadowHeight]; 32 | } 33 | 34 | - (void) setHighlighted:(BOOL)highlighted { 35 | UIEdgeInsets insets = highlighted ? self.highlightedEdgeInsets : self.normalEdgeInsets; 36 | [super setTitleEdgeInsets:insets]; 37 | [super setHighlighted:highlighted]; 38 | } 39 | 40 | - (void) setCornerRadius:(CGFloat)cornerRadius { 41 | _cornerRadius = cornerRadius; 42 | [self configureFlatButton]; 43 | } 44 | 45 | - (void) setButtonColor:(UIColor *)buttonColor { 46 | _buttonColor = buttonColor; 47 | [self configureFlatButton]; 48 | } 49 | 50 | - (void) setShadowColor:(UIColor *)shadowColor { 51 | _shadowColor = shadowColor; 52 | [self configureFlatButton]; 53 | } 54 | 55 | - (void) setHighlightedColor:(UIColor *)highlightedColor { 56 | _highlightedColor = highlightedColor; 57 | [self configureFlatButton]; 58 | } 59 | 60 | - (void) setDisabledColor:(UIColor *)disabledColor { 61 | _disabledColor = disabledColor; 62 | [self configureFlatButton]; 63 | } 64 | 65 | - (void) setDisabledShadowColor:(UIColor *)disabledShadowColor { 66 | _disabledShadowColor = disabledShadowColor; 67 | [self configureFlatButton]; 68 | } 69 | 70 | - (void) setShadowHeight:(CGFloat)shadowHeight { 71 | _shadowHeight = shadowHeight; 72 | UIEdgeInsets insets = self.defaultEdgeInsets; 73 | insets.top += shadowHeight; 74 | self.highlightedEdgeInsets = insets; 75 | insets.top -= shadowHeight * 2.0f; 76 | self.normalEdgeInsets = insets; 77 | [super setTitleEdgeInsets:insets]; 78 | [self configureFlatButton]; 79 | } 80 | 81 | - (void) configureFlatButton { 82 | UIImage *normalBackgroundImage = [UIImage buttonImageWithColor:self.buttonColor 83 | cornerRadius:self.cornerRadius 84 | shadowColor:self.shadowColor 85 | shadowInsets:UIEdgeInsetsMake(0, 0, self.shadowHeight, 0)]; 86 | 87 | UIColor *highlightedColor = self.highlightedColor == nil ? self.buttonColor : self.highlightedColor; 88 | UIImage *highlightedBackgroundImage = [UIImage buttonImageWithColor:highlightedColor 89 | cornerRadius:self.cornerRadius 90 | shadowColor:[UIColor clearColor] 91 | shadowInsets:UIEdgeInsetsMake(self.shadowHeight, 0, 0, 0)]; 92 | 93 | if (self.disabledColor) { 94 | UIColor *disabledShadowColor = self.disabledShadowColor == nil ? self.shadowColor : self.disabledShadowColor; 95 | UIImage *disabledBackgroundImage = [UIImage buttonImageWithColor:self.disabledColor 96 | cornerRadius:self.cornerRadius 97 | shadowColor:disabledShadowColor 98 | shadowInsets:UIEdgeInsetsMake(0, 0, self.shadowHeight, 0)]; 99 | [self setBackgroundImage:disabledBackgroundImage forState:UIControlStateDisabled]; 100 | } 101 | 102 | [self setBackgroundImage:normalBackgroundImage forState:UIControlStateNormal]; 103 | [self setBackgroundImage:highlightedBackgroundImage forState:UIControlStateHighlighted]; 104 | } 105 | 106 | @end 107 | -------------------------------------------------------------------------------- /Classes/ios/FUICellBackgroundView.h: -------------------------------------------------------------------------------- 1 | // 2 | // UACellBackgroundView.h 3 | // FlatUI 4 | // 5 | // Created by Maciej Swic on 2013-05-30. 6 | // Licensed under the MIT license. 7 | 8 | #import 9 | 10 | @interface FUICellBackgroundView : UIView 11 | 12 | @property (nonatomic, strong) UIColor *backgroundColor UI_APPEARANCE_SELECTOR; 13 | @property (nonatomic) CGFloat cornerRadius UI_APPEARANCE_SELECTOR; 14 | @property (nonatomic, strong) UIColor* separatorColor UI_APPEARANCE_SELECTOR; 15 | @property (nonatomic) CGFloat separatorHeight UI_APPEARANCE_SELECTOR; 16 | @property (nonatomic) UIRectCorner roundedCorners; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Classes/ios/FUICellBackgroundView.m: -------------------------------------------------------------------------------- 1 | // 2 | // UACellBackgroundView.m 3 | // FlatUI 4 | // 5 | // Created by Maciej Swic on 2013-05-30. 6 | // Licensed under the MIT license. 7 | 8 | #import "FUICellBackgroundView.h" 9 | 10 | @implementation FUICellBackgroundView 11 | 12 | + (void)initialize { 13 | if (self == [FUICellBackgroundView class]) { 14 | FUICellBackgroundView *appearance = [self appearance]; 15 | [appearance setCornerRadius:3.0f]; 16 | [appearance setSeparatorHeight:1.0f]; 17 | [appearance setSeparatorColor:[UIColor clearColor]]; 18 | } 19 | } 20 | 21 | - (id)initWithFrame:(CGRect)frame { 22 | if ((self = [super initWithFrame:frame])) { 23 | self.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; 24 | } 25 | return self; 26 | } 27 | 28 | - (BOOL)isOpaque { 29 | return NO; 30 | } 31 | 32 | - (void)drawRect:(CGRect)aRect { 33 | 34 | CGContextRef c = UIGraphicsGetCurrentContext(); 35 | 36 | int lineWidth = 1; 37 | 38 | CGContextSetStrokeColorWithColor(c, [[UIColor grayColor] CGColor]); 39 | CGContextSetLineWidth(c, lineWidth); 40 | CGContextSetAllowsAntialiasing(c, YES); 41 | CGContextSetShouldAntialias(c, YES); 42 | 43 | CGSize radii = CGSizeMake(self.cornerRadius, self.cornerRadius); 44 | UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds 45 | byRoundingCorners:self.roundedCorners 46 | cornerRadii:radii]; 47 | CGPathRef path = bezierPath.CGPath; 48 | 49 | CGContextSaveGState(c); 50 | CGContextAddPath(c, path); 51 | CGContextClip(c); 52 | 53 | CGContextSetFillColorWithColor(c, self.backgroundColor.CGColor); 54 | CGContextFillRect(c, self.bounds); 55 | CGContextSetFillColorWithColor(c, self.separatorColor.CGColor); 56 | CGContextFillRect(c, CGRectMake(0, self.bounds.size.height - self.separatorHeight, self.bounds.size.width, self.bounds.size.height - self.separatorHeight)); 57 | 58 | CGContextRestoreGState(c); 59 | 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /Classes/ios/FUIPopoverBackgroundView.h: -------------------------------------------------------------------------------- 1 | // 2 | // FUIPopoverBackgroundView.h 3 | // FlatUIKitExample 4 | // 5 | // Created by Jack Flintermann on 6/5/13. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface FUIPopoverBackgroundView : UIPopoverBackgroundView 12 | 13 | + (void) setBackgroundColor:(UIColor *)backgroundColor; 14 | + (void) setCornerRadius:(CGFloat)cornerRadius; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Classes/ios/FUIPopoverBackgroundView.m: -------------------------------------------------------------------------------- 1 | // 2 | // FUIPopoverBackgroundView.m 3 | // FlatUIKitExample 4 | // 5 | // Created by Jack Flintermann on 6/5/13. 6 | // Partial implementation created by Ignacio on 5/30/13. 7 | // 8 | 9 | #import "FUIPopoverBackgroundView.h" 10 | #import "UIImage+FlatUI.h" 11 | #import 12 | #import "UIColor+FlatUI.h" 13 | 14 | #define CONTENT_INSET 10.0f 15 | #define ARROW_BASE 30.0f 16 | #define ARROW_HEIGHT 20.0f 17 | 18 | static CGFloat _cornerRadius = 9.0; 19 | static UIColor *_backgroundColor; 20 | 21 | @interface FUIPopoverBackgroundView() { 22 | UIImageView *_borderImageView; 23 | UIImageView *_arrowView; 24 | CGFloat _arrowOffset; 25 | UIPopoverArrowDirection _arrowDirection; 26 | } 27 | @end 28 | 29 | @implementation FUIPopoverBackgroundView 30 | 31 | - (id)initWithFrame:(CGRect)frame { 32 | self = [super initWithFrame:frame]; 33 | if (self) { 34 | if (!_backgroundColor) { 35 | _backgroundColor = [UIColor midnightBlueColor]; 36 | } 37 | 38 | _borderImageView = [[UIImageView alloc] init]; 39 | [self addSubview:_borderImageView]; 40 | 41 | _arrowView = [[UIImageView alloc] init]; 42 | [self setupImages]; 43 | [self addSubview:_arrowView]; 44 | self.layer.shadowColor = [UIColor clearColor].CGColor; 45 | } 46 | return self; 47 | } 48 | 49 | + (void) setBackgroundColor:(UIColor *)backgroundColor { 50 | _backgroundColor = backgroundColor; 51 | } 52 | 53 | + (void) setCornerRadius:(CGFloat)cornerRadius { 54 | _cornerRadius = cornerRadius; 55 | } 56 | 57 | - (void) setupImages { 58 | _borderImageView.image = [self borderImage]; 59 | _arrowView.image = [self arrowImage]; 60 | } 61 | 62 | - (UIImage *)borderImage { 63 | return [[[UIImage imageWithColor:_backgroundColor cornerRadius:_cornerRadius] imageWithMinimumSize:self.frame.size] resizableImageWithCapInsets:UIEdgeInsetsMake(_cornerRadius, _cornerRadius, _cornerRadius, _cornerRadius)]; 64 | } 65 | 66 | - (UIImage *)arrowImage { 67 | //Create a UIBezierPath for a Triangle 68 | UIGraphicsBeginImageContextWithOptions(CGSizeMake(ARROW_BASE, ARROW_HEIGHT), NO, [UIScreen mainScreen].scale); 69 | 70 | //// Bezier Drawing 71 | UIBezierPath* bezierPath = [UIBezierPath bezierPath]; 72 | [bezierPath moveToPoint:CGPointMake(ARROW_BASE / 2, 0)]; 73 | [bezierPath addLineToPoint:CGPointMake(0, ARROW_HEIGHT)]; 74 | [bezierPath addLineToPoint:CGPointMake(ARROW_BASE, ARROW_HEIGHT)]; 75 | [bezierPath closePath]; 76 | [_backgroundColor setFill]; 77 | [bezierPath fill]; 78 | 79 | //Create a UIImage using the current context. 80 | UIImage *arrow = UIGraphicsGetImageFromCurrentImageContext(); 81 | UIGraphicsEndImageContext(); 82 | 83 | return arrow; 84 | } 85 | 86 | + (BOOL)wantsDefaultContentAppearance { 87 | return NO; 88 | } 89 | 90 | /* 91 | The following code is taken from the Treehouse blog and can be found (along with other awesome stuff) at 92 | http://blog.teamtreehouse.com/customizing-the-design-of-uipopovercontroller 93 | */ 94 | 95 | - (CGFloat) arrowOffset { 96 | return _arrowOffset; 97 | } 98 | 99 | - (void) setArrowOffset:(CGFloat)arrowOffset { 100 | _arrowOffset = arrowOffset; 101 | } 102 | 103 | - (UIPopoverArrowDirection)arrowDirection { 104 | return _arrowDirection; 105 | } 106 | 107 | - (void)setArrowDirection:(UIPopoverArrowDirection)arrowDirection { 108 | _arrowDirection = arrowDirection; 109 | } 110 | 111 | + (UIEdgeInsets)contentViewInsets{ 112 | return UIEdgeInsetsMake(CONTENT_INSET, CONTENT_INSET, CONTENT_INSET, CONTENT_INSET); 113 | } 114 | 115 | + (CGFloat)arrowHeight{ 116 | return ARROW_HEIGHT; 117 | } 118 | 119 | + (CGFloat)arrowBase{ 120 | return ARROW_BASE; 121 | } 122 | 123 | #pragma mark - Layout subviews 124 | - (void)layoutSubviews { 125 | [super layoutSubviews]; 126 | 127 | CGFloat _height = self.frame.size.height; 128 | CGFloat _width = self.frame.size.width; 129 | CGFloat _left = 0.0; 130 | CGFloat _top = 0.0; 131 | CGFloat _coordinate = 0.0; 132 | CGAffineTransform _rotation = CGAffineTransformIdentity; 133 | 134 | switch (_arrowDirection) { 135 | default: 136 | case UIPopoverArrowDirectionUp: 137 | _top += ARROW_HEIGHT; 138 | _height -= ARROW_HEIGHT; 139 | _coordinate = ((self.frame.size.width / 2) + self.arrowOffset) - (ARROW_BASE/2); 140 | _arrowView.frame = CGRectMake(_coordinate, 0, ARROW_BASE, ARROW_HEIGHT); 141 | break; 142 | case UIPopoverArrowDirectionDown: 143 | _height -= ARROW_HEIGHT; 144 | _coordinate = ((self.frame.size.width / 2) + self.arrowOffset) - (ARROW_BASE/2); 145 | _arrowView.frame = CGRectMake(_coordinate, _height, ARROW_BASE, ARROW_HEIGHT); 146 | _rotation = CGAffineTransformMakeRotation( (float)M_PI ); 147 | break; 148 | case UIPopoverArrowDirectionLeft: 149 | _left += ARROW_BASE - 10; 150 | _width -= ARROW_BASE; 151 | _width += 10; 152 | _coordinate = ((self.frame.size.height / 2) + self.arrowOffset) - (ARROW_HEIGHT/2); 153 | _arrowView.frame = CGRectMake(-(ARROW_BASE - ARROW_HEIGHT)/2, _coordinate, ARROW_BASE, ARROW_HEIGHT); 154 | _rotation = CGAffineTransformMakeRotation( -(float)M_PI_2 ); 155 | break; 156 | case UIPopoverArrowDirectionRight: 157 | _width -= ARROW_BASE; 158 | _coordinate = ((self.frame.size.height / 2) + self.arrowOffset)- (ARROW_HEIGHT/2); 159 | _arrowView.frame = CGRectMake(_width + ((ARROW_BASE - ARROW_HEIGHT)/2), _coordinate, ARROW_BASE, ARROW_HEIGHT); 160 | _rotation = CGAffineTransformMakeRotation( (float)M_PI_2 ); 161 | _width += 10; 162 | break; 163 | } 164 | 165 | _borderImageView.frame = CGRectMake(_left, _top, _width, _height); 166 | [_arrowView setTransform:_rotation]; 167 | } 168 | 169 | @end 170 | -------------------------------------------------------------------------------- /Classes/ios/FUISegmentedControl.h: -------------------------------------------------------------------------------- 1 | // 2 | // FUISegmentedControl.h 3 | // FlatUIKitExample 4 | // 5 | // Created by Alex Medearis on 5/17/13. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface FUISegmentedControl : UISegmentedControl 12 | 13 | @property(nonatomic, strong, readwrite) UIColor *selectedColor UI_APPEARANCE_SELECTOR; 14 | @property(nonatomic, strong, readwrite) UIColor *disabledColor UI_APPEARANCE_SELECTOR; 15 | @property(nonatomic, strong, readwrite) UIColor *deselectedColor UI_APPEARANCE_SELECTOR; 16 | @property(nonatomic, strong, readwrite) UIColor *highlightedColor UI_APPEARANCE_SELECTOR; 17 | @property(nonatomic, strong, readwrite) UIColor *dividerColor UI_APPEARANCE_SELECTOR; 18 | @property(nonatomic, readwrite) CGFloat cornerRadius UI_APPEARANCE_SELECTOR; 19 | @property(nonatomic, strong, readwrite) UIFont *selectedFont UI_APPEARANCE_SELECTOR; 20 | @property(nonatomic, strong, readwrite) UIFont *disabledFont UI_APPEARANCE_SELECTOR; 21 | @property(nonatomic, strong, readwrite) UIFont *deselectedFont UI_APPEARANCE_SELECTOR; 22 | @property(nonatomic, strong, readwrite) UIFont *highlightedFont UI_APPEARANCE_SELECTOR; 23 | @property(nonatomic, strong, readwrite) UIColor *selectedFontColor UI_APPEARANCE_SELECTOR; 24 | @property(nonatomic, strong, readwrite) UIColor *deselectedFontColor UI_APPEARANCE_SELECTOR; 25 | @property(nonatomic, strong, readwrite) UIColor *disabledFontColor UI_APPEARANCE_SELECTOR; 26 | @property(nonatomic, strong, readwrite) UIColor *highlightedFontColor UI_APPEARANCE_SELECTOR; 27 | @property(nonatomic, strong, readwrite) UIColor *borderColor UI_APPEARANCE_SELECTOR; 28 | @property(nonatomic, readwrite) CGFloat borderWidth UI_APPEARANCE_SELECTOR; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Classes/ios/FUISegmentedControl.m: -------------------------------------------------------------------------------- 1 | // 2 | // FUISegmentedControl.m 3 | // FlatUIKitExample 4 | // 5 | // Created by Alex Medearis on 5/17/13. 6 | // 7 | // 8 | 9 | #import "FUISegmentedControl.h" 10 | #import "UIImage+FlatUI.h" 11 | #import "UIColor+FlatUI.h" 12 | #import "UIFont+FlatUI.h" 13 | 14 | @implementation FUISegmentedControl 15 | 16 | + (void)initialize { 17 | if (self == [FUISegmentedControl class]) { 18 | FUISegmentedControl *appearance = [self appearance]; 19 | [appearance setCornerRadius:5.0f]; 20 | [appearance setSelectedColor:[UIColor blueColor]]; 21 | [appearance setDeselectedColor:[UIColor darkGrayColor]]; 22 | [appearance setSelectedFontColor:[UIColor whiteColor]]; 23 | [appearance setDeselectedFontColor:[UIColor whiteColor]]; 24 | [appearance setHighlightedColor:[UIColor grayColor]]; 25 | [appearance setHighlightedFontColor:[UIColor whiteColor]]; 26 | } 27 | } 28 | 29 | - (void)setDeselectedColor:(UIColor *)deselectedColor { 30 | _deselectedColor = deselectedColor; 31 | [self configureFlatSegmentedControl]; 32 | } 33 | 34 | - (void)setSelectedColor:(UIColor *)selectedColor { 35 | _selectedColor = selectedColor; 36 | [self configureFlatSegmentedControl]; 37 | } 38 | 39 | - (void)setHighlightedColor:(UIColor *)highlightedColor { 40 | _highlightedColor = highlightedColor; 41 | [self configureFlatSegmentedControl]; 42 | } 43 | 44 | - (void)setDisabledColor:(UIColor *)disabledColor { 45 | _disabledColor = disabledColor; 46 | [self configureFlatSegmentedControl]; 47 | } 48 | 49 | - (void)setDividerColor:(UIColor *)dividerColor { 50 | _dividerColor = dividerColor; 51 | [self configureFlatSegmentedControl]; 52 | } 53 | 54 | - (void)setCornerRadius:(CGFloat)cornerRadius { 55 | _cornerRadius = cornerRadius; 56 | [self configureFlatSegmentedControl]; 57 | } 58 | 59 | - (void)setSelectedFont:(UIFont *)selectedFont { 60 | _selectedFont = selectedFont; 61 | [self setupFonts]; 62 | } 63 | 64 | - (void)setSelectedFontColor:(UIColor *)selectedFontColor { 65 | _selectedFontColor = selectedFontColor; 66 | [self setupFonts]; 67 | } 68 | 69 | - (void)setDeselectedFont:(UIFont *)deselectedFont { 70 | _deselectedFont = deselectedFont; 71 | [self setupFonts]; 72 | } 73 | 74 | - (void)setDeselectedFontColor:(UIColor *)deselectedFontColor { 75 | _deselectedFontColor = deselectedFontColor; 76 | [self setupFonts]; 77 | } 78 | 79 | - (void)setDisabledFont:(UIFont *)disabledFont { 80 | _disabledFont = disabledFont; 81 | [self setupFonts]; 82 | } 83 | 84 | - (void)setDisabledFontColor:(UIColor *)disabledFontColor { 85 | _disabledFontColor = disabledFontColor; 86 | [self setupFonts]; 87 | } 88 | 89 | - (void)setHighlightedFont:(UIFont *)highlightedFont { 90 | _highlightedFont = highlightedFont; 91 | [self setupFonts]; 92 | } 93 | 94 | - (void)setHighlightedFontColor:(UIColor *)highlightedFontColor { 95 | _highlightedFontColor = highlightedFontColor; 96 | [self setupFonts]; 97 | } 98 | 99 | - (void)setBorderColor:(UIColor *)borderColor { 100 | _borderColor = borderColor; 101 | [self configureFlatSegmentedControl]; 102 | } 103 | 104 | - (void)setBorderWidth:(CGFloat)borderWidth { 105 | _borderWidth = borderWidth; 106 | [self configureFlatSegmentedControl]; 107 | } 108 | 109 | - (void)setupFonts { 110 | // Although iOS 6 supports NSForegroundColorAttributeName, 111 | // it doesn't seem to apply it to deselected segments but will apply the 112 | // old UITextAttributeTextColor attribute. We therefore do a runtime version 113 | // check and use the old attributes when needed 114 | 115 | NSDictionary *selectedAttributesDictionary; 116 | 117 | if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) { 118 | NSShadow *shadow = [[NSShadow alloc] init]; 119 | [shadow setShadowOffset:CGSizeZero]; 120 | [shadow setShadowColor:[UIColor clearColor]]; 121 | selectedAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys: 122 | self.selectedFontColor, 123 | NSForegroundColorAttributeName, 124 | shadow, 125 | NSShadowAttributeName, 126 | self.selectedFont, 127 | NSFontAttributeName, 128 | nil]; 129 | } else { 130 | // iOS6- methods 131 | selectedAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys: 132 | self.selectedFontColor, 133 | UITextAttributeTextColor, 134 | [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0], 135 | UITextAttributeTextShadowColor, 136 | [NSValue valueWithUIOffset:UIOffsetMake(0, 0)], 137 | UITextAttributeTextShadowOffset, 138 | self.selectedFont, 139 | UITextAttributeFont, 140 | nil]; 141 | } 142 | 143 | [self setTitleTextAttributes:selectedAttributesDictionary forState:UIControlStateSelected]; 144 | 145 | NSDictionary *deselectedAttributesDictionary; 146 | if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) { 147 | // iOS7+ methods 148 | NSShadow *shadow = [[NSShadow alloc] init]; 149 | [shadow setShadowOffset:CGSizeZero]; 150 | [shadow setShadowColor:[UIColor clearColor]]; 151 | deselectedAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys: 152 | self.deselectedFontColor, 153 | NSForegroundColorAttributeName, 154 | shadow, 155 | NSShadowAttributeName, 156 | self.deselectedFont, 157 | NSFontAttributeName, 158 | nil]; 159 | } else { 160 | // iOS6- methods. 161 | deselectedAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys: 162 | self.deselectedFontColor, 163 | UITextAttributeTextColor, 164 | [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0], 165 | UITextAttributeTextShadowColor, 166 | [NSValue valueWithUIOffset:UIOffsetMake(0, 0)], 167 | UITextAttributeTextShadowOffset, 168 | self.deselectedFont, 169 | UITextAttributeFont, 170 | nil]; 171 | } 172 | [self setTitleTextAttributes:deselectedAttributesDictionary forState:UIControlStateNormal]; 173 | 174 | NSDictionary *disabledAttributesDictionary; 175 | if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) { 176 | // iOS7+ methods 177 | NSShadow *shadow = [[NSShadow alloc] init]; 178 | [shadow setShadowOffset:CGSizeZero]; 179 | [shadow setShadowColor:[UIColor clearColor]]; 180 | disabledAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys: 181 | self.disabledFontColor, 182 | NSForegroundColorAttributeName, 183 | shadow, 184 | NSShadowAttributeName, 185 | self.disabledFont, 186 | NSFontAttributeName, 187 | nil]; 188 | } else { 189 | // iOS6- methods 190 | disabledAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys: 191 | self.disabledFontColor, 192 | UITextAttributeTextColor, 193 | [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0], 194 | UITextAttributeTextShadowColor, 195 | [NSValue valueWithUIOffset:UIOffsetMake(0, 0)], 196 | UITextAttributeTextShadowOffset, 197 | self.disabledFont, 198 | UITextAttributeFont, 199 | nil]; 200 | } 201 | 202 | [self setTitleTextAttributes:disabledAttributesDictionary forState:UIControlStateDisabled]; 203 | 204 | 205 | NSDictionary *highlightedAttributesDictionary; 206 | if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) { 207 | // iOS7+ methods 208 | NSShadow *shadow = [[NSShadow alloc] init]; 209 | [shadow setShadowOffset:CGSizeZero]; 210 | [shadow setShadowColor:[UIColor clearColor]]; 211 | highlightedAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys: 212 | self.highlightedFontColor, 213 | NSForegroundColorAttributeName, 214 | shadow, 215 | NSShadowAttributeName, 216 | self.highlightedFont, 217 | NSFontAttributeName, 218 | nil]; 219 | } else { 220 | // iOS6- methods 221 | highlightedAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys: 222 | self.highlightedFontColor, 223 | UITextAttributeTextColor, 224 | [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0], 225 | UITextAttributeTextShadowColor, 226 | [NSValue valueWithUIOffset:UIOffsetMake(0, 0)], 227 | UITextAttributeTextShadowOffset, 228 | self.highlightedFont, 229 | UITextAttributeFont, 230 | nil]; 231 | } 232 | 233 | [self setTitleTextAttributes:highlightedAttributesDictionary forState:UIControlStateHighlighted]; 234 | } 235 | 236 | - (void)configureFlatSegmentedControl { 237 | UIImage *selectedBackgroundImage = [UIImage buttonImageWithColor:self.selectedColor 238 | cornerRadius:self.cornerRadius 239 | shadowColor:[UIColor clearColor] 240 | shadowInsets:UIEdgeInsetsMake(0, 0, 0, 0)]; 241 | UIImage *deselectedBackgroundImage = [UIImage buttonImageWithColor:self.deselectedColor 242 | cornerRadius:self.cornerRadius 243 | shadowColor:[UIColor clearColor] 244 | shadowInsets:UIEdgeInsetsMake(0, 0, 0, 0)]; 245 | UIImage *disabledBackgroundImage = [UIImage buttonImageWithColor:self.disabledColor 246 | cornerRadius:self.cornerRadius 247 | shadowColor:[UIColor clearColor] 248 | shadowInsets:UIEdgeInsetsMake(0, 0, 0, 0)]; 249 | UIImage *highlightedBackgroundImage = [UIImage buttonImageWithColor:self.highlightedColor 250 | cornerRadius:self.cornerRadius 251 | shadowColor:[UIColor clearColor] 252 | shadowInsets:UIEdgeInsetsMake(0, 0, 0, 0)]; 253 | 254 | UIColor *selectedColor = (self.dividerColor) ? self.dividerColor : self.selectedColor; 255 | UIColor *deselectedColor = (self.dividerColor) ? self.dividerColor : self.deselectedColor; 256 | UIImage *selectedDividerImage = [[UIImage imageWithColor:selectedColor cornerRadius:0] imageWithMinimumSize:CGSizeMake(1, 1)]; 257 | UIImage *deselectedDividerImage = [[UIImage imageWithColor:deselectedColor cornerRadius:0] imageWithMinimumSize:CGSizeMake(1, 1)]; 258 | 259 | 260 | [self setBackgroundImage:selectedBackgroundImage forState:UIControlStateSelected barMetrics:UIBarMetricsDefault]; 261 | [self setBackgroundImage:deselectedBackgroundImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 262 | [self setBackgroundImage:disabledBackgroundImage forState:UIControlStateDisabled barMetrics:UIBarMetricsDefault]; 263 | [self setBackgroundImage:highlightedBackgroundImage forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault]; 264 | 265 | [self setDividerImage:deselectedDividerImage forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 266 | [self setDividerImage:selectedDividerImage forLeftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 267 | [self setDividerImage:deselectedDividerImage forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected barMetrics:UIBarMetricsDefault]; 268 | [self setDividerImage:selectedDividerImage forLeftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateSelected barMetrics:UIBarMetricsDefault]; 269 | self.layer.borderWidth = self.borderWidth; 270 | self.layer.borderColor = self.borderColor.CGColor; 271 | self.layer.cornerRadius = self.cornerRadius; 272 | } 273 | 274 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 275 | NSInteger previousSelectedSegmentIndex = self.selectedSegmentIndex; 276 | [super touchesBegan:touches withEvent:event]; 277 | [self sendActionsForControlEvents:UIControlEventTouchDown]; 278 | if (!(NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)) { 279 | // before iOS7 the segment is selected in touchesBegan 280 | if (previousSelectedSegmentIndex == self.selectedSegmentIndex) { 281 | // if the selectedSegmentIndex before the selection process is equal to the selectedSegmentIndex 282 | // after the selection process the superclass won't send a UIControlEventValueChanged event. 283 | // So we have to do this ourselves. 284 | [self sendActionsForControlEvents:UIControlEventValueChanged]; 285 | } 286 | } 287 | } 288 | 289 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 290 | NSInteger previousSelectedSegmentIndex = self.selectedSegmentIndex; 291 | [super touchesEnded:touches withEvent:event]; 292 | [self sendActionsForControlEvents:UIControlEventTouchUpInside]; 293 | if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) { 294 | // on iOS7 the segment is selected in touchesEnded 295 | if (previousSelectedSegmentIndex == self.selectedSegmentIndex) { 296 | [self sendActionsForControlEvents:UIControlEventValueChanged]; 297 | } 298 | } 299 | } 300 | 301 | @end 302 | -------------------------------------------------------------------------------- /Classes/ios/FUISwitch.h: -------------------------------------------------------------------------------- 1 | // 2 | // FUISwitch.h 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/3/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FUISwitch : UIControl 12 | 13 | @property(nonatomic,getter=isOn) BOOL on; 14 | @property(nonatomic, strong, readwrite) UIColor *onBackgroundColor UI_APPEARANCE_SELECTOR; 15 | @property(nonatomic, strong, readwrite) UIColor *offBackgroundColor UI_APPEARANCE_SELECTOR; 16 | @property(nonatomic, strong, readwrite) UIColor *onColor UI_APPEARANCE_SELECTOR; 17 | @property(nonatomic, strong, readwrite) UIColor *offColor UI_APPEARANCE_SELECTOR; 18 | @property(nonatomic, strong, readwrite) UIColor *highlightedColor UI_APPEARANCE_SELECTOR; 19 | @property(nonatomic, readwrite) CGFloat switchCornerRadius UI_APPEARANCE_SELECTOR; 20 | @property(nonatomic, readwrite) CGFloat percentOn; 21 | @property(weak, readwrite, nonatomic) UILabel *offLabel; 22 | @property(weak, readwrite, nonatomic) UILabel *onLabel; 23 | 24 | - (void)setOn:(BOOL)on animated:(BOOL)animated; // does not send action 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Classes/ios/FUISwitch.m: -------------------------------------------------------------------------------- 1 | // 2 | // FUISwitch.m 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/3/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import "FUISwitch.h" 10 | #import "UIImage+FlatUI.h" 11 | #import "UIColor+FlatUI.h" 12 | #import 13 | 14 | @interface FUISwitch() 15 | @property(weak, readwrite, nonatomic) UIView *thumbView; 16 | @property(weak, readwrite, nonatomic) UIScrollView *internalContainer; 17 | @end 18 | 19 | @implementation FUISwitch 20 | 21 | - (id)initWithFrame:(CGRect)frame 22 | { 23 | self = [super initWithFrame:frame]; 24 | if (self) { 25 | [self sharedInit]; 26 | } 27 | return self; 28 | } 29 | 30 | - (id) initWithCoder:(NSCoder *)aDecoder { 31 | self = [super initWithCoder:aDecoder]; 32 | if (self) { 33 | [self sharedInit]; 34 | } 35 | return self; 36 | } 37 | 38 | - (void) sharedInit { 39 | self.clipsToBounds = YES; 40 | UIScrollView *internalContainer = [[UIScrollView alloc] init]; 41 | internalContainer.pagingEnabled = YES; 42 | internalContainer.showsHorizontalScrollIndicator = NO; 43 | internalContainer.showsVerticalScrollIndicator = NO; 44 | internalContainer.bounces = NO; 45 | internalContainer.userInteractionEnabled = NO; 46 | self.internalContainer = internalContainer; 47 | UILabel *offLabel = [[UILabel alloc] init]; 48 | UILabel *onLabel = [[UILabel alloc] init]; 49 | offLabel.backgroundColor = [UIColor clearColor]; 50 | onLabel.backgroundColor = [UIColor clearColor]; 51 | offLabel.textAlignment = NSTextAlignmentCenter; 52 | onLabel.textAlignment = NSTextAlignmentCenter; 53 | offLabel.text = @"OFF"; 54 | onLabel.text = @"ON"; 55 | self.offLabel = offLabel; 56 | self.onLabel = onLabel; 57 | [internalContainer addSubview:offLabel]; 58 | [internalContainer addSubview:onLabel]; 59 | UIView *thumbView = [[UIView alloc] init]; 60 | [internalContainer addSubview:thumbView]; 61 | self.thumbView = thumbView; 62 | [self addSubview:internalContainer]; 63 | 64 | UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panned:)]; 65 | panGestureRecognizer.cancelsTouchesInView = NO; 66 | [self addGestureRecognizer:panGestureRecognizer]; 67 | 68 | UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)]; 69 | [self addGestureRecognizer:tapGestureRecognizer]; 70 | _on = YES; 71 | _percentOn = 1; 72 | self.layer.cornerRadius = 3.0; 73 | } 74 | 75 | - (void) layoutSubviews { 76 | [super layoutSubviews]; 77 | 78 | //container 79 | CGSize size = self.frame.size; 80 | size.width *= 2; 81 | size.width -= self.frame.size.height; 82 | self.internalContainer.contentSize = size; 83 | self.internalContainer.frame = self.bounds; 84 | CGFloat contentHeight = self.internalContainer.contentSize.height; 85 | 86 | //thumb image 87 | CGFloat insetFraction = .75; 88 | CGFloat thumbEdgeSize = floorf(contentHeight * insetFraction); 89 | CGFloat thumbInset = (contentHeight - thumbEdgeSize) / 2; 90 | self.thumbView.frame = CGRectMake((self.internalContainer.contentSize.width - contentHeight) / 2 + thumbInset, thumbInset, thumbEdgeSize, thumbEdgeSize); 91 | self.thumbView.layer.cornerRadius = thumbEdgeSize / 2; 92 | 93 | //labels 94 | CGRect left = CGRectMake(0, 0, (self.internalContainer.contentSize.width - self.thumbView.frame.size.width)/2, contentHeight); 95 | CGRect right = left; 96 | right.origin.x = self.internalContainer.contentSize.width - left.size.width; 97 | self.offLabel.frame = right; 98 | self.onLabel.frame = left; 99 | [self setOn:_on]; 100 | } 101 | 102 | - (void) setOn:(BOOL)on { 103 | [self setOn:on animated:NO]; 104 | } 105 | 106 | - (void)setOn:(BOOL)on animated:(BOOL)animated { 107 | [self setOn:on animated:NO sendEvent:NO]; 108 | } 109 | 110 | - (void)setOn:(BOOL)on animated:(BOOL)animated sendEvent:(BOOL)sendEvent { 111 | if (_on != on) { 112 | _on = on; 113 | if (sendEvent) { 114 | [self sendActionsForControlEvents:UIControlEventValueChanged]; 115 | } 116 | } 117 | [self setPercentOn:_on * 1.0f animated:animated]; 118 | } 119 | 120 | - (void) setPercentOn:(CGFloat)percentOn { 121 | [self setPercentOn:percentOn animated:NO]; 122 | } 123 | 124 | - (void) setPercentOn:(CGFloat)percentOn animated:(BOOL)animated { 125 | _percentOn = percentOn; 126 | [self updateBackground]; 127 | CGFloat maxOffset = self.internalContainer.contentSize.width - self.frame.size.width; 128 | CGPoint newOffset = CGPointMake((1 - _percentOn) * maxOffset, 0); 129 | [self.internalContainer setContentOffset:newOffset animated:animated]; 130 | } 131 | 132 | - (void) panned:(UIPanGestureRecognizer *)gestureRecognizer { 133 | 134 | CGPoint translation = [gestureRecognizer translationInView:self.internalContainer]; 135 | [gestureRecognizer setTranslation:CGPointZero inView:self.internalContainer]; 136 | CGPoint newOffset = self.internalContainer.contentOffset; 137 | newOffset.x -= translation.x; 138 | CGFloat maxOffset = self.internalContainer.contentSize.width - self.frame.size.width; 139 | newOffset.x = MAX(newOffset.x, 0); 140 | newOffset.x = MIN(newOffset.x, maxOffset); 141 | 142 | if (gestureRecognizer.state == UIGestureRecognizerStateBegan || 143 | gestureRecognizer.state == UIGestureRecognizerStateChanged) { 144 | 145 | [self setPercentOn:(1 - newOffset.x/maxOffset) animated:NO]; 146 | 147 | } else if (gestureRecognizer.state == UIGestureRecognizerStateEnded) { 148 | BOOL left = newOffset.x > maxOffset / 2; 149 | [self setOn:(!left) animated:YES sendEvent:YES]; 150 | } 151 | 152 | } 153 | 154 | - (void) tapped:(UITapGestureRecognizer *)gestureRecognizer { 155 | [self setOn:!self.on animated:YES sendEvent:YES]; 156 | } 157 | 158 | - (void) setOnBackgroundColor:(UIColor *)onBackgroundColor { 159 | _onBackgroundColor = onBackgroundColor; 160 | [self updateBackground]; 161 | } 162 | 163 | - (void) setOffBackgroundColor:(UIColor *)offBackgroundColor { 164 | _offBackgroundColor = offBackgroundColor; 165 | [self updateBackground]; 166 | } 167 | 168 | - (void) setOnColor:(UIColor *)onColor { 169 | _onColor = onColor; 170 | [self updateBackground]; 171 | } 172 | 173 | - (void) setOffColor:(UIColor *)offColor { 174 | _offColor = offColor; 175 | [self updateBackground]; 176 | } 177 | 178 | - (void) setSwitchCornerRadius:(CGFloat)switchCornerRadius { 179 | _switchCornerRadius = switchCornerRadius; 180 | self.layer.cornerRadius = _switchCornerRadius; 181 | } 182 | 183 | - (void) updateBackground { 184 | self.backgroundColor = [UIColor blendedColorWithForegroundColor:self.onBackgroundColor 185 | backgroundColor:self.offBackgroundColor 186 | percentBlend:self.percentOn]; 187 | UIColor *contentColor = [UIColor blendedColorWithForegroundColor:self.onColor 188 | backgroundColor:self.offColor 189 | percentBlend:self.percentOn]; 190 | self.onLabel.textColor = contentColor; 191 | self.offLabel.textColor = contentColor; 192 | self.thumbView.backgroundColor = contentColor; 193 | } 194 | 195 | - (void)setHighlighted:(BOOL)highlighted { 196 | [super setHighlighted:highlighted]; 197 | 198 | if (highlighted) 199 | self.backgroundColor = self.highlightedColor; 200 | } 201 | 202 | - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 203 | [super touchesBegan:touches withEvent:event]; 204 | [self setHighlighted:YES]; 205 | } 206 | 207 | @end 208 | -------------------------------------------------------------------------------- /Classes/ios/FUITextField.h: -------------------------------------------------------------------------------- 1 | // 2 | // FUITextField.h 3 | // FlatUI 4 | // 5 | // Created by Andrej Mihajlov on 8/25/13. 6 | // Copyright (c) 2013 Andrej Mihajlov. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FUITextField : UITextField 12 | 13 | @property (nonatomic, assign) UIEdgeInsets edgeInsets UI_APPEARANCE_SELECTOR; 14 | @property (nonatomic, strong) UIColor *textFieldColor UI_APPEARANCE_SELECTOR; 15 | @property (nonatomic, strong) UIColor *borderColor UI_APPEARANCE_SELECTOR; 16 | @property (nonatomic, assign) CGFloat borderWidth UI_APPEARANCE_SELECTOR; 17 | @property (nonatomic, assign) CGFloat cornerRadius UI_APPEARANCE_SELECTOR; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Classes/ios/FUITextField.m: -------------------------------------------------------------------------------- 1 | // 2 | // FUITextField.m 3 | // FlatUI 4 | // 5 | // Created by Andrej Mihajlov on 8/25/13. 6 | // Copyright (c) 2013 Andrej Mihajlov. All rights reserved. 7 | // 8 | 9 | #import "FUITextField.h" 10 | #import "UIImage+FlatUI.h" 11 | 12 | @implementation FUITextField { 13 | UIImage* _flatBackgroundImage; 14 | UIImage* _flatHighlightedBackgroundImage; 15 | } 16 | 17 | - (void)setTextFieldColor:(UIColor *)textFieldColor { 18 | _textFieldColor = textFieldColor; 19 | [self configureTextField]; 20 | } 21 | 22 | - (void)setBorderColor:(UIColor *)borderColor { 23 | _borderColor = borderColor; 24 | [self configureTextField]; 25 | } 26 | 27 | - (void)setBorderWidth:(CGFloat)borderWidth { 28 | _borderWidth = borderWidth; 29 | [self configureTextField]; 30 | } 31 | 32 | - (void)setCornerRadius:(CGFloat)cornerRadius { 33 | _cornerRadius = cornerRadius; 34 | [self configureTextField]; 35 | } 36 | 37 | - (void)setTextColor:(UIColor *)textColor { 38 | [super setTextColor:textColor]; 39 | 40 | // Setup placeholder color with 60% alpha of original text color 41 | if([self respondsToSelector:@selector(setAttributedPlaceholder:)] && self.placeholder) { 42 | self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder attributes:@{ NSForegroundColorAttributeName: [self.textColor colorWithAlphaComponent:.6] }]; 43 | } 44 | } 45 | 46 | - (void)configureTextField { 47 | _flatBackgroundImage = [self textFieldImageWithColor:_textFieldColor borderColor:_borderColor borderWidth:0 cornerRadius:_cornerRadius]; 48 | _flatHighlightedBackgroundImage = [self textFieldImageWithColor:_textFieldColor borderColor:_borderColor borderWidth:_borderWidth cornerRadius:_cornerRadius]; 49 | 50 | [self setBackground:_flatBackgroundImage]; 51 | } 52 | 53 | // A helper method to draw a simple rounded rectangle image that can be used as background 54 | - (UIImage*)textFieldImageWithColor:(UIColor*)color borderColor:(UIColor*)borderColor 55 | borderWidth:(CGFloat)borderWidth cornerRadius:(CGFloat)cornerRadius { 56 | CGRect rect = CGRectMake(0, 0, 44, 44); 57 | UIBezierPath* bezierPath = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(rect, borderWidth, borderWidth) cornerRadius:cornerRadius]; 58 | 59 | UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0f); 60 | CGContextRef ctx = UIGraphicsGetCurrentContext(); 61 | 62 | [color setFill]; 63 | [borderColor setStroke]; 64 | 65 | CGContextSetLineWidth(ctx, borderWidth); 66 | CGContextAddPath(ctx, [bezierPath CGPath]); 67 | CGContextDrawPath(ctx, kCGPathFillStroke); 68 | 69 | UIImage* output = UIGraphicsGetImageFromCurrentImageContext(); 70 | UIGraphicsEndImageContext(); 71 | 72 | return [output resizableImageWithCapInsets:UIEdgeInsetsMake(cornerRadius*2, cornerRadius*2, cornerRadius*2, cornerRadius*2)]; 73 | } 74 | 75 | // Both methods make some space around text 76 | - (CGRect)textRectForBounds:(CGRect)bounds { 77 | return [super textRectForBounds:UIEdgeInsetsInsetRect(bounds, self.edgeInsets)]; 78 | } 79 | 80 | - (CGRect)editingRectForBounds:(CGRect)bounds { 81 | return [super editingRectForBounds:UIEdgeInsetsInsetRect(bounds, self.edgeInsets)]; 82 | } 83 | 84 | - (CGRect)leftViewRectForBounds:(CGRect)bounds { 85 | bounds.origin.x += self.edgeInsets.left; 86 | return [super leftViewRectForBounds:bounds]; 87 | } 88 | 89 | - (CGRect)rightViewRectForBounds:(CGRect)bounds { 90 | bounds.origin.x -= self.edgeInsets.right; 91 | return [super rightViewRectForBounds:bounds]; 92 | } 93 | 94 | // Switch background image to bordered image 95 | - (BOOL)becomeFirstResponder { 96 | BOOL flag = [super becomeFirstResponder]; 97 | if(flag) { 98 | self.background = _flatHighlightedBackgroundImage; 99 | } 100 | return flag; 101 | } 102 | 103 | // Switch background image to borderless image 104 | - (BOOL)resignFirstResponder { 105 | BOOL flag = [super resignFirstResponder]; 106 | if(flag) { 107 | self.background = _flatBackgroundImage; 108 | } 109 | return flag; 110 | } 111 | 112 | @end 113 | -------------------------------------------------------------------------------- /Classes/ios/FlatUIKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // FlatUIKit.h 3 | // FlatUI 4 | // 5 | // Created by Keisuke Kimura on 6/8/13. 6 | // Copyright (c) 2013 Keisuke Kimura. All rights reserved. 7 | // 8 | 9 | #ifndef FlatUI_FlatUIKit_h 10 | #define FlatUI_FlatUIKit_h 11 | 12 | #if TARGET_OS_IPHONE 13 | #import 14 | #import 15 | #endif 16 | 17 | #endif 18 | 19 | #import "FUIAlertView.h" 20 | #import "FUIButton.h" 21 | #import "FUITextField.h" 22 | #import "FUICellBackgroundView.h" 23 | #import "FUISegmentedControl.h" 24 | #import "FUISwitch.h" 25 | #import "UIBarButtonItem+FlatUI.h" 26 | #import "UIColor+FlatUI.h" 27 | #import "UIFont+FlatUI.h" 28 | #import "UIImage+FlatUI.h" 29 | #import "UINavigationBar+FlatUI.h" 30 | #import "UIProgressView+FlatUI.h" 31 | #import "UIStepper+FlatUI.h" 32 | #import "UISlider+FlatUI.h" 33 | #import "UITabBar+FlatUI.h" 34 | #import "UITableViewCell+FlatUI.h" 35 | #import "UIToolbar+FlatUI.h" -------------------------------------------------------------------------------- /Classes/ios/NSString+Icons.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Icons.h 3 | // FlatUIKitExample 4 | // 5 | // Created by Jamie Matthews on 12/24/14. 6 | // 7 | // 8 | 9 | #import 10 | typedef NS_ENUM(NSInteger, FlatUIIcon) { 11 | FUITriangleUp, 12 | FUITraingleDown, 13 | FUITriangleUpSmall, 14 | FUITriangleDownSmall, 15 | FUITriangleLeftLarge, 16 | FUITriangleRightLarge, 17 | FUIArrowLeft, 18 | FUIArrowRight, 19 | FUIPlus, 20 | FUICross, 21 | FUICheck, 22 | FUIRadioUnchecked, 23 | FUIRadioChecked, 24 | FUICheckboxUnchecked, 25 | FUICheckboxChecked, 26 | FUIInfoCircle, 27 | FUIAlertCircle, 28 | FUIQuestionCirlce, 29 | FUICheckCircle, 30 | FUICrossCircle, 31 | FUIPlusCircle, 32 | FUIPause, 33 | FUIPlay, 34 | FUIVolume, 35 | FUIMute, 36 | FUIResize, 37 | FUIList, 38 | FUIListThumbnailed, 39 | FUIListSmallThumbails, 40 | FUIListLargeThumnails, 41 | FUIListNumbered, 42 | FUIListColumned, 43 | FUIListBulleted, 44 | FUIWindow, 45 | FUIWindows, 46 | FUILoop, 47 | FUICMD, 48 | FUIMic, 49 | FUIHeart, 50 | FUILocation, 51 | FUINew, 52 | FUIVideo, 53 | FUIPhoto, 54 | FUITime, 55 | FUIEye, 56 | FUIChat, 57 | FUIHome, 58 | FUIUpload, 59 | FUISearch, 60 | FUIUser, 61 | FUIMail, 62 | FUILock, 63 | FUIPower, 64 | FUICalendar, 65 | FUIGear, 66 | FUIBookmark, 67 | FUIExit, 68 | FUITrash, 69 | FUIFolder, 70 | FUIBubble, 71 | FUIExport, 72 | FUICalendarSolid, 73 | FUIStar, 74 | FUIStar2, 75 | FUICreditCard, 76 | FUIClip, 77 | FUILink, 78 | FUITag, 79 | FUIDocument, 80 | FUIImage, 81 | FUIFacebook, 82 | FUIYoutube, 83 | FUIVimeo, 84 | FUITwitter, 85 | FUISpotify, 86 | FUISkype, 87 | FUIPintrest, 88 | FUIPath, 89 | FUILinkedin, 90 | FUIGooglePlus, 91 | FUIDribble, 92 | FUIBehance, 93 | FUIStumbleUpon, 94 | FUIYelp, 95 | FUIWordpress, 96 | FUIWindows8, 97 | FUIVine, 98 | FUITumblr, 99 | FUIPaypal, 100 | FUILastFM, 101 | FUIInstagram, 102 | FUIHtml5, 103 | FUIGithub, 104 | FUIFourSquare, 105 | FUIDropBox, 106 | FUIAndroid, 107 | FUIApple, 108 | 109 | }; 110 | 111 | static NSString *const kFlatUIFontFamilyName = @"flat-ui-pro-icons"; 112 | 113 | @interface NSString (Icons) 114 | + (NSString*)iconStringForEnum:(FlatUIIcon)value; 115 | + (NSArray *)iconUnicodeStrings; 116 | @end 117 | -------------------------------------------------------------------------------- /Classes/ios/NSString+Icons.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Icons.m 3 | // FlatUIKitExample 4 | // 5 | // Created by Jamie Matthews on 12/24/14. 6 | // 7 | // Credit to https://github.com/designmodo/Flat-UI 8 | // for the aweseome flat icons! 9 | 10 | #import "NSString+Icons.h" 11 | 12 | 13 | @implementation NSString (Icons) 14 | + (NSString*)iconStringForEnum:(FlatUIIcon)value { 15 | NSString *toReturn = [NSString iconUnicodeStrings][value]; 16 | return toReturn; 17 | } 18 | 19 | + (NSArray *)iconUnicodeStrings { 20 | 21 | static NSArray *iconUnicodeStrings; 22 | 23 | static dispatch_once_t unicodeStringsOnceToken; 24 | dispatch_once(&unicodeStringsOnceToken, ^{ 25 | 26 | iconUnicodeStrings = @[@"\ue600", @"\ue601", @"\ue602", @"\ue603", @"\ue604", @"\ue605", @"\ue606", @"\ue607", @"\ue608", @"\ue609", @"\ue60a", @"\ue60b", @"\ue60c", @"\ue60d", @"\ue60e", @"\ue60f", @"\ue610", @"\ue611", @"\ue612", @"\ue613", @"\ue614", @"\ue615", @"\ue616", @"\ue617", @"\ue618", @"\ue619", @"\ue61a", @"\ue61b", @"\ue61c", @"\ue61d", @"\ue61e", @"\ue61f", @"\ue620", @"\ue621", @"\ue622", @"\ue623", @"\ue624", @"\ue625", @"\ue626", @"\ue627", @"\ue628", @"\ue629", @"\ue62a", @"\ue62b", @"\ue62c", @"\ue62d", @"\ue62e", @"\ue62f", @"\ue630", @"\ue631", @"\ue632", @"\ue633", @"\ue634", @"\ue635", @"\ue636", @"\ue637", @"\ue638", @"\ue639", @"\ue63a", @"\ue63b", @"\ue63c", @"\ue63d", @"\ue63e", @"\ue63f", @"\ue640", @"\ue641", @"\ue642", @"\ue643", @"\ue644", @"\ue645", @"\ue646", @"\ue647", @"\ue648", @"\ue649", @"\ue64a", @"\ue64b", @"\ue64c", @"\ue64d", @"\ue64e", @"\ue64f", @"\ue650", @"\ue651", @"\ue652", @"\ue653", @"\ue654", @"\ue655", @"\ue656", @"\ue657", @"\ue658", @"\ue659", @"\ue65a", @"\ue65b", @"\ue65c", @"\ua65d", @"\ue65e", @"\ue65f", @"\ue660"]; 27 | 28 | }); 29 | 30 | return iconUnicodeStrings; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Classes/ios/UIBarButtonItem+FlatUI.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIBarButtonItem+FlatUI.h 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/8/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIBarButtonItem (FlatUI) 12 | 13 | // styles a single bar button item 14 | - (void) configureFlatButtonWithColor:(UIColor *)color 15 | highlightedColor:(UIColor *)highlightedColor 16 | cornerRadius:(CGFloat) cornerRadius UI_APPEARANCE_SELECTOR; 17 | 18 | // styles all bar button items that exist within a class heirarchy (same as UIAppearanceProxy methods) 19 | + (void) configureFlatButtonsWithColor:(UIColor *) color 20 | highlightedColor:(UIColor *)highlightedColor 21 | cornerRadius:(CGFloat) cornerRadius 22 | whenContainedIn:(Class )containerClass, ... NS_REQUIRES_NIL_TERMINATION; 23 | 24 | // styles all bar button items (can be overwritten with the above methods) 25 | + (void) configureFlatButtonsWithColor:(UIColor *) color 26 | highlightedColor:(UIColor *)highlightedColor 27 | cornerRadius:(CGFloat) cornerRadius; 28 | 29 | 30 | // removes the text shadows off a single bar button item (sadly, this can't be easily done for all buttons simultaneously) 31 | - (void) removeTitleShadow; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Classes/ios/UIBarButtonItem+FlatUI.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIBarButtonItem+FlatUI.m 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/8/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import "UIBarButtonItem+FlatUI.h" 10 | #import "UIImage+FlatUI.h" 11 | 12 | @implementation UIBarButtonItem (FlatUI) 13 | 14 | - (void) configureFlatButtonWithColor:(UIColor *)color 15 | highlightedColor:(UIColor *)highlightedColor 16 | cornerRadius:(CGFloat) cornerRadius { 17 | [UIBarButtonItem configureItemOrProxy:self forFlatButtonWithColor:color highlightedColor:highlightedColor cornerRadius:cornerRadius]; 18 | } 19 | 20 | + (void) configureFlatButtonsWithColor:(UIColor *) color 21 | highlightedColor:(UIColor *)highlightedColor 22 | cornerRadius:(CGFloat) cornerRadius { 23 | [self configureFlatButtonsWithColor:color highlightedColor:highlightedColor cornerRadius:cornerRadius whenContainedIn:[UINavigationBar class], [UINavigationController class], [UIToolbar class], nil]; 24 | } 25 | 26 | + (void) configureFlatButtonsWithColor:(UIColor *) color 27 | highlightedColor:(UIColor *)highlightedColor 28 | cornerRadius:(CGFloat) cornerRadius 29 | whenContainedIn:(Class )containerClass, ... { 30 | va_list vl; 31 | va_start(vl, containerClass); 32 | id appearance = [UIBarButtonItem appearanceWhenContainedIn:containerClass, nil]; 33 | va_end(vl); 34 | [UIBarButtonItem configureItemOrProxy:appearance forFlatButtonWithColor:color highlightedColor:highlightedColor cornerRadius:cornerRadius]; 35 | } 36 | 37 | // only used pre-ios7 38 | - (void) removeTitleShadow { 39 | 40 | if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_6_1) { 41 | NSArray *states = @[@(UIControlStateNormal), @(UIControlStateHighlighted)]; 42 | 43 | for (NSNumber *state in states) { 44 | UIControlState controlState = [state unsignedIntegerValue]; 45 | NSMutableDictionary *titleTextAttributes = [[self titleTextAttributesForState:controlState] mutableCopy]; 46 | if (!titleTextAttributes) { 47 | titleTextAttributes = [NSMutableDictionary dictionary]; 48 | } 49 | 50 | // iOS6+ methods 51 | NSShadow *shadow = [[NSShadow alloc] init]; 52 | [shadow setShadowOffset:CGSizeZero]; 53 | [shadow setShadowColor:[UIColor clearColor]]; 54 | [titleTextAttributes setObject:shadow forKey:NSShadowAttributeName]; 55 | 56 | [self setTitleTextAttributes:titleTextAttributes forState:controlState]; 57 | } 58 | } 59 | } 60 | 61 | //helper method, basically a wrapper to allow creating a custom UIAppearance method that doesn't conform to the usual naming style 62 | + (void) configureItemOrProxy:(id)appearance 63 | forFlatButtonWithColor:(UIColor *)color 64 | highlightedColor:(UIColor *)highlightedColor 65 | cornerRadius:(CGFloat) cornerRadius { 66 | UIImage *backButtonPortraitImage = [UIImage backButtonImageWithColor:color 67 | barMetrics:UIBarMetricsDefault 68 | cornerRadius:cornerRadius]; 69 | UIImage *highlightedBackButtonPortraitImage = [UIImage backButtonImageWithColor:highlightedColor 70 | barMetrics:UIBarMetricsDefault 71 | cornerRadius:cornerRadius]; 72 | UIImage *backButtonLandscapeImage = [UIImage backButtonImageWithColor:color 73 | barMetrics:UIBarMetricsLandscapePhone 74 | cornerRadius:2]; 75 | UIImage *highlightedBackButtonLandscapeImage = [UIImage backButtonImageWithColor:highlightedColor 76 | barMetrics:UIBarMetricsLandscapePhone 77 | cornerRadius:2]; 78 | 79 | [appearance setBackButtonBackgroundImage:backButtonPortraitImage 80 | forState:UIControlStateNormal 81 | barMetrics:UIBarMetricsDefault]; 82 | [appearance setBackButtonBackgroundImage:backButtonLandscapeImage 83 | forState:UIControlStateNormal 84 | barMetrics:UIBarMetricsLandscapePhone]; 85 | [appearance setBackButtonBackgroundImage:highlightedBackButtonPortraitImage 86 | forState:UIControlStateHighlighted 87 | barMetrics:UIBarMetricsDefault]; 88 | [appearance setBackButtonBackgroundImage:highlightedBackButtonLandscapeImage 89 | forState:UIControlStateHighlighted 90 | barMetrics:UIBarMetricsLandscapePhone]; 91 | 92 | [appearance setBackButtonTitlePositionAdjustment:UIOffsetMake(1.0f, 1.0f) forBarMetrics:UIBarMetricsDefault]; 93 | [appearance setBackButtonTitlePositionAdjustment:UIOffsetMake(1.0f, 1.0f) forBarMetrics:UIBarMetricsLandscapePhone]; 94 | 95 | UIImage *buttonImageNormal = [UIImage imageWithColor:color cornerRadius:cornerRadius]; 96 | UIImage *buttonImageHightlighted = [UIImage imageWithColor:highlightedColor cornerRadius:cornerRadius]; 97 | [appearance setBackgroundImage:buttonImageNormal forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 98 | [appearance setBackgroundImage:buttonImageHightlighted forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault]; 99 | } 100 | 101 | @end 102 | -------------------------------------------------------------------------------- /Classes/ios/UIColor+FlatUI.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+FlatUI.h 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/3/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIColor (FlatUI) 12 | 13 | + (UIColor *) colorFromHexCode:(NSString *)hexString; 14 | + (UIColor *) turquoiseColor; 15 | + (UIColor *) greenSeaColor; 16 | + (UIColor *) emerlandColor; 17 | + (UIColor *) nephritisColor; 18 | + (UIColor *) peterRiverColor; 19 | + (UIColor *) belizeHoleColor; 20 | + (UIColor *) amethystColor; 21 | + (UIColor *) wisteriaColor; 22 | + (UIColor *) wetAsphaltColor; 23 | + (UIColor *) midnightBlueColor; 24 | + (UIColor *) sunflowerColor; 25 | + (UIColor *) tangerineColor; 26 | + (UIColor *) carrotColor; 27 | + (UIColor *) pumpkinColor; 28 | + (UIColor *) alizarinColor; 29 | + (UIColor *) pomegranateColor; 30 | + (UIColor *) cloudsColor; 31 | + (UIColor *) silverColor; 32 | + (UIColor *) concreteColor; 33 | + (UIColor *) asbestosColor; 34 | 35 | + (UIColor *) blendedColorWithForegroundColor:(UIColor *)foregroundColor 36 | backgroundColor:(UIColor *)backgroundColor 37 | percentBlend:(CGFloat) percentBlend; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Classes/ios/UIColor+FlatUI.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+FlatUI.m 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/3/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import "UIColor+FlatUI.h" 10 | 11 | @implementation UIColor (FlatUI) 12 | 13 | // Thanks to http://stackoverflow.com/questions/3805177/how-to-convert-hex-rgb-color-codes-to-uicolor 14 | + (UIColor *) colorFromHexCode:(NSString *)hexString { 15 | NSString *cleanString = [hexString stringByReplacingOccurrencesOfString:@"#" withString:@""]; 16 | if ([cleanString length] == 3) { 17 | cleanString = [NSString stringWithFormat:@"%@%@%@%@%@%@", 18 | [cleanString substringWithRange:NSMakeRange(0, 1)],[cleanString substringWithRange:NSMakeRange(0, 1)], 19 | [cleanString substringWithRange:NSMakeRange(1, 1)],[cleanString substringWithRange:NSMakeRange(1, 1)], 20 | [cleanString substringWithRange:NSMakeRange(2, 1)],[cleanString substringWithRange:NSMakeRange(2, 1)]]; 21 | } 22 | if([cleanString length] == 6) { 23 | cleanString = [cleanString stringByAppendingString:@"ff"]; 24 | } 25 | 26 | unsigned int baseValue; 27 | [[NSScanner scannerWithString:cleanString] scanHexInt:&baseValue]; 28 | 29 | float red = ((baseValue >> 24) & 0xFF)/255.0f; 30 | float green = ((baseValue >> 16) & 0xFF)/255.0f; 31 | float blue = ((baseValue >> 8) & 0xFF)/255.0f; 32 | float alpha = ((baseValue >> 0) & 0xFF)/255.0f; 33 | 34 | return [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; 35 | } 36 | 37 | + (UIColor *) turquoiseColor { 38 | static UIColor *turquoise = nil; 39 | static dispatch_once_t dispatchToken; 40 | 41 | dispatch_once(&dispatchToken, ^{ 42 | turquoise = [UIColor colorFromHexCode:@"1ABC9C"]; 43 | }); 44 | 45 | return turquoise; 46 | } 47 | 48 | + (UIColor *) greenSeaColor { 49 | static UIColor *greenSea = nil; 50 | static dispatch_once_t greenToken; 51 | 52 | dispatch_once(&greenToken, ^{ 53 | greenSea = [UIColor colorFromHexCode:@"16A085"]; 54 | }); 55 | 56 | return greenSea; 57 | } 58 | 59 | + (UIColor *) emerlandColor { 60 | static UIColor *emerald = nil; 61 | static dispatch_once_t emeraldToken; 62 | 63 | dispatch_once(&emeraldToken, ^{ 64 | emerald = [UIColor colorFromHexCode:@"2ECC71"]; 65 | }); 66 | 67 | return emerald; 68 | } 69 | 70 | + (UIColor *) nephritisColor { 71 | static UIColor *nephritis = nil; 72 | static dispatch_once_t nephritisToken; 73 | 74 | dispatch_once(&nephritisToken, ^{ 75 | nephritis = [UIColor colorFromHexCode:@"27AE60"]; 76 | }); 77 | 78 | return nephritis; 79 | } 80 | 81 | + (UIColor *) peterRiverColor { 82 | static UIColor *peterRiver = nil; 83 | static dispatch_once_t peterToken; 84 | 85 | dispatch_once(&peterToken, ^{ 86 | peterRiver = [UIColor colorFromHexCode:@"#3498DB"]; 87 | }); 88 | 89 | return peterRiver; 90 | } 91 | 92 | + (UIColor *) belizeHoleColor { 93 | static UIColor *tripToBelize = nil; // Let's cook! 94 | static dispatch_once_t belizeToken; 95 | 96 | dispatch_once(&belizeToken, ^{ 97 | tripToBelize = [UIColor colorFromHexCode:@"2980B9"]; 98 | }); 99 | 100 | return tripToBelize; 101 | } 102 | 103 | + (UIColor *) amethystColor { 104 | static UIColor *amethyst = nil; 105 | static dispatch_once_t amethystToken; 106 | 107 | dispatch_once(&amethystToken, ^{ 108 | amethyst = [UIColor colorFromHexCode:@"9B59B6"]; 109 | }); 110 | 111 | return amethyst; 112 | } 113 | 114 | + (UIColor *) wisteriaColor { 115 | static UIColor *wisteria = nil; 116 | static dispatch_once_t wisteriaToken; 117 | 118 | dispatch_once(&wisteriaToken, ^{ 119 | wisteria = [UIColor colorFromHexCode:@"8E44AD"]; 120 | }); 121 | 122 | return wisteria; 123 | } 124 | 125 | + (UIColor *) wetAsphaltColor { 126 | static UIColor *asphalt = nil; 127 | static dispatch_once_t asphaltToken; 128 | 129 | dispatch_once(&asphaltToken, ^{ 130 | asphalt = [UIColor colorFromHexCode:@"34495E"]; 131 | }); 132 | 133 | return asphalt; 134 | } 135 | 136 | + (UIColor *) midnightBlueColor { 137 | static UIColor *midnightBlue = nil; 138 | static dispatch_once_t midnightBlueToken; 139 | 140 | dispatch_once(&midnightBlueToken, ^{ 141 | midnightBlue = [UIColor colorFromHexCode:@"2C3E50"]; 142 | }); 143 | 144 | return midnightBlue; 145 | } 146 | 147 | + (UIColor *) sunflowerColor { 148 | static UIColor *sunflower = nil; 149 | static dispatch_once_t sunflowerToken; 150 | 151 | dispatch_once(&sunflowerToken, ^{ 152 | sunflower = [UIColor colorFromHexCode:@"F1C40F"]; 153 | }); 154 | 155 | return sunflower; 156 | } 157 | 158 | + (UIColor *) tangerineColor { 159 | static UIColor *tangerine = nil; 160 | static dispatch_once_t tangerineToken; 161 | 162 | dispatch_once(&tangerineToken, ^{ 163 | tangerine = [UIColor colorFromHexCode:@"F39C12"]; 164 | }); 165 | 166 | return tangerine; 167 | } 168 | 169 | + (UIColor *) carrotColor { 170 | static UIColor *carrot = nil; 171 | static dispatch_once_t carrotToken; 172 | 173 | dispatch_once(&carrotToken, ^{ 174 | carrot = [UIColor colorFromHexCode:@"E67E22"]; 175 | }); 176 | 177 | return carrot; 178 | } 179 | 180 | + (UIColor *) pumpkinColor { 181 | static UIColor *pumpkin = nil; 182 | static dispatch_once_t pumpkinToken; 183 | 184 | dispatch_once(&pumpkinToken, ^{ 185 | pumpkin = [UIColor colorFromHexCode:@"D35400"]; 186 | }); 187 | 188 | return pumpkin; 189 | } 190 | 191 | + (UIColor *) alizarinColor { 192 | static UIColor *alizarin = nil; 193 | static dispatch_once_t alizarinToken; 194 | 195 | dispatch_once(&alizarinToken, ^{ 196 | alizarin = [UIColor colorFromHexCode:@"E74C3C"]; 197 | }); 198 | 199 | return alizarin; 200 | } 201 | 202 | + (UIColor *) pomegranateColor { 203 | static UIColor *pomegranate = nil; 204 | static dispatch_once_t pomegranateToken; 205 | 206 | dispatch_once(&pomegranateToken, ^{ 207 | pomegranate = [UIColor colorFromHexCode:@"C0392B"]; 208 | }); 209 | 210 | return pomegranate; 211 | } 212 | 213 | + (UIColor *) cloudsColor { 214 | static UIColor *clouds = nil; 215 | static dispatch_once_t cloudsToken; 216 | 217 | dispatch_once(&cloudsToken, ^{ 218 | clouds = [UIColor colorFromHexCode:@"ECF0F1"]; 219 | }); 220 | 221 | return clouds; 222 | } 223 | 224 | + (UIColor *) silverColor { 225 | static UIColor *silver = nil; 226 | static dispatch_once_t silverToken; 227 | 228 | dispatch_once(&silverToken, ^{ 229 | silver = [UIColor colorFromHexCode:@"BDC3C7"]; 230 | }); 231 | 232 | return silver; 233 | } 234 | 235 | + (UIColor *) concreteColor { 236 | static UIColor *concrete = nil; 237 | static dispatch_once_t concreteToken; 238 | 239 | dispatch_once(&concreteToken, ^{ 240 | concrete = [UIColor colorFromHexCode:@"95A5A6"]; 241 | }); 242 | 243 | return concrete; 244 | } 245 | 246 | + (UIColor *) asbestosColor { 247 | static UIColor *asbestos = nil; 248 | static dispatch_once_t asbestosToken; 249 | 250 | dispatch_once(&asbestosToken, ^{ 251 | asbestos = [UIColor colorFromHexCode:@"7F8C8D"]; 252 | }); 253 | 254 | return asbestos; 255 | } 256 | 257 | + (UIColor *) blendedColorWithForegroundColor:(UIColor *)foregroundColor 258 | backgroundColor:(UIColor *)backgroundColor 259 | percentBlend:(CGFloat) percentBlend { 260 | CGFloat onRed, offRed, newRed, onGreen, offGreen, newGreen, onBlue, offBlue, newBlue, onWhite, offWhite; 261 | if (![foregroundColor getRed:&onRed green:&onGreen blue:&onBlue alpha:nil]) { 262 | [foregroundColor getWhite:&onWhite alpha:nil]; 263 | onRed = onWhite; 264 | onBlue = onWhite; 265 | onGreen = onWhite; 266 | } 267 | if (![backgroundColor getRed:&offRed green:&offGreen blue:&offBlue alpha:nil]) { 268 | [backgroundColor getWhite:&offWhite alpha:nil]; 269 | offRed = offWhite; 270 | offBlue = offWhite; 271 | offGreen = offWhite; 272 | } 273 | newRed = onRed * percentBlend + offRed * (1-percentBlend); 274 | newGreen = onGreen * percentBlend + offGreen * (1-percentBlend); 275 | newBlue = onBlue * percentBlend + offBlue * (1-percentBlend); 276 | return [UIColor colorWithRed:newRed green:newGreen blue:newBlue alpha:1.0]; 277 | } 278 | 279 | @end 280 | -------------------------------------------------------------------------------- /Classes/ios/UIFont+FlatUI.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIFont+FlatUI.h 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/7/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIFont (FlatUI) 12 | 13 | + (UIFont *)flatFontOfSize:(CGFloat)size; 14 | + (UIFont *)boldFlatFontOfSize:(CGFloat)size; 15 | + (UIFont *)italicFlatFontOfSize:(CGFloat)size; 16 | + (UIFont *)lightFlatFontOfSize:(CGFloat)size; 17 | + (UIFont *)iconFontWithSize:(CGFloat)size; 18 | @end 19 | -------------------------------------------------------------------------------- /Classes/ios/UIFont+FlatUI.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIFont+FlatUI.m 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/7/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import "UIFont+FlatUI.h" 10 | #import 11 | #import "NSString+Icons.h" 12 | 13 | @implementation UIFont (FlatUI) 14 | 15 | + (void) initialize { 16 | [super initialize]; 17 | static dispatch_once_t onceToken; 18 | dispatch_once(&onceToken, ^{ 19 | NSArray *fontNames = @[@"Lato-Regular", @"Lato-Bold", @"Lato-Italic", @"Lato-Light"]; 20 | for (NSString *fontName in fontNames) { 21 | NSURL * url = [[NSBundle mainBundle] URLForResource:fontName withExtension:@"ttf"]; 22 | if (url) { 23 | CFErrorRef error; 24 | CTFontManagerRegisterFontsForURL((__bridge CFURLRef)url, kCTFontManagerScopeNone, &error); 25 | } 26 | } 27 | }); 28 | } 29 | 30 | + (UIFont *)flatFontOfSize:(CGFloat)size { 31 | return [UIFont fontWithName:@"Lato-Regular" size:size]; 32 | } 33 | 34 | + (UIFont *)boldFlatFontOfSize:(CGFloat)size { 35 | return [UIFont fontWithName:@"Lato-Bold" size:size]; 36 | } 37 | 38 | + (UIFont *)italicFlatFontOfSize:(CGFloat)size { 39 | return [UIFont fontWithName:@"Lato-Italic" size:size]; 40 | } 41 | 42 | + (UIFont *)lightFlatFontOfSize:(CGFloat)size { 43 | return [UIFont fontWithName:@"Lato-Light" size:size]; 44 | } 45 | 46 | + (UIFont *)iconFontWithSize:(CGFloat)size{ 47 | return [UIFont fontWithName:kFlatUIFontFamilyName size:size]; 48 | } 49 | @end 50 | -------------------------------------------------------------------------------- /Classes/ios/UIImage+FlatUI.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Color.h 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/3/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (FlatUI) 12 | 13 | + (UIImage *)imageWithColor:(UIColor *)color 14 | cornerRadius:(CGFloat)cornerRadius; 15 | 16 | + (UIImage *) buttonImageWithColor:(UIColor *)color 17 | cornerRadius:(CGFloat)cornerRadius 18 | shadowColor:(UIColor *)shadowColor 19 | shadowInsets:(UIEdgeInsets)shadowInsets; 20 | 21 | + (UIImage *) circularImageWithColor:(UIColor *)color 22 | size:(CGSize)size; 23 | 24 | - (UIImage *) imageWithMinimumSize:(CGSize)size; 25 | 26 | + (UIImage *) stepperPlusImageWithColor:(UIColor *)color; 27 | + (UIImage *) stepperMinusImageWithColor:(UIColor *)color; 28 | 29 | + (UIImage *) backButtonImageWithColor:(UIColor *)color 30 | barMetrics:(UIBarMetrics) metrics 31 | cornerRadius:(CGFloat)cornerRadius; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Classes/ios/UIImage+FlatUI.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Color.m 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/3/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import "UIImage+FlatUI.h" 10 | 11 | @implementation UIImage (FlatUI) 12 | 13 | static CGFloat edgeSizeFromCornerRadius(CGFloat cornerRadius) { 14 | return cornerRadius * 2 + 1; 15 | } 16 | 17 | + (UIImage *)imageWithColor:(UIColor *)color 18 | cornerRadius:(CGFloat)cornerRadius { 19 | CGFloat minEdgeSize = edgeSizeFromCornerRadius(cornerRadius); 20 | CGRect rect = CGRectMake(0, 0, minEdgeSize, minEdgeSize); 21 | UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:cornerRadius]; 22 | roundedRect.lineWidth = 0; 23 | UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0f); 24 | [color setFill]; 25 | [roundedRect fill]; 26 | [roundedRect stroke]; 27 | [roundedRect addClip]; 28 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 29 | UIGraphicsEndImageContext(); 30 | return [image resizableImageWithCapInsets:UIEdgeInsetsMake(cornerRadius, cornerRadius, cornerRadius, cornerRadius)]; 31 | } 32 | 33 | + (UIImage *) buttonImageWithColor:(UIColor *)color 34 | cornerRadius:(CGFloat)cornerRadius 35 | shadowColor:(UIColor *)shadowColor 36 | shadowInsets:(UIEdgeInsets)shadowInsets { 37 | UIImage *topImage = [self imageWithColor:color cornerRadius:cornerRadius]; 38 | UIImage *bottomImage = [self imageWithColor:shadowColor cornerRadius:cornerRadius]; 39 | CGFloat totalHeight = edgeSizeFromCornerRadius(cornerRadius) + shadowInsets.top + shadowInsets.bottom; 40 | CGFloat totalWidth = edgeSizeFromCornerRadius(cornerRadius) + shadowInsets.left + shadowInsets.right; 41 | CGFloat topWidth = edgeSizeFromCornerRadius(cornerRadius); 42 | CGFloat topHeight = edgeSizeFromCornerRadius(cornerRadius); 43 | CGRect topRect = CGRectMake(shadowInsets.left, shadowInsets.top, topWidth, topHeight); 44 | CGRect bottomRect = CGRectMake(0, 0, totalWidth, totalHeight); 45 | UIGraphicsBeginImageContextWithOptions(CGSizeMake(totalWidth, totalHeight), NO, 0.0f); 46 | if (!CGRectEqualToRect(bottomRect, topRect)) { 47 | [bottomImage drawInRect:bottomRect]; 48 | } 49 | [topImage drawInRect:topRect]; 50 | UIImage *buttonImage = UIGraphicsGetImageFromCurrentImageContext(); 51 | UIEdgeInsets resizeableInsets = UIEdgeInsetsMake(cornerRadius + shadowInsets.top, 52 | cornerRadius + shadowInsets.left, 53 | cornerRadius + shadowInsets.bottom, 54 | cornerRadius + shadowInsets.right); 55 | UIGraphicsEndImageContext(); 56 | return [buttonImage resizableImageWithCapInsets:resizeableInsets]; 57 | 58 | } 59 | 60 | + (UIImage *) circularImageWithColor:(UIColor *)color 61 | size:(CGSize)size { 62 | CGRect rect = CGRectMake(0, 0, size.width, size.height); 63 | UIBezierPath *circle = [UIBezierPath bezierPathWithOvalInRect:rect]; 64 | UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0f); 65 | [color setFill]; 66 | [color setStroke]; 67 | [circle addClip]; 68 | [circle fill]; 69 | [circle stroke]; 70 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 71 | UIGraphicsEndImageContext(); 72 | return image; 73 | } 74 | 75 | - (UIImage *) imageWithMinimumSize:(CGSize)size { 76 | CGRect rect = CGRectMake(0, 0, size.width, size.height); 77 | UIGraphicsBeginImageContextWithOptions(CGSizeMake(size.width, size.height), NO, 0.0f); 78 | [self drawInRect:rect]; 79 | UIImage *resized = UIGraphicsGetImageFromCurrentImageContext(); 80 | UIGraphicsEndImageContext(); 81 | return [resized resizableImageWithCapInsets:UIEdgeInsetsMake(size.height/2, size.width/2, size.height/2, size.width/2)]; 82 | } 83 | 84 | + (UIImage *) stepperPlusImageWithColor:(UIColor *)color { 85 | CGFloat iconEdgeSize = 15; 86 | CGFloat iconInternalEdgeSize = 3; 87 | UIGraphicsBeginImageContextWithOptions(CGSizeMake(iconEdgeSize, iconEdgeSize), NO, 0.0f); 88 | CGContextRef context = UIGraphicsGetCurrentContext(); 89 | [color setFill]; 90 | CGFloat padding = (iconEdgeSize - iconInternalEdgeSize) / 2; 91 | CGContextFillRect(context, CGRectMake(padding, 0, iconInternalEdgeSize, iconEdgeSize)); 92 | CGContextFillRect(context, CGRectMake(0, padding, iconEdgeSize, iconInternalEdgeSize)); 93 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 94 | UIGraphicsEndImageContext(); 95 | return image; 96 | } 97 | 98 | + (UIImage *) stepperMinusImageWithColor:(UIColor *)color { 99 | CGFloat iconEdgeSize = 15; 100 | CGFloat iconInternalEdgeSize = 3; 101 | UIGraphicsBeginImageContextWithOptions(CGSizeMake(iconEdgeSize, iconEdgeSize), NO, 0.0f); 102 | CGContextRef context = UIGraphicsGetCurrentContext(); 103 | [color setFill]; 104 | CGFloat padding = (iconEdgeSize - iconInternalEdgeSize) / 2; 105 | CGContextFillRect(context, CGRectMake(0, padding, iconEdgeSize, iconInternalEdgeSize)); 106 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 107 | UIGraphicsEndImageContext(); 108 | return image; 109 | } 110 | 111 | + (UIImage *) backButtonImageWithColor:(UIColor *)color 112 | barMetrics:(UIBarMetrics) metrics 113 | cornerRadius:(CGFloat)cornerRadius { 114 | CGSize size; 115 | if (metrics == UIBarMetricsDefault) { 116 | size = CGSizeMake(50, 30); 117 | } else { 118 | size = CGSizeMake(60, 23); 119 | } 120 | UIBezierPath *path = [self bezierPathForBackButtonInRect:CGRectMake(0, 0, size.width, size.height) cornerRadius:cornerRadius]; 121 | UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f); 122 | [color setFill]; 123 | [path addClip]; 124 | [path fill]; 125 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 126 | UIGraphicsEndImageContext(); 127 | 128 | if ([image respondsToSelector:@selector(resizableImageWithCapInsets:resizingMode:)]) { 129 | return [image resizableImageWithCapInsets:UIEdgeInsetsMake(cornerRadius, 15, cornerRadius, cornerRadius) resizingMode:UIImageResizingModeStretch]; 130 | }else{ 131 | return [image resizableImageWithCapInsets:UIEdgeInsetsMake(cornerRadius, 15, cornerRadius, cornerRadius)]; 132 | } 133 | } 134 | 135 | + (UIBezierPath *) bezierPathForBackButtonInRect:(CGRect)rect cornerRadius:(CGFloat)radius { 136 | UIBezierPath *path = [UIBezierPath bezierPath]; 137 | CGPoint mPoint = CGPointMake(CGRectGetMaxX(rect) - radius, rect.origin.y); 138 | CGPoint ctrlPoint = mPoint; 139 | [path moveToPoint:mPoint]; 140 | 141 | ctrlPoint.y += radius; 142 | mPoint.x += radius; 143 | mPoint.y += radius; 144 | if (radius > 0) [path addArcWithCenter:ctrlPoint radius:radius startAngle:(float)M_PI + (float)M_PI_2 endAngle:0 clockwise:YES]; 145 | 146 | mPoint.y = CGRectGetMaxY(rect) - radius; 147 | [path addLineToPoint:mPoint]; 148 | 149 | ctrlPoint = mPoint; 150 | mPoint.y += radius; 151 | mPoint.x -= radius; 152 | ctrlPoint.x -= radius; 153 | if (radius > 0) [path addArcWithCenter:ctrlPoint radius:radius startAngle:0 endAngle:(float)M_PI_2 clockwise:YES]; 154 | 155 | mPoint.x = rect.origin.x + (10.0f); 156 | [path addLineToPoint:mPoint]; 157 | 158 | [path addLineToPoint:CGPointMake(rect.origin.x, CGRectGetMidY(rect))]; 159 | 160 | mPoint.y = rect.origin.y; 161 | [path addLineToPoint:mPoint]; 162 | 163 | [path closePath]; 164 | return path; 165 | } 166 | 167 | @end 168 | -------------------------------------------------------------------------------- /Classes/ios/UINavigationBar+FlatUI.h: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationBar+FlatUI.h 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/3/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UINavigationBar (FlatUI) 12 | 13 | - (void) configureFlatNavigationBarWithColor:(UIColor *)color UI_APPEARANCE_SELECTOR; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Classes/ios/UINavigationBar+FlatUI.m: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationBar+FlatUI.m 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/3/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import "UINavigationBar+FlatUI.h" 10 | #import "UIImage+FlatUI.h" 11 | 12 | @implementation UINavigationBar (FlatUI) 13 | 14 | - (void) configureFlatNavigationBarWithColor:(UIColor *)color { 15 | [self setBackgroundImage:[UIImage imageWithColor:color cornerRadius:0] 16 | forBarMetrics:UIBarMetricsDefault & UIBarMetricsLandscapePhone]; 17 | NSMutableDictionary *titleTextAttributes = [[self titleTextAttributes] mutableCopy]; 18 | if (!titleTextAttributes) { 19 | titleTextAttributes = [NSMutableDictionary dictionary]; 20 | } 21 | 22 | if ([[[UIDevice currentDevice] systemVersion] compare:@"6.0" options:NSNumericSearch] != NSOrderedAscending) { 23 | // iOS6 methods 24 | NSShadow *shadow = [[NSShadow alloc] init]; 25 | [shadow setShadowOffset:CGSizeZero]; 26 | [shadow setShadowColor:[UIColor clearColor]]; 27 | [titleTextAttributes setObject:shadow forKey:NSShadowAttributeName]; 28 | } else { 29 | // Pre-iOS6 methods 30 | [titleTextAttributes setValue:[UIColor clearColor] forKey:UITextAttributeTextShadowColor]; 31 | [titleTextAttributes setValue:[NSValue valueWithUIOffset:UIOffsetZero] forKey:UITextAttributeTextShadowOffset]; 32 | 33 | } 34 | 35 | [self setTitleTextAttributes:titleTextAttributes]; 36 | if ([self respondsToSelector:@selector(setShadowImage:)]) { 37 | [self setShadowImage:[UIImage imageWithColor:[UIColor clearColor] cornerRadius:0]]; 38 | } 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /Classes/ios/UIPopoverController+FlatUI.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIPopoverController+FlatUI.h 3 | // FlatUIKit 4 | // 5 | // Created by Jack Flintermann on 6/29/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIPopoverController (FlatUI) 12 | 13 | - (void) configureFlatPopoverWithBackgroundColor:(UIColor *)backgroundColor 14 | cornerRadius:(CGFloat)cornerRadius; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Classes/ios/UIPopoverController+FlatUI.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIPopoverController+FlatUI.m 3 | // FlatUIKit 4 | // 5 | // Created by Jack Flintermann on 6/29/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import "UIPopoverController+FlatUI.h" 10 | #import "FUIPopoverBackgroundView.h" 11 | 12 | @implementation UIPopoverController (FlatUI) 13 | 14 | - (void) configureFlatPopoverWithBackgroundColor:(UIColor *)backgroundColor 15 | cornerRadius:(CGFloat)cornerRadius { 16 | [FUIPopoverBackgroundView setBackgroundColor:backgroundColor]; 17 | [FUIPopoverBackgroundView setCornerRadius:cornerRadius]; 18 | [self setPopoverLayoutMargins:[FUIPopoverBackgroundView contentViewInsets]]; 19 | [self setPopoverBackgroundViewClass:[FUIPopoverBackgroundView class]]; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Classes/ios/UIProgressView+FlatUI.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIProgressView+FlatUI.h 3 | // FlatUITestProj 4 | // 5 | // Created by Alex Medearis on 5/16/13. 6 | // Copyright (c) 2013 Alex Medearis. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIProgressView (FlatUI) 12 | 13 | - (void)configureFlatProgressViewWithTrackColor:(UIColor *)trackColor UI_APPEARANCE_SELECTOR; 14 | - (void)configureFlatProgressViewWithProgressColor:(UIColor *)progressColor UI_APPEARANCE_SELECTOR; 15 | 16 | - (void) configureFlatProgressViewWithTrackColor:(UIColor *)trackColor 17 | progressColor:(UIColor *)progressColor; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Classes/ios/UIProgressView+FlatUI.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIProgressView+FlatUI.h 3 | // FlatUITestProj 4 | // 5 | // Created by Alex Medearis on 5/16/13. 6 | // Copyright (c) 2013 Alex Medearis. All rights reserved. 7 | // 8 | 9 | #import "UIImage+FlatUI.h" 10 | 11 | @implementation UIProgressView (FlatUI) 12 | 13 | - (void)configureFlatProgressViewWithTrackColor:(UIColor *)trackColor { 14 | UIImage *trackImage = [UIImage imageWithColor:trackColor cornerRadius:4.0]; 15 | trackImage = [trackImage imageWithMinimumSize:CGSizeMake(10.0f, 10.0f)]; 16 | [self setTrackImage:trackImage]; 17 | 18 | if ([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending) { 19 | [self setTintColor:trackColor]; 20 | } 21 | 22 | } 23 | 24 | - (void)configureFlatProgressViewWithProgressColor:(UIColor *)progressColor { 25 | UIImage *progressImage = [UIImage imageWithColor:progressColor cornerRadius:4.0]; 26 | [self setProgressImage:progressImage]; 27 | 28 | if ([[[UIDevice currentDevice] systemVersion] compare:@"7.1" options:NSNumericSearch] != NSOrderedAscending) { 29 | [self setTintColor:progressColor]; 30 | } 31 | 32 | } 33 | 34 | - (void) configureFlatProgressViewWithTrackColor:(UIColor *)trackColor 35 | progressColor:(UIColor *)progressColor { 36 | [self configureFlatProgressViewWithTrackColor:trackColor]; 37 | [self configureFlatProgressViewWithProgressColor:progressColor]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Classes/ios/UISlider+FlatUI.h: -------------------------------------------------------------------------------- 1 | // 2 | // UISlider+FlatUI.h 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/3/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UISlider (FlatUI) 12 | 13 | - (void) configureFlatSliderWithTrackColor:(UIColor *)trackColor 14 | progressColor:(UIColor *)progressColor 15 | thumbColor:(UIColor *)thumbColor; 16 | 17 | - (void) configureFlatSliderWithTrackColor:(UIColor *)trackColor 18 | progressColor:(UIColor *)progressColor 19 | thumbColorNormal:(UIColor *)thumbColorNormal 20 | thumbColorHighlighted:(UIColor *)highlightedThumbColor; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Classes/ios/UISlider+FlatUI.m: -------------------------------------------------------------------------------- 1 | // 2 | // UISlider+FlatUI.m 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/3/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import "UISlider+FlatUI.h" 10 | #import "UIImage+FlatUI.h" 11 | 12 | @implementation UISlider (FlatUI) 13 | 14 | - (void) configureFlatSliderWithTrackColor:(UIColor *)trackColor 15 | progressColor:(UIColor *)progressColor 16 | thumbColor:(UIColor *)thumbColor { 17 | 18 | [self configureFlatSliderWithTrackColor:trackColor 19 | progressColor:progressColor 20 | thumbColorNormal:thumbColor 21 | thumbColorHighlighted:thumbColor]; 22 | } 23 | 24 | - (void) configureFlatSliderWithTrackColor:(UIColor *)trackColor 25 | progressColor:(UIColor *)progressColor 26 | thumbColorNormal:(UIColor *)normalThumbColor 27 | thumbColorHighlighted:(UIColor *)highlightedThumbColor 28 | { 29 | UIImage *progressImage = [[UIImage imageWithColor:progressColor cornerRadius:5.0] 30 | imageWithMinimumSize:CGSizeMake(10, 10)]; 31 | UIImage *trackImage = [[UIImage imageWithColor:trackColor cornerRadius:5.0] 32 | imageWithMinimumSize:CGSizeMake(10, 10)]; 33 | 34 | [self setMinimumTrackImage:progressImage forState:UIControlStateNormal]; 35 | [self setMaximumTrackImage:trackImage forState:UIControlStateNormal]; 36 | 37 | UIImage *normalSliderImage = [UIImage circularImageWithColor:normalThumbColor size:CGSizeMake(24, 24)]; 38 | [self setThumbImage:normalSliderImage forState:UIControlStateNormal]; 39 | 40 | UIImage *highlighedSliderImage = [UIImage circularImageWithColor:highlightedThumbColor size:CGSizeMake(24, 24)]; 41 | [self setThumbImage:highlighedSliderImage forState:UIControlStateHighlighted]; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /Classes/ios/UIStepper+FlatUI.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIStepper+FlatUI.h 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/3/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIStepper (FlatUI) 12 | 13 | - (void) configureFlatStepperWithColor:(UIColor *)color 14 | highlightedColor:(UIColor *)highlightedColor 15 | disabledColor:(UIColor *)disabledColor 16 | iconColor:(UIColor *)iconColor; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Classes/ios/UIStepper+FlatUI.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIStepper+FlatUI.m 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/3/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import "UIStepper+FlatUI.h" 10 | #import "UIImage+FlatUI.h" 11 | #import 12 | 13 | @implementation UIStepper (FlatUI) 14 | 15 | - (void) configureFlatStepperWithColor:(UIColor *)color 16 | highlightedColor:(UIColor *)highlightedColor 17 | disabledColor:(UIColor *)disabledColor 18 | iconColor:(UIColor *)iconColor { 19 | 20 | // iOS 6 compat check 21 | if ([self respondsToSelector:@selector(setBackgroundImage:forState:)]) { 22 | UIImage *normalImage = [UIImage imageWithColor:color cornerRadius:2.0]; 23 | UIImage *highlightedImage = [UIImage imageWithColor:highlightedColor cornerRadius:2.0]; 24 | UIImage *disabledImage = [UIImage imageWithColor:disabledColor cornerRadius:2.0]; 25 | [self setBackgroundImage:normalImage forState:UIControlStateNormal]; 26 | [self setBackgroundImage:highlightedImage forState:UIControlStateHighlighted]; 27 | [self setBackgroundImage:disabledImage forState:UIControlStateDisabled]; 28 | [self setDividerImage:[UIImage imageWithColor:highlightedColor cornerRadius:0] 29 | forLeftSegmentState:UIControlStateNormal 30 | rightSegmentState:UIControlStateNormal]; 31 | [self setDividerImage:[UIImage imageWithColor:highlightedColor cornerRadius:0] 32 | forLeftSegmentState:UIControlStateHighlighted 33 | rightSegmentState:UIControlStateNormal]; 34 | [self setDividerImage:[UIImage imageWithColor:highlightedColor cornerRadius:0] 35 | forLeftSegmentState:UIControlStateNormal 36 | rightSegmentState:UIControlStateHighlighted]; 37 | 38 | UIImage *plusImage = [UIImage stepperPlusImageWithColor:iconColor]; 39 | UIImage *minusImage = [UIImage stepperMinusImageWithColor:iconColor]; 40 | [self setIncrementImage:plusImage forState:UIControlStateNormal]; 41 | [self setIncrementImage:plusImage forState:UIControlStateDisabled]; 42 | [self setDecrementImage:minusImage forState:UIControlStateNormal]; 43 | [self setDecrementImage:minusImage forState:UIControlStateDisabled]; 44 | } 45 | 46 | if ([[[UIDevice currentDevice] systemVersion] compare:@"7.1" options:NSNumericSearch] != NSOrderedAscending) { 47 | [self setTintColor:iconColor]; 48 | } 49 | 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /Classes/ios/UITabBar+FlatUI.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITabBar+FlatUI.h 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/3/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UITabBar (FlatUI) 12 | 13 | - (void)configureFlatTabBarWithColor:(UIColor *)color UI_APPEARANCE_SELECTOR; 14 | - (void)configureFlatTabBarWithSelectedColor:(UIColor *)selectedColor UI_APPEARANCE_SELECTOR; 15 | 16 | - (void)configureFlatTabBarWithColor:(UIColor *)color 17 | selectedColor:(UIColor *)selectedColor; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Classes/ios/UITabBar+FlatUI.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITabBar+FlatUI.m 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/3/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import "UITabBar+FlatUI.h" 10 | #import "UIImage+FlatUI.h" 11 | 12 | @implementation UITabBar (FlatUI) 13 | 14 | - (void)configureFlatTabBarWithColor:(UIColor *)color { 15 | [self setBackgroundImage:[UIImage imageWithColor:color cornerRadius:0]]; 16 | } 17 | 18 | - (void)configureFlatTabBarWithSelectedColor:(UIColor *)selectedColor { 19 | [self setSelectionIndicatorImage:[UIImage imageWithColor:selectedColor cornerRadius:6.0]]; 20 | } 21 | 22 | - (void)configureFlatTabBarWithColor:(UIColor *)color 23 | selectedColor:(UIColor *)selectedColor { 24 | [self configureFlatTabBarWithColor:color]; 25 | [self configureFlatTabBarWithSelectedColor:selectedColor]; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Classes/ios/UITableViewCell+FlatUI.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITableViewCell+FlatUI.h 3 | // FlatUIKitExample 4 | // 5 | // Created by Maciej Swic on 2013-05-31. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface UITableViewCell (FlatUI) 12 | 13 | @property (nonatomic) CGFloat cornerRadius; 14 | @property (nonatomic) CGFloat separatorHeight; 15 | 16 | - (void) configureFlatCellWithColor:(UIColor *)color 17 | selectedColor:(UIColor *)selectedColor; 18 | 19 | - (void) configureFlatCellWithColor:(UIColor *)color 20 | selectedColor:(UIColor *)selectedColor 21 | roundingCorners:(UIRectCorner)corners; 22 | 23 | - (void)setCornerRadius:(CGFloat)cornerRadius; 24 | - (void)setSeparatorHeight:(CGFloat)separatorHeight; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Classes/ios/UITableViewCell+FlatUI.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITableViewCell+FlatUI.m 3 | // FlatUIKitExample 4 | // 5 | // Created by Maciej Swic on 2013-05-31. 6 | // 7 | // 8 | 9 | #import "UITableViewCell+FlatUI.h" 10 | #import "FUICellBackgroundView.h" 11 | #import 12 | 13 | @implementation UITableViewCell (FlatUI) 14 | 15 | @dynamic cornerRadius, separatorHeight; 16 | 17 | - (void) configureFlatCellWithColor:(UIColor *)color 18 | selectedColor:(UIColor *)selectedColor { 19 | [self configureFlatCellWithColor:color 20 | selectedColor:selectedColor 21 | roundingCorners:0]; 22 | } 23 | 24 | - (void) configureFlatCellWithColor:(UIColor *)color 25 | selectedColor:(UIColor *)selectedColor 26 | roundingCorners:(UIRectCorner)corners { 27 | FUICellBackgroundView* backgroundView = [FUICellBackgroundView new]; 28 | backgroundView.backgroundColor = color; 29 | backgroundView.roundedCorners = corners; 30 | self.backgroundView = backgroundView; 31 | 32 | FUICellBackgroundView* selectedBackgroundView = [FUICellBackgroundView new]; 33 | selectedBackgroundView.roundedCorners = corners; 34 | selectedBackgroundView.backgroundColor = selectedColor; 35 | self.selectedBackgroundView = selectedBackgroundView; 36 | 37 | //The labels need a clear background color or they will look very funky 38 | self.textLabel.backgroundColor = [UIColor clearColor]; 39 | if ([self respondsToSelector:@selector(detailTextLabel)]) 40 | self.detailTextLabel.backgroundColor = [UIColor clearColor]; 41 | 42 | //Guess some good text colors 43 | self.textLabel.textColor = selectedColor; 44 | self.textLabel.highlightedTextColor = color; 45 | if ([self respondsToSelector:@selector(detailTextLabel)]) { 46 | self.detailTextLabel.textColor = selectedColor; 47 | self.detailTextLabel.highlightedTextColor = color; 48 | } 49 | } 50 | 51 | - (void)setCornerRadius:(CGFloat)cornerRadius { 52 | [(FUICellBackgroundView*)self.backgroundView setCornerRadius:cornerRadius]; 53 | [(FUICellBackgroundView*)self.selectedBackgroundView setCornerRadius:cornerRadius]; 54 | } 55 | 56 | - (void)setSeparatorHeight:(CGFloat)separatorHeight { 57 | [(FUICellBackgroundView*)self.backgroundView setSeparatorHeight:separatorHeight]; 58 | [(FUICellBackgroundView*)self.selectedBackgroundView setSeparatorHeight:separatorHeight]; 59 | } 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /Classes/ios/UIToolbar+FlatUI.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Jonathon Hibbard on 6/13/13. 3 | // Copyright (c) 2013 Integrated Events. All rights reserved. 4 | // 5 | // To change the template use AppCode | Preferences | File Templates. 6 | // 7 | 8 | #import 9 | 10 | @interface UIToolbar (FlatUI) 11 | 12 | - (void)configureFlatToolbarWithColor:(UIColor *)color UI_APPEARANCE_SELECTOR; 13 | 14 | @end -------------------------------------------------------------------------------- /Classes/ios/UIToolbar+FlatUI.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Jonathon Hibbard on 6/13/13. 3 | // Copyright (c) 2013 Integrated Events. All rights reserved. 4 | // 5 | // To change the template use AppCode | Preferences | File Templates. 6 | // 7 | 8 | #import "UIToolbar+FlatUI.h" 9 | #import "UIImage+FlatUI.h" 10 | 11 | @implementation UIToolbar (FlatUI) 12 | 13 | - (void)configureFlatToolbarWithColor:(UIColor *)color { 14 | [self setBackgroundImage:[UIImage imageWithColor:color cornerRadius:0] 15 | forToolbarPosition:UIToolbarPositionAny 16 | barMetrics:UIBarMetricsDefault]; 17 | 18 | if ([self respondsToSelector:@selector(setShadowImage:forToolbarPosition:)]) { 19 | UIImage *clearShadowImage = [UIImage imageWithColor:[UIColor clearColor] cornerRadius:0]; 20 | [self setShadowImage:clearShadowImage forToolbarPosition:UIToolbarPositionAny]; 21 | } 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Example/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.swp 3 | *~.nib 4 | .idea 5 | build/ 6 | bin/ 7 | .idea/ 8 | *.pbxuser 9 | *.perspective 10 | *.perspectivev3 11 | 12 | *.xcodeproj/xcuserdata/* 13 | *.xcodeproj/project.xcworkspace/xcuserdata/* 14 | objects 15 | Settings.bundle 16 | 17 | -------------------------------------------------------------------------------- /Example/FlatUIKitExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/FlatUIKitExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // FlatUIKitExample 4 | // 5 | // Created by Alejandro Benito Santos on 5/16/13. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @class ViewController; 12 | 13 | @interface AppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) ViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Example/FlatUIKitExample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // FlatUIKitExample 4 | // 5 | // Created by Alejandro Benito Santos on 5/16/13. 6 | // 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "ViewController.h" 11 | 12 | @implementation AppDelegate 13 | 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 15 | { 16 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 17 | 18 | if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { 19 | self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; 20 | } else { 21 | self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; 22 | } 23 | 24 | UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.viewController]; 25 | self.window.rootViewController = navController; 26 | [self.window makeKeyAndVisible]; 27 | return YES; 28 | } 29 | 30 | - (void)applicationWillResignActive:(UIApplication *)application 31 | { 32 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 33 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 34 | } 35 | 36 | - (void)applicationDidEnterBackground:(UIApplication *)application 37 | { 38 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 39 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 40 | } 41 | 42 | - (void)applicationWillEnterForeground:(UIApplication *)application 43 | { 44 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 45 | } 46 | 47 | - (void)applicationDidBecomeActive:(UIApplication *)application 48 | { 49 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 50 | } 51 | 52 | - (void)applicationWillTerminate:(UIApplication *)application 53 | { 54 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /Example/FlatUIKitExample/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Example/FlatUIKitExample/Default-568h@2x.png -------------------------------------------------------------------------------- /Example/FlatUIKitExample/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Example/FlatUIKitExample/Default.png -------------------------------------------------------------------------------- /Example/FlatUIKitExample/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Example/FlatUIKitExample/Default@2x.png -------------------------------------------------------------------------------- /Example/FlatUIKitExample/FlatUIKitExample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIAppFonts 6 | 7 | flat-ui-icons-regular.ttf 8 | 9 | CFBundleDevelopmentRegion 10 | en 11 | CFBundleDisplayName 12 | ${PRODUCT_NAME} 13 | CFBundleExecutable 14 | ${EXECUTABLE_NAME} 15 | CFBundleIdentifier 16 | com.joingrouper.${PRODUCT_NAME:rfc1034identifier} 17 | CFBundleInfoDictionaryVersion 18 | 6.0 19 | CFBundleName 20 | ${PRODUCT_NAME} 21 | CFBundlePackageType 22 | APPL 23 | CFBundleShortVersionString 24 | 1.0 25 | CFBundleSignature 26 | ???? 27 | CFBundleVersion 28 | 1.0 29 | LSRequiresIPhoneOS 30 | 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Example/FlatUIKitExample/FlatUIKitExample-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'FlatUIKitExample' target in the 'FlatUIKitExample' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Example/FlatUIKitExample/IconViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // IconViewController.h 3 | // FlatUIKitExample 4 | // 5 | // Created by Jamie Matthews on 12/24/14. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface IconViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/FlatUIKitExample/IconViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // IconViewController.m 3 | // FlatUIKitExample 4 | // 5 | // Created by Jamie Matthews on 12/24/14. 6 | // 7 | // 8 | 9 | #import "IconViewController.h" 10 | #import "FlatUIKit.h" 11 | #import "NSString+Icons.h" 12 | 13 | @implementation IconViewController{ 14 | UICollectionView *_collectionView; 15 | NSArray *unicodeStrings; 16 | NSArray *colorArray; 17 | } 18 | 19 | -(void)viewDidLoad{ 20 | [super viewDidLoad]; 21 | 22 | self.view.backgroundColor = [UIColor cloudsColor]; 23 | self.title = @"Icons"; 24 | self.navigationController.navigationBar.translucent = NO; 25 | UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init]; 26 | _collectionView=[[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout]; 27 | [_collectionView setDataSource:self]; 28 | [_collectionView setDelegate:self]; 29 | [_collectionView setTranslatesAutoresizingMaskIntoConstraints:NO]; 30 | 31 | [_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cellIdentifier"]; 32 | [_collectionView setBackgroundColor:[UIColor clearColor]]; 33 | [self.view addSubview:_collectionView]; 34 | 35 | [self.view addConstraints:[NSLayoutConstraint 36 | constraintsWithVisualFormat:@"H:|-0-[_collectionView]-0-|" 37 | options:NSLayoutFormatDirectionLeadingToTrailing 38 | metrics:nil 39 | views:NSDictionaryOfVariableBindings(_collectionView)]]; 40 | [self.view addConstraints:[NSLayoutConstraint 41 | constraintsWithVisualFormat:@"V:|-0-[_collectionView]-0-|" 42 | options:NSLayoutFormatDirectionLeadingToTrailing 43 | metrics:nil 44 | views:NSDictionaryOfVariableBindings(_collectionView)]]; 45 | 46 | // loop over all of the icon string values 47 | unicodeStrings = [NSString iconUnicodeStrings]; 48 | // use a few different colors to show how these icons can be styled 49 | colorArray = @[[UIColor turquoiseColor], [UIColor emerlandColor], [UIColor peterRiverColor], [UIColor amethystColor], [UIColor sunflowerColor], [UIColor carrotColor], [UIColor alizarinColor]]; 50 | } 51 | 52 | 53 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 54 | { 55 | return [unicodeStrings count]; 56 | } 57 | 58 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 59 | { 60 | UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"cellIdentifier" forIndexPath:indexPath]; 61 | if(!cell){ 62 | 63 | } 64 | else{ 65 | [[cell.contentView viewWithTag:100] removeFromSuperview]; 66 | } 67 | 68 | UILabel *title = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, cell.bounds.size.width, cell.bounds.size.height)]; 69 | title.font = [UIFont iconFontWithSize:16]; 70 | title.textAlignment = NSTextAlignmentCenter; 71 | title.text = [unicodeStrings objectAtIndex:indexPath.row]; 72 | title.tag = 100; 73 | title.textColor = [colorArray objectAtIndex:indexPath.row%[colorArray count]]; 74 | [cell.contentView addSubview:title]; 75 | 76 | return cell; 77 | } 78 | 79 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath 80 | { 81 | return CGSizeMake(50, 50); 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /Example/FlatUIKitExample/TableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewController.h 3 | // FlatUIKitExample 4 | // 5 | // Created by Maciej Swic on 2013-05-31. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface TableViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/FlatUIKitExample/TableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewController.m 3 | // FlatUIKitExample 4 | // 5 | // Created by Maciej Swic on 2013-05-31. 6 | // 7 | // 8 | 9 | #import "TableViewController.h" 10 | 11 | #import "UITableViewCell+FlatUI.h" 12 | #import "UIColor+FlatUI.h" 13 | 14 | static NSString * const FUITableViewControllerCellReuseIdentifier = @"FUITableViewControllerCellReuseIdentifier"; 15 | 16 | @implementation TableViewController 17 | 18 | - (void)viewDidLoad 19 | { 20 | [super viewDidLoad]; 21 | 22 | self.title = @"Table View"; 23 | 24 | //Set the separator color 25 | self.tableView.separatorColor = [UIColor cloudsColor]; 26 | 27 | //Set the background color 28 | self.tableView.backgroundColor = [UIColor cloudsColor]; 29 | self.tableView.backgroundView = nil; 30 | [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:FUITableViewControllerCellReuseIdentifier]; 31 | } 32 | 33 | #pragma mark - Table view data source 34 | 35 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 36 | { 37 | return 7; 38 | } 39 | 40 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 41 | { 42 | if (section % 2) 43 | return 3; 44 | else 45 | return 1; 46 | } 47 | 48 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 49 | { 50 | UIRectCorner corners = 0; 51 | if (tableView.style == UITableViewStyleGrouped) { 52 | if ([tableView numberOfRowsInSection:indexPath.section] == 1) { 53 | corners = UIRectCornerAllCorners; 54 | } else if (indexPath.row == 0) { 55 | corners = UIRectCornerTopLeft | UIRectCornerTopRight; 56 | } else if (indexPath.row == [tableView numberOfRowsInSection:indexPath.section] - 1) { 57 | corners = UIRectCornerBottomLeft | UIRectCornerBottomRight; 58 | } 59 | } 60 | UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:FUITableViewControllerCellReuseIdentifier]; 61 | [cell configureFlatCellWithColor:[UIColor greenSeaColor] 62 | selectedColor:[UIColor cloudsColor] 63 | roundingCorners:corners]; 64 | 65 | cell.cornerRadius = 5.f; //Optional 66 | if (self.tableView.style == UITableViewStyleGrouped) { 67 | cell.separatorHeight = 2.f; //Optional 68 | } else { 69 | cell.separatorHeight = 0.; 70 | } 71 | 72 | cell.textLabel.text = [NSString stringWithFormat:@"Section %ld Row %ld", (long)indexPath.section, (long)indexPath.row]; 73 | 74 | return cell; 75 | } 76 | 77 | #pragma mark - Table view delegate 78 | 79 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 80 | { 81 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /Example/FlatUIKitExample/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/3/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FUIAlertView.h" 11 | 12 | @interface ViewController : UIViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Example/FlatUIKitExample/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // FlatUI 4 | // 5 | // Created by Jack Flintermann on 5/3/13. 6 | // Copyright (c) 2013 Jack Flintermann. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "TableViewController.h" 11 | #import "UIColor+FlatUI.h" 12 | #import "UISlider+FlatUI.h" 13 | #import "UIStepper+FlatUI.h" 14 | #import "UITabBar+FlatUI.h" 15 | #import "UINavigationBar+FlatUI.h" 16 | #import "FUIButton.h" 17 | #import "FUISwitch.h" 18 | #import "UIFont+FlatUI.h" 19 | #import "FUIAlertView.h" 20 | #import "UIBarButtonItem+FlatUI.h" 21 | #import "UIProgressView+FlatUI.h" 22 | #import "FUISegmentedControl.h" 23 | #import "UIPopoverController+FlatUI.h" 24 | #import "NSString+Icons.h" 25 | #import "IconViewController.h" 26 | 27 | #define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame) 28 | #define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending) 29 | #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) 30 | #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) 31 | #define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending) 32 | 33 | @interface ViewController () { 34 | UIPopoverController *_popoverController; 35 | } 36 | @property (weak, nonatomic) IBOutlet FUIButton *alertViewButton; 37 | @property (weak, nonatomic) IBOutlet FUIButton *popoverButton; 38 | @property (weak, nonatomic) IBOutlet UISlider *slider; 39 | @property (weak, nonatomic) IBOutlet UIStepper *stepper; 40 | @property (weak, nonatomic) IBOutlet FUISwitch *flatSwitch; 41 | @property (strong, nonatomic) IBOutletCollection(UILabel) NSArray *labels; 42 | @property (weak, nonatomic) IBOutlet UIProgressView *flatProgress; 43 | @property (weak, nonatomic) IBOutlet FUISegmentedControl *flatSegmentedControl; 44 | @property (weak, nonatomic) IBOutlet FUIButton *iconsButton; 45 | 46 | @end 47 | 48 | @implementation ViewController 49 | 50 | - (void)viewDidLoad 51 | { 52 | [super viewDidLoad]; 53 | 54 | if ([UIDevice currentDevice].systemVersion.floatValue >= 7) { 55 | self.edgesForExtendedLayout = UIRectEdgeNone; 56 | } 57 | 58 | self.title = @"Flat UI"; 59 | self.view.backgroundColor = [UIColor cloudsColor]; 60 | NSDictionary *attrs = @{NSForegroundColorAttributeName: [UIColor whiteColor]}; 61 | [[UIBarItem appearance] setTitleTextAttributes:attrs 62 | forState:UIControlStateNormal]; 63 | [UIBarButtonItem configureFlatButtonsWithColor:[UIColor peterRiverColor] 64 | highlightedColor:[UIColor belizeHoleColor] 65 | cornerRadius:3 66 | whenContainedIn:[UINavigationBar class], nil]; 67 | 68 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Plain Table" 69 | style:UIBarButtonItemStylePlain 70 | target:self 71 | action:@selector(showPlainTableView:)]; 72 | [self.navigationItem.rightBarButtonItem removeTitleShadow]; 73 | 74 | self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Grouped Table" 75 | style:UIBarButtonItemStylePlain 76 | target:self 77 | action:@selector(showTableView:)]; 78 | [self.navigationItem.leftBarButtonItem removeTitleShadow]; 79 | 80 | [self.navigationItem.leftBarButtonItem configureFlatButtonWithColor:[UIColor alizarinColor] 81 | highlightedColor:[UIColor pomegranateColor] 82 | cornerRadius:3]; 83 | 84 | self.alertViewButton.buttonColor = [UIColor turquoiseColor]; 85 | self.alertViewButton.shadowColor = [UIColor greenSeaColor]; 86 | self.alertViewButton.shadowHeight = 3.0f; 87 | self.alertViewButton.cornerRadius = 6.0f; 88 | self.alertViewButton.titleLabel.font = [UIFont boldFlatFontOfSize:16]; 89 | [self.alertViewButton setTitleColor:[UIColor cloudsColor] forState:UIControlStateNormal]; 90 | [self.alertViewButton setTitleColor:[UIColor cloudsColor] forState:UIControlStateHighlighted]; 91 | 92 | self.iconsButton.titleLabel.font = [UIFont iconFontWithSize:16]; 93 | self.iconsButton.buttonColor = [UIColor turquoiseColor]; 94 | self.iconsButton.shadowColor = [UIColor greenSeaColor]; 95 | self.iconsButton.shadowHeight = 3.0f; 96 | self.iconsButton.cornerRadius = 6.0f; 97 | [self.iconsButton setTitle:[NSString stringWithFormat:@"%@ Icons", [NSString iconStringForEnum:FUIListBulleted]] forState:UIControlStateNormal]; 98 | 99 | [self.iconsButton setTitleColor:[UIColor cloudsColor] forState:UIControlStateNormal]; 100 | [self.iconsButton addTarget:self action:@selector(iconsButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; 101 | 102 | [self.slider configureFlatSliderWithTrackColor:[UIColor silverColor] 103 | progressColor:[UIColor alizarinColor] 104 | thumbColor:[UIColor pomegranateColor]]; 105 | 106 | [self.stepper configureFlatStepperWithColor:[UIColor wisteriaColor] 107 | highlightedColor:[UIColor amethystColor] 108 | disabledColor:[UIColor silverColor] 109 | iconColor:[UIColor cloudsColor]]; 110 | 111 | if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) { 112 | self.navigationController.navigationBar.titleTextAttributes = @{NSFontAttributeName:[UIFont boldFlatFontOfSize:18], 113 | NSForegroundColorAttributeName: [UIColor whiteColor]}; 114 | } else { 115 | // Pre-iOS7 methods 116 | self.navigationController.navigationBar.titleTextAttributes = @{UITextAttributeFont: [UIFont boldFlatFontOfSize:18], 117 | UITextAttributeTextColor: [UIColor whiteColor]}; 118 | } 119 | 120 | [self.navigationController.navigationBar configureFlatNavigationBarWithColor:[UIColor midnightBlueColor]]; 121 | 122 | self.flatSwitch.onColor = [UIColor turquoiseColor]; 123 | self.flatSwitch.offColor = [UIColor cloudsColor]; 124 | self.flatSwitch.onBackgroundColor = [UIColor midnightBlueColor]; 125 | self.flatSwitch.offBackgroundColor = [UIColor silverColor]; 126 | self.flatSwitch.offLabel.font = [UIFont boldFlatFontOfSize:14]; 127 | self.flatSwitch.onLabel.font = [UIFont boldFlatFontOfSize:14]; 128 | 129 | [self.labels enumerateObjectsUsingBlock:^(UILabel *label, NSUInteger idx, BOOL *stop) { 130 | label.font = [UIFont flatFontOfSize:16]; 131 | label.textColor = [UIColor midnightBlueColor]; 132 | }]; 133 | 134 | [self.flatProgress configureFlatProgressViewWithTrackColor:[UIColor silverColor] progressColor:[UIColor wisteriaColor]]; 135 | 136 | self.flatSegmentedControl.selectedFont = [UIFont boldFlatFontOfSize:16]; 137 | self.flatSegmentedControl.selectedFontColor = [UIColor cloudsColor]; 138 | self.flatSegmentedControl.deselectedFont = [UIFont flatFontOfSize:16]; 139 | self.flatSegmentedControl.deselectedFontColor = [UIColor cloudsColor]; 140 | self.flatSegmentedControl.selectedColor = [UIColor pumpkinColor]; 141 | self.flatSegmentedControl.deselectedColor = [UIColor tangerineColor]; 142 | self.flatSegmentedControl.disabledColor = [UIColor silverColor]; 143 | self.flatSegmentedControl.dividerColor = [UIColor silverColor]; 144 | self.flatSegmentedControl.cornerRadius = 5.0; 145 | 146 | if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { 147 | self.popoverButton.buttonColor = [UIColor carrotColor]; 148 | self.popoverButton.shadowColor = [UIColor alizarinColor]; 149 | self.popoverButton.shadowHeight = 3.0f; 150 | self.popoverButton.cornerRadius = 6.0f; 151 | self.popoverButton.titleLabel.font = [UIFont boldFlatFontOfSize:16]; 152 | [self.popoverButton setTitleColor:[UIColor cloudsColor] forState:UIControlStateNormal]; 153 | [self.popoverButton setTitleColor:[UIColor cloudsColor] forState:UIControlStateHighlighted]; 154 | } 155 | } 156 | 157 | - (IBAction)showAlertView:(id)sender { 158 | FUIAlertView *alertView = [[FUIAlertView alloc] initWithTitle:@"Hello" message:@"This is an alert view" delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:@"Do Something", nil]; 159 | alertView.alertViewStyle = FUIAlertViewStylePlainTextInput; 160 | [@[[alertView textFieldAtIndex:0], [alertView textFieldAtIndex:1]] enumerateObjectsUsingBlock:^(FUITextField *textField, NSUInteger idx, BOOL *stop) { 161 | [textField setTextFieldColor:[UIColor cloudsColor]]; 162 | [textField setBorderColor:[UIColor asbestosColor]]; 163 | [textField setCornerRadius:4]; 164 | [textField setFont:[UIFont flatFontOfSize:14]]; 165 | [textField setTextColor:[UIColor midnightBlueColor]]; 166 | }]; 167 | [[alertView textFieldAtIndex:0] setPlaceholder:@"Text here!"]; 168 | 169 | alertView.delegate = self; 170 | alertView.titleLabel.textColor = [UIColor cloudsColor]; 171 | alertView.titleLabel.font = [UIFont boldFlatFontOfSize:16]; 172 | alertView.messageLabel.textColor = [UIColor cloudsColor]; 173 | alertView.messageLabel.font = [UIFont flatFontOfSize:14]; 174 | alertView.backgroundOverlay.backgroundColor = [[UIColor cloudsColor] colorWithAlphaComponent:0.8]; 175 | alertView.alertContainer.backgroundColor = [UIColor midnightBlueColor]; 176 | alertView.defaultButtonColor = [UIColor cloudsColor]; 177 | alertView.defaultButtonShadowColor = [UIColor asbestosColor]; 178 | alertView.defaultButtonFont = [UIFont boldFlatFontOfSize:16]; 179 | alertView.defaultButtonTitleColor = [UIColor asbestosColor]; 180 | [alertView show]; 181 | } 182 | 183 | - (IBAction)showPopover:(id)sender { 184 | UIButton *button = (UIButton *)sender; 185 | 186 | UIViewController *vc = [[UIViewController alloc] init]; 187 | vc.view.backgroundColor = [UIColor whiteColor]; 188 | vc.title = @"FUIPopoverController"; 189 | 190 | if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) { 191 | vc.preferredContentSize = CGSizeMake(320, 480); 192 | self.navigationController.navigationBar.titleTextAttributes = @{NSFontAttributeName:[UIFont boldFlatFontOfSize:18], 193 | NSForegroundColorAttributeName: [UIColor whiteColor]}; 194 | } else { 195 | // Pre-iOS7 methods 196 | vc.contentSizeForViewInPopover = CGSizeMake(320, 480); 197 | vc.navigationController.navigationBar.titleTextAttributes = @{UITextAttributeFont: [UIFont boldFlatFontOfSize:18], 198 | UITextAttributeTextColor: [UIColor whiteColor]}; 199 | } 200 | 201 | UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc]; 202 | 203 | _popoverController = [[UIPopoverController alloc] initWithContentViewController:nc]; 204 | [_popoverController configureFlatPopoverWithBackgroundColor:[UIColor turquoiseColor] cornerRadius:9.0]; 205 | _popoverController.delegate = self; 206 | 207 | [_popoverController presentPopoverFromRect:button.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 208 | } 209 | 210 | - (void)showTableView:(id)sender { 211 | TableViewController* tableViewController = [[TableViewController alloc] initWithStyle:UITableViewStyleGrouped]; 212 | [self.navigationController pushViewController:tableViewController animated:YES]; 213 | } 214 | 215 | - (void)showPlainTableView:(id)sender { 216 | TableViewController* tableViewController = [[TableViewController alloc] initWithStyle:UITableViewStylePlain]; 217 | [self.navigationController pushViewController:tableViewController animated:YES]; 218 | } 219 | 220 | -(void)iconsButtonPressed:(UIButton*)button { 221 | IconViewController *iconViewController = [[IconViewController alloc]init]; 222 | [self.navigationController pushViewController:iconViewController animated:YES]; 223 | } 224 | 225 | #pragma mark - UIPopoverControllerDelegate Methods 226 | 227 | - (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController 228 | { 229 | return YES; 230 | } 231 | 232 | - (void) popoverControllerDidDismissPopover:(UIPopoverController *)popoverController { 233 | _popoverController = nil; 234 | } 235 | 236 | @end 237 | -------------------------------------------------------------------------------- /Example/FlatUIKitExample/ViewController_iPad.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 56 | 66 | 73 | 80 | 87 | 94 | 101 | 108 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /Example/FlatUIKitExample/ViewController_iPhone.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 51 | 58 | 65 | 72 | 79 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 102 | 103 | 104 | 105 | 106 | 113 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /Example/FlatUIKitExample/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/FlatUIKitExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // FlatUIKitExample 4 | // 5 | // Created by Alejandro Benito Santos on 5/16/13. 6 | // 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Example/README images/fuialertview-small.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Example/README images/fuialertview-small.gif -------------------------------------------------------------------------------- /Example/README images/fuialertview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Example/README images/fuialertview.gif -------------------------------------------------------------------------------- /Example/README images/fuibutton-small.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Example/README images/fuibutton-small.gif -------------------------------------------------------------------------------- /Example/README images/fuibutton.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Example/README images/fuibutton.gif -------------------------------------------------------------------------------- /Example/README images/fuinavbar-small.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Example/README images/fuinavbar-small.gif -------------------------------------------------------------------------------- /Example/README images/fuipopovercontroller-small.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Example/README images/fuipopovercontroller-small.gif -------------------------------------------------------------------------------- /Example/README images/fuislider-small.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Example/README images/fuislider-small.gif -------------------------------------------------------------------------------- /Example/README images/fuistepper-small.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Example/README images/fuistepper-small.gif -------------------------------------------------------------------------------- /Example/README images/fuiswitch-small.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Example/README images/fuiswitch-small.gif -------------------------------------------------------------------------------- /Example/README images/fuiswitch.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Example/README images/fuiswitch.gif -------------------------------------------------------------------------------- /Example/README images/fuitableview-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Example/README images/fuitableview-small.png -------------------------------------------------------------------------------- /Example/README images/fuitableview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Example/README images/fuitableview.png -------------------------------------------------------------------------------- /Example/README images/fuitextfield-small.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Example/README images/fuitextfield-small.gif -------------------------------------------------------------------------------- /FlatUIKit.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "FlatUIKit" 3 | s.version = "1.6.2" 4 | s.summary = "A collection of awesome flat UI components for iOS." 5 | s.homepage = "https://github.com/Grouper/FlatUIKit" 6 | s.license = 'MIT' 7 | s.authors = { "Jamie Matthews" => "jmatthews08@gmail.com" } 8 | s.source = { :git => "https://github.com/Grouper/FlatUIKit.git", :tag => "1.6.2" } 9 | s.platform = :ios, '6.0' 10 | s.source_files = 'Classes', 'Classes/**/*.{h,m}' 11 | 12 | s.resources = "Resources/*" 13 | s.frameworks = 'QuartzCore', 'CoreText' 14 | s.requires_arc = true 15 | end 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Grouper, Inc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | Background 2 | ====== 3 | FlatUIKit was originally written by Jack Flintermann in March of 2013, before iOS7 had even come out. The idea was to give a nice flat look to some of the native iOS components. Then iOS7 came along and introduced a decent API to do most of these tasks. 4 | 5 | However, for backwards compatability, we will be attempting to maintain iOS6 compatability, as long as feasabilty possible. If we find a reason to move to iOS7 only support, we will leave a branch for remaining iOS6 support, and move forward. 6 | 7 | FlatUIKit 8 | ====== 9 | 10 | FlatUIKit is a collection of iOS components styled with the "Flat UI" aesthetic that we created while building [Grouper for iPhone](http://www.joingrouper.com). Its design inspiration comes from [Flat UI](http://designmodo.github.io/Flat-UI/) and [Kyle Miller](http://kylemillercreative.com/grouper-social-club). Styling is implemented via categories on/drop-in replacements for existing UIKit components, so integrating it into your project is very straightforward. 11 | 12 | Installation 13 | ------- 14 | 15 | FlatUIKit can be installed via [CocoaPods](http://cocoapods.org/). Simply add 16 | 17 | ```ruby 18 | pod 'FlatUIKit' 19 | ``` 20 | 21 | to your Podfile. If you don't use CocoaPods you're welcome to use git submodules, or simply [download it](https://github.com/Grouper/FlatUIKit/archive/master.zip) and include it in your project manually. 22 | 23 | Note that FlatUIKit requires the CoreText framework as well as iOS > 6.0. 24 | 25 | The Components 26 | ------- 27 | 28 | ### Buttons 29 | 30 | FUIButton is a drop-in subclass of UIButton that exposes the additional properties buttonColor, shadowColor, cornerRadius, and shadowHeight. Note that if you set any of these, you have to set all of them. 31 | 32 | ```objective-c 33 | myButton.buttonColor = [UIColor turquoiseColor]; 34 | myButton.shadowColor = [UIColor greenSeaColor]; 35 | myButton.shadowHeight = 3.0f; 36 | myButton.cornerRadius = 6.0f; 37 | myButton.titleLabel.font = [UIFont boldFlatFontOfSize:16]; 38 | [myButton setTitleColor:[UIColor cloudsColor] forState:UIControlStateNormal]; 39 | [myButton setTitleColor:[UIColor cloudsColor] forState:UIControlStateHighlighted]; 40 | ``` 41 | 42 | ![FUIButton](https://raw.github.com/Grouper/FlatUIKit/master/Example/README%20images/fuibutton-small.gif) 43 | 44 | ### TextFields 45 | 46 | FUITextField is a drop-in subclass of UITextField that exposes the additional properties edgeInsets, textFieldColor, borderColor, borderWidth and cornerRadius. Note that if you set any of these, you have to set all of them. 47 | 48 | ```objective-c 49 | myTextField.font = [UIFont flatFontOfSize:16]; 50 | myTextField.backgroundColor = [UIColor clearColor]; 51 | myTextField.edgeInsets = UIEdgeInsetsMake(4.0f, 15.0f, 4.0f, 15.0f); 52 | myTextField.textFieldColor = [UIColor whiteColor]; 53 | myTextField.borderColor = [UIColor turquoiseColor]; 54 | myTextField.borderWidth = 2.0f; 55 | myTextField.cornerRadius = 3.0f; 56 | ``` 57 | 58 | ![FUITextField](Example/README%20images/fuitextfield-small.gif) 59 | 60 | ### SegmentedControls 61 | 62 | FUISegmentedControl is a drop-in subclass of UISegmentedControl that exposes the additional properties selectedColor, deselectedColor, selectedFont, deselectedFont, selectedFontColor, deselectedFontColor, dividerColor and cornerRadius. Note that if you set any of these, it is recommended that you set all of them. 63 | 64 | ```objective-c 65 | mySegmentedControl.selectedFont = [UIFont boldFlatFontOfSize:16]; 66 | mySegmentedControl.selectedFontColor = [UIColor cloudsColor]; 67 | mySegmentedControl.deselectedFont = [UIFont flatFontOfSize:16]; 68 | mySegmentedControl.deselectedFontColor = [UIColor cloudsColor]; 69 | mySegmentedControl.selectedColor = [UIColor amethystColor]; 70 | mySegmentedControl.deselectedColor = [UIColor silverColor]; 71 | mySegmentedControl.dividerColor = [UIColor midnightBlueColor]; 72 | mySegmentedControl.cornerRadius = 5.0; 73 | ``` 74 | 75 | ### Switches 76 | 77 | FUISwitch is not a subclass of UISwitch (UISwitch is too inflexible to subclass), but rather a reimplementation that exposes all of the methods of UISwitch. In addition, it also provides access to its underlying on/off UILabels and other subviews. 78 | 79 | ```objective-c 80 | mySwitch.onColor = [UIColor turquoiseColor]; 81 | mySwitch.offColor = [UIColor cloudsColor]; 82 | mySwitch.onBackgroundColor = [UIColor midnightBlueColor]; 83 | mySwitch.offBackgroundColor = [UIColor silverColor]; 84 | mySwitch.offLabel.font = [UIFont boldFlatFontOfSize:14]; 85 | mySwitch.onLabel.font = [UIFont boldFlatFontOfSize:14]; 86 | ``` 87 | 88 | ![FUISwitch](https://raw.github.com/Grouper/FlatUIKit/master/Example/README%20images/fuiswitch-small.gif) 89 | 90 | ### Alert Views 91 | 92 | Similar to FUISwitch, FUIAlertView is a reimplemenation of UIAlertView that exposes all of UIAlertView's methods (and delegate methods, with the FUIAlertViewDelegate protocol), but with far greater flexibility in UI customization. All of its child UILabels, UIViews, and FUIButtons can be customized at will. 93 | 94 | ```objective-c 95 | FUIAlertView *alertView = [[FUIAlertView alloc] initWithTitle:@"Hello" 96 | message:@"This is an alert view" 97 | delegate:nil cancelButtonTitle:@"Dismiss" 98 | otherButtonTitles:@"Do Something", nil]; 99 | alertView.titleLabel.textColor = [UIColor cloudsColor]; 100 | alertView.titleLabel.font = [UIFont boldFlatFontOfSize:16]; 101 | alertView.messageLabel.textColor = [UIColor cloudsColor]; 102 | alertView.messageLabel.font = [UIFont flatFontOfSize:14]; 103 | alertView.backgroundOverlay.backgroundColor = [[UIColor cloudsColor] colorWithAlphaComponent:0.8]; 104 | alertView.alertContainer.backgroundColor = [UIColor midnightBlueColor]; 105 | alertView.defaultButtonColor = [UIColor cloudsColor]; 106 | alertView.defaultButtonShadowColor = [UIColor asbestosColor]; 107 | alertView.defaultButtonFont = [UIFont boldFlatFontOfSize:16]; 108 | alertView.defaultButtonTitleColor = [UIColor asbestosColor]; 109 | [alertView show]; 110 | ``` 111 | 112 | NOTE: to create FUIAlertView instance in Swift please use default initializer 113 | s 114 | ```swift 115 | let alertView = FUIAlertView() 116 | ``` 117 | FUIAlertView 118 | 119 | ### Sliders/Steppers/Progress Views 120 | To provide flat UISliders, UIProgressViews and UISteppers, we simply provide categories on UISlider/ProgressView/UIStepper to automatically configure their appearance with appropriate colors/corner radii. This makes for zero-friction integration with your existing project: 121 | 122 | ```objective-c 123 | [mySlider configureFlatSliderWithTrackColor:[UIColor silverColor] 124 | progressColor:[UIColor alizarinColor] 125 | thumbColor:[UIColor pomegranateColor]]; 126 | ``` 127 | 128 | ![FUISlider](https://raw.github.com/Grouper/FlatUIKit/master/Example/README%20images/fuislider-small.gif) 129 | 130 | ```objective-c 131 | [myProgressView configureFlatProgressViewWithTrackColor:[UIColor silverColor] 132 | progressColor:[UIColor alizarinColor]]; 133 | 134 | [myStepper configureFlatStepperWithColor:[UIColor wisteriaColor] 135 | highlightedColor:[UIColor wisteriaColor] 136 | disabledColor:[UIColor amethystColor] 137 | iconColor:[UIColor cloudsColor]]; 138 | ``` 139 | 140 | ![FUIStepper](https://raw.github.com/Grouper/FlatUIKit/master/Example/README%20images/fuistepper-small.gif) 141 | 142 | ### Bar Button Items 143 | To customize bar button items for your entire application (including back buttons), UIBarButtonItem+FlatUI provides a class method which leverages the UIBarButtonItem appearance proxy to do this in one step: 144 | 145 | ```objective-c 146 | [UIBarButtonItem configureFlatButtonsWithColor:[UIColor peterRiverColor] 147 | highlightedColor:[UIColor belizeHoleColor] 148 | cornerRadius:3]; 149 | ``` 150 | 151 | ![FUINavBar](https://raw.github.com/Grouper/FlatUIKit/master/Example/README%20images/fuinavbar-small.gif) 152 | 153 | However, this might cause rendering issues with controllers that are pushed from actionsheets, sharesheets or links in webviews. To prevent this behavior, scope the customized bar buttom items to your controllers: 154 | 155 | ```objective-c 156 | [UIBarButtonItem configureFlatButtonsWithColor:[UIColor peterRiverColor] 157 | highlightedColor:[UIColor belizeHoleColor] 158 | cornerRadius:3 159 | whenContainedIn:[YourViewController class]]; 160 | ``` 161 | 162 | ### Navigation Bars 163 | As above, we provide a category on UINavigationBar to configure it flatly with a single color: 164 | 165 | ```objective-c 166 | [self.navigationController.navigationBar configureFlatNavigationBarWithColor:[UIColor midnightBlueColor]]; 167 | ``` 168 | 169 | ### TableView Cells 170 | You can modify the backgroundColor and selectedBackgroundColor of a UITableViewCell without losing the rounded corners. The cell will copy the UITableView's separator color. The separator height is exposed as separatorHeight and the radius as cornerRadius. 171 | 172 | ```objective-c 173 | UITableViewCell *cell = ...; 174 | [cell configureFlatCellWithColor:[UIColor greenSeaColor] 175 | selectedColor:[UIColor cloudsColor] 176 | roundingCorners:corners]; 177 | 178 | cell.cornerRadius = 5.0f; // optional 179 | cell.separatorHeight = 2.0f; // optional 180 | ``` 181 | 182 | ![FUITableViewCell](https://raw.github.com/Grouper/FlatUIKit/master/Example/README%20images/fuitableview-small.png) 183 | 184 | 185 | ### Popover 186 | Like some other flat components, we simply provide a category to automatically configure a popover appearance for iPad by only having to set a background color. 187 | 188 | ```objective-c 189 | popover = [[UIPopoverController alloc] initWithContentViewController:nc]; 190 | [popover configureFlatPopoverWithBackgroundColor: [UIColor midnightBlueColor] cornerRadius:3]; 191 | popover.delegate = self; 192 | [popover presentPopoverFromRect:button.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 193 | ``` 194 | 195 | ![Popover](https://raw.github.com/Grouper/FlatUIKit/master/Example/README%20images/fuipopovercontroller-small.gif) 196 | 197 | Colors 198 | ------- 199 | 200 | For convenience, FlatUIKit includes the colors defined at [Flat UI Colors](http://flatuicolors.com/). You can see examples of these colors in the code/components above. Using them is as simple as: 201 | 202 | ```objective-c 203 | #import 204 | UIColor *myColor = [UIColor turquoiseColor]; 205 | ``` 206 | 207 | Fonts 208 | ------- 209 | 210 | FlatUIKit comes bundled with Lato, a clean, beautiful open font. More info on Lato can be found [here](http://www.latofonts.com/). It is included in FlatUIKit automatically; you can use it as follows: 211 | 212 | ```objective-c 213 | #import "UIFont+FlatUI.h" 214 | UIFont *myFont = [UIFont flatFontOfSize:16]; 215 | ``` 216 | 217 | Icons 218 | ------- 219 | 220 | You can now use the great icons provided by [FlatUIKit](http://designmodo.github.io/Flat-UI/) in your app. The easiest way is to use a label, but I will be adding support to use them in buttons, ImageViews, and other conveniences. 221 | 222 | ```objective-c 223 | #import "NSString+Icons.h" 224 | UILabel *label = [...] 225 | label.font = [UIFont iconFontWithSize:16]; 226 | label.text = [NSString iconStringForEnum:FUIHeart]; 227 | ``` 228 | 229 | The icons follow roughly the same naming scheme as FlatUI, but you can look up the enumeration in NSString+Icons.h 230 | 231 | Contributions 232 | -------- 233 | 234 | Contributions are totally welcome. We'll review all pull requests and if you send us a good one/are interested we're happy to give you push access to the repo. 235 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | desc 'Setup the schemes required to run iOS tests' 2 | task :prepare do 3 | system(%Q{mkdir -p "Tests/FUIKitTests.xcodeproj/xcshareddata/xcschemes" && cp Tests/Schemes/*.xcscheme "Tests/FUIKitTests.xcodeproj/xcshareddata/xcschemes/"}) 4 | end 5 | 6 | task :ios => :prepare do 7 | $test_success = system('xctool -workspace Tests/FUIKitTests.xcworkspace -scheme FUIKitTests build -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO') 8 | $test_success = system('xctool -workspace Tests/FUIKitTests.xcworkspace -scheme FUIKitTests build-tests -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO') 9 | $test_success = system('xctool -workspace Tests/FUIKitTests.xcworkspace -scheme FUIKitTests test -test-sdk iphonesimulator ONLY_ACTIVE_ARCH=NO') 10 | end 11 | 12 | desc 'Run all iOS tests' 13 | task :test => :ios do 14 | if $test_success 15 | puts '** All tests passed successfully **' 16 | else 17 | puts 'Unit tests failed' 18 | exit(-1) 19 | end 20 | end 21 | 22 | task :default => 'test' 23 | -------------------------------------------------------------------------------- /Resources/Lato-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Resources/Lato-Bold.ttf -------------------------------------------------------------------------------- /Resources/Lato-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Resources/Lato-Italic.ttf -------------------------------------------------------------------------------- /Resources/Lato-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Resources/Lato-Light.ttf -------------------------------------------------------------------------------- /Resources/Lato-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Resources/Lato-Regular.ttf -------------------------------------------------------------------------------- /Resources/flat-ui-icons-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Resources/flat-ui-icons-regular.ttf -------------------------------------------------------------------------------- /Tests/FUIKitTests.xcodeproj/xcshareddata/xcschemes/FUIKitTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 94 | 100 | 101 | 102 | 103 | 105 | 106 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /Tests/FUIKitTests/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Tests/FUIKitTests/Default-568h@2x.png -------------------------------------------------------------------------------- /Tests/FUIKitTests/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Tests/FUIKitTests/Default.png -------------------------------------------------------------------------------- /Tests/FUIKitTests/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grouper/FlatUIKit/63fea9a86cadb2180173e29bf75fa978ec999fc6/Tests/FUIKitTests/Default@2x.png -------------------------------------------------------------------------------- /Tests/FUIKitTests/FUIAppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface FUIAppDelegate : UIResponder 4 | 5 | @property (strong, nonatomic) UIWindow *window; 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /Tests/FUIKitTests/FUIAppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "FUIAppDelegate.h" 2 | 3 | @implementation FUIAppDelegate 4 | 5 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 6 | { 7 | return YES; 8 | } 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Tests/FUIKitTests/FUIKitTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | Grouper.${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 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Tests/FUIKitTests/FUIKitTests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'FUIKitTests' target in the 'FUIKitTests' 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 | -------------------------------------------------------------------------------- /Tests/FUIKitTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Tests/FUIKitTests/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // FUIKitTests 4 | // 5 | // Created by Adam Fraser on 8/06/13. 6 | // Copyright (c) 2013 Grouper. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "FUIAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([FUIAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Tests/FUIKitTestsTests/FUIAlertViewTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // FUIKitTestsTests.m 3 | // FUIKitTestsTests 4 | // 5 | // Copyright (c) 2013 Grouper. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "FUIAlertView.h" 10 | #import "SenTestCase+FUITestHelpers.h" 11 | 12 | #define EXP_SHORTHAND YES 13 | #import 14 | 15 | @interface FUIAlertViewTests : SenTestCase 16 | @property (strong, nonatomic) FUIAlertView *alertView; 17 | 18 | //Delegate method flags 19 | @property (nonatomic) BOOL willPresent; 20 | @property (nonatomic) BOOL didPresent; 21 | @property (nonatomic) BOOL clickedButton; 22 | @property (nonatomic) BOOL willDismissWithIndex; 23 | @property (nonatomic) BOOL didDismissWithIndex; 24 | @property (nonatomic) NSInteger delegateButtonIndex; 25 | @end 26 | 27 | @implementation FUIAlertViewTests 28 | 29 | - (void)setUp { 30 | [super setUp]; 31 | self.alertView = [[FUIAlertView alloc] initWithTitle:@"Test Title" message:@"Test message" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:nil, nil]; 32 | [self.alertView setAnimationDuration:0]; 33 | [self.alertView setDelegate:self]; 34 | [self setDelegateButtonIndex:1]; 35 | } 36 | 37 | - (void)testAlertViewInitializesWithTitle { 38 | expect(self.alertView.title).to.equal(@"Test Title"); 39 | expect(self.alertView.titleLabel.text).to.equal(@"Test Title"); 40 | } 41 | 42 | - (void)testAlertViewInitializesWithMessage { 43 | expect(self.alertView.message).to.equal(@"Test message"); 44 | expect(self.alertView.messageLabel.text).to.equal(@"Test message"); 45 | } 46 | 47 | - (void)testAlertViewInitializesWithOnlyCancelButton { 48 | expect(self.alertView.buttons.count).to.equal(1); 49 | } 50 | 51 | - (void)testAlertViewSetsCorrectCancelButtonTitle { 52 | UIButton *cancelButton = [self.alertView.buttons objectAtIndex:[self.alertView cancelButtonIndex]]; 53 | expect(cancelButton.titleLabel.text).to.equal(@"Cancel"); 54 | } 55 | 56 | - (void)testAlertViewCanInitializeWithMultipleButtons { 57 | FUIAlertView *multiButtonAlert = [[FUIAlertView alloc] initWithTitle:@"Test title" message:@"Test Message" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", @"Maybe", nil]; 58 | expect(multiButtonAlert.buttons.count).to.equal(3); 59 | } 60 | 61 | - (void)testAlertViewAlwaysInitializesCancelButtonAsIndexZero { 62 | FUIAlertView *multiButtonAlert = [[FUIAlertView alloc] initWithTitle:@"Test Title" message:@"Test message" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"Button1", @"Button2", nil]; 63 | UIButton *cancelButton = [multiButtonAlert.buttons objectAtIndex:0]; 64 | expect(cancelButton.titleLabel.text).to.equal(@"Cancel"); 65 | } 66 | 67 | - (void)testAlertViewAlwaysPlacesCancelButtonBelowOtherButtons { 68 | FUIAlertView *multiButtonAlert = [[FUIAlertView alloc] initWithTitle:@"Test Title" message:@"Test message" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"Button1", @"Button2", nil]; 69 | [multiButtonAlert layoutSubviews]; 70 | 71 | CGRect cancelButtonFrame = [[multiButtonAlert.buttons objectAtIndex:0] frame]; 72 | CGRect button1Frame = [[multiButtonAlert.buttons objectAtIndex:1] frame]; 73 | CGRect button2Frame = [[multiButtonAlert.buttons objectAtIndex:2] frame]; 74 | 75 | expect(cancelButtonFrame.origin.y).to.beGreaterThan(button1Frame.origin.y); 76 | expect(cancelButtonFrame.origin.y).to.beGreaterThan(button2Frame.origin.y); 77 | } 78 | 79 | - (void)testAlertViewSetsCorrectOtherButtonTitles { 80 | FUIAlertView *multiButtonAlert = [[FUIAlertView alloc] initWithTitle:@"Test title" message:@"Test message" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"Title1", @"Title2", nil]; 81 | UIButton *otherButton1 = [multiButtonAlert.buttons objectAtIndex:1]; 82 | UIButton *otherButton2 = [multiButtonAlert.buttons objectAtIndex:2]; 83 | expect(otherButton1.titleLabel.text).to.equal(@"Title1"); 84 | expect(otherButton2.titleLabel.text).to.equal(@"Title2"); 85 | } 86 | 87 | - (void)testAddButtonWithTitleReturnsCorrectIndex { 88 | NSInteger buttonIndex = [self.alertView addButtonWithTitle:@"New button"]; 89 | expect(buttonIndex).to.equal(1); 90 | expect([self.alertView buttonTitleAtIndex:buttonIndex]).to.equal(@"New button"); 91 | } 92 | 93 | - (void)testAddButtonWithTitleAddsNewButton { 94 | [self.alertView addButtonWithTitle:@"New button"]; 95 | expect(self.alertView.buttons.count).to.equal(2); 96 | } 97 | 98 | - (void)testAddButtonWithTitleParamaterCannotBeNil { 99 | NSInteger buttonIndex = [self.alertView addButtonWithTitle:nil]; 100 | expect(buttonIndex).to.equal(-1); 101 | expect([[self.alertView buttons] count]).to.equal(1); 102 | } 103 | 104 | - (void)testWillPresentAlertView { 105 | [self.alertView show]; 106 | expect(self.willPresent).to.beTruthy(); 107 | } 108 | 109 | - (void)testDidPresentAlertView { 110 | [self.alertView show]; 111 | [self waitForAnimations]; 112 | expect(self.didPresent).to.beTruthy(); 113 | } 114 | 115 | - (void)testAlertViewWillDissmissWithButtonIndex { 116 | [self.alertView show]; 117 | [self.alertView clickButtonAtIndex:0]; 118 | expect(self.willDismissWithIndex).to.beTruthy(); 119 | expect(self.delegateButtonIndex).to.equal(0); 120 | } 121 | 122 | - (void)testAlertViewDidDissmissWithButtonIndex { 123 | [self.alertView show]; 124 | [self.alertView clickButtonAtIndex:0]; 125 | [self waitForAnimations]; 126 | expect(self.didDismissWithIndex).to.beTruthy(); 127 | expect(self.delegateButtonIndex).to.equal(0); 128 | } 129 | 130 | - (void)testAlertViewClickedButtonAtIndex{ 131 | [self.alertView show]; 132 | [self.alertView clickButtonAtIndex:0]; 133 | expect(self.clickedButton).to.beTruthy(); 134 | expect(self.delegateButtonIndex).to.equal(0); 135 | } 136 | 137 | // Delegate methods 138 | 139 | - (void)willPresentAlertView:(FUIAlertView *)alertView { 140 | [self setWillPresent:YES]; 141 | } 142 | 143 | - (void)didPresentAlertView:(FUIAlertView *)alertView { 144 | [self setDidPresent:YES]; 145 | } 146 | 147 | - (void)alertView:(FUIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex { 148 | [self setWillDismissWithIndex:YES]; 149 | [self setDelegateButtonIndex:buttonIndex]; 150 | } 151 | 152 | - (void)alertView:(FUIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { 153 | [self setDidDismissWithIndex:YES]; 154 | [self setDelegateButtonIndex:buttonIndex]; 155 | } 156 | 157 | - (void)alertView:(FUIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { 158 | [self setClickedButton:YES]; 159 | [self setDelegateButtonIndex:buttonIndex]; 160 | } 161 | 162 | @end 163 | -------------------------------------------------------------------------------- /Tests/FUIKitTestsTests/FUIKitTestsTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | Grouper.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Tests/FUIKitTestsTests/FUITableViewCellTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // FUITableViewCellTests.m 3 | // FUIKitTestsTests 4 | // 5 | // Copyright (c) 2013 Grouper. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "UITableViewCell+FlatUI.h" 10 | #import "FUICellBackgroundView.h" 11 | #import "SenTestCase+FUITestHelpers.h" 12 | 13 | #define EXP_SHORTHAND YES 14 | #import 15 | 16 | @interface FUITableViewCellTests : SenTestCase 17 | 18 | @end 19 | 20 | @implementation FUITableViewCellTests 21 | 22 | 23 | - (void)testFlatBackgroundsWithInstanceMethodConfigureFlatCell { 24 | static NSString *CellIdentifier = @"Cell"; 25 | 26 | UITableViewCell* tableViewCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 27 | [tableViewCell configureFlatCellWithColor:[UIColor whiteColor] selectedColor:[UIColor blackColor]]; 28 | 29 | expect(tableViewCell.backgroundView).to.beInstanceOf([FUICellBackgroundView class]); 30 | expect(tableViewCell.selectedBackgroundView).to.beInstanceOf([FUICellBackgroundView class]); 31 | } 32 | 33 | - (void)testFlatBackgroundsWithStaticMethodConfigureFlatCell { 34 | static NSString *CellIdentifier = @"Cell"; 35 | 36 | UITableViewCell* tableViewCell = [UITableViewCell configureFlatCellWithColor:[UIColor whiteColor] selectedColor:[UIColor blackColor] style:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 37 | 38 | expect(tableViewCell.backgroundView).to.beInstanceOf([FUICellBackgroundView class]); 39 | expect(tableViewCell.selectedBackgroundView).to.beInstanceOf([FUICellBackgroundView class]); 40 | } 41 | 42 | 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /Tests/FUIKitTestsTests/SenTestCase+FUITestHelpers.h: -------------------------------------------------------------------------------- 1 | // 2 | // SenTestCase+FUIKitTestHelpers.h 3 | // FUIKitTests 4 | // 5 | // Copyright (c) 2013 Grouper. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface SenTestCase (FUITestHelpers) 11 | 12 | - (void)waitForAnimations; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Tests/FUIKitTestsTests/SenTestCase+FUITestHelpers.m: -------------------------------------------------------------------------------- 1 | // 2 | // SenTestCase+FUIKitTestHelpers.m 3 | // FUIKitTests 4 | // 5 | // Copyright (c) 2013 Grouper. All rights reserved. 6 | // 7 | 8 | #import "SenTestCase+FUITestHelpers.h" 9 | 10 | @implementation SenTestCase (FUITestHelpers) 11 | 12 | - (void)waitForAnimations { 13 | NSTimeInterval timeout = 0.1; 14 | NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:timeout]; 15 | while ([loopUntil timeIntervalSinceNow] > 0) 16 | { 17 | [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:loopUntil]; 18 | } 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Tests/FUIKitTestsTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Tests/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, 5.0 2 | 3 | pod 'Expecta' 4 | -------------------------------------------------------------------------------- /Tests/Schemes/FUIKitTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 94 | 100 | 101 | 102 | 103 | 105 | 106 | 109 | 110 | 111 | --------------------------------------------------------------------------------