Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the recommended method of styling an iOS app?

Tags:

What is the recommended method of styling an iOS app? For example, if there are multiple labels or text views how can updating font style/color at one place update the style/color at all other places?

I know sub classing could be one way... is there any other way?

like image 603
Yogesh Agarwal Avatar asked Aug 22 '11 18:08

Yogesh Agarwal


2 Answers

You could import a standard header file into all your controllers with several constants set for styling... example:

Styles.h

#define kFontSize 14 #define kFontFamily @"Helevetica" 

Controller

#import "Styles.h" // at the top  myLabel.font = [UIFont fontWithName:kFontFamily size:kFontSize]; 

I personally think Interface Builder is the best way to style, however this answers your question directly.

like image 108
Alex Coplan Avatar answered Sep 22 '22 19:09

Alex Coplan


Update: I would recommend starting by understanding UIAppearance APIs, and seeing how well they suit your needs. UIAppearance is a convenient way to provide custom default stylization of specific controls' attributes at multiple levels (e.g. globally or contextually).


My original answer, which predated UIAppearance's availability:


since we're working with an object based language...

for the implementation, it depends on how you want it to behave/execute. when the implementation becomes nontrivial, i will often create a protocol. you could use class methods or instance methods and significantly optimize these types for your usage because you create fewer intermediate colors, fonts, images, etc.

a basic interface could take the form:

@protocol MONLabelThemeProtocol  - (UIFont *)labelFont; - (UIColor *)labelTextColor; - (UITextAlignment)labelTextAlignment; // ... @end  @protocol MONTableViewCellThemeProtocol  - (UIFont *)tableViewCellFont; - (UIColor *)tableViewCellTextColor; - (UIImage *)tableViewCellImage; - (NSInteger)tableViewCellIndentationLevel; - (CGFloat)tableViewCellIndentationWidth; // ... @end 

then a simple amalgamate theme could be declared like this:

@interface MONAmalgamateThemeBase : NSObject    < MONLabelThemeProtocol, MONTableViewCellThemeProtocol > { @protected     /* labels */     UIFont * labelFont;     UIColor * labelTextColor;     UITextAlignment labelTextAlignment;     // ...     /* table view cells */     UIFont * tableViewCellFont;     UIColor * tableViewCellTextColor;     UIImage * tableViewCellImage;     NSInteger tableViewCellIndentationLevel;     CGWidth tableViewCellIndentationWidth;     // ... }  @end 

in this example, the amalgamate defines the getters and dealloc and expects the subclasses to initialize the instance variables. you could also support lazy initialization if initialization times are high (e.g. uses many images).

then a specialization could take the form:

@interface MONDarkTheme : MONAmalgamateThemeBase @end  @implementation MONDarkTheme  - (id)init {     self = [super init];     if (nil != self) {         labelFont = [[UIFont boldSystemFontOfSize:15] retain];         labelTextColor = [[UIColor redColor] retain];         // and so on...     }     return self; }  // ...  @end  /* declare another theme and set it up appropriately */ @interface MONLightTheme : MONAmalgamateThemeBase @end 

then just reuse the theme instances (e.g. MONDarkTheme) throughout the app to stylize the views. if you have a lot of themes or they are not trivial to construct, then you may want to create a collection for themes (theme manager). the amalgamate could also take a parameter, such as init with theme if your needs are simple. you can even configure objects to register for changes to themes, if you need support for dynamic changes.

finally, you can create a simple theme applier to make life easier - like so:

@interface UILabel (MONThemeAdditions)  - (void)mon_applyMONLabelTheme:(id<MONLabelTheme>)theme;  @end  @implementation UILabel (MONThemeAdditions)  - (void)mon_applyMONLabelTheme:(id<MONLabelTheme>)theme {     assert(theme);     if (nil == theme) return;     self.font = [theme labelFont];     self.textColor = [theme labelTextColor];     self.textAlignment = [theme labelTextAlignment]; }  @end 
like image 37
justin Avatar answered Sep 25 '22 19:09

justin