2011-08-22 236 views
22

什麼是推薦iOS應用程序樣式的方法?例如,如果有多個標籤或文本視圖,在一個地方如何更新字體樣式/顏色更新所有其他位置的樣式/顏色?什麼是推薦的iOS應用程序樣式?

我知道子分類可能是一種方法...有沒有其他方法?

+0

您可能需要查看此庫。它支持動態多個主題/皮膚。目前支持圖片和顏色。將來會添加字體支持。 https://github.com/charithnidarsha/MultiThemeManager –

回答

9

你可以導入一個標準的頭文件到所有的控制器與造型...例如設置幾個常數:

Styles.h

#define kFontSize 14 
#define kFontFamily @"Helevetica" 

控制器

#import "Styles.h" // at the top 

myLabel.font = [UIFont fontWithName:kFontFamily size:kFontSize]; 

我個人認爲Interface Builder是風格的最佳方式,howe這直接回答你的問題。

+4

我不會downvote它,但...如果選擇走這條路線,外部聲明,如:'extern const CGFloat MONDarkThemeFontSize;'和'extern NSString * const MONDarkThemeFontName;'比'#define kShortName值'更可取,原因有很多。 – justin

+0

我寧願因爲我認爲這是最簡單的方法,非常適合我在工作的應用程序。感謝Alex和@Justin。 – Yogesh

+0

這不是一個好主意。 – DexterW

3

亞歷克斯的想法類似,您可以創建一個名爲ThemeManager靜態類:

typedef enum 
{ 
    defaultStyle, 
    redStyle, 
} ThemeStyles; 

@interface Level : NSObject 
{ 
    ThemeStyles currentTheme; 
} 

可主題將導入ThemeManager所有課程。然後,您可以創建如下方法:

+ (UIColor*) fontColor; 

其他類在需要字體顏色時會調用哪些類。然後,如果你想改變的主題,你可以實現fontColor爲:

+ (UIColor*) fontColor 
{ 
    switch (currentTheme) 
    { 
     case defaultStyle: 
     return [UIColor blackColor]; 
     case redStyle: 
     return [UIColor redColor]; 
    } 
} 

當你想改變的主題,你可以有ThemeManager實施等的方法:

+ (void) changeTheme:(ThemeStyles)newTheme 
{ 
    currentTheme = newTheme; 
} 
6

坦率地說,最好的關於這方面的方法是使用Interface Builder。儘管在代碼的某處更改單個常量並讓整個應用程序改變樣式看起來不錯,但它永遠不會那麼順利。這裏是我的推理:

1)開發人員不寫界面代碼以及界面生成器。 界面生成器是一個經過精心設計,經過測試並經過處理的工具。它提供了字體,文本對齊,陰影等。它可以向後兼容,只要你想要。它爲任何數量的開發人員和設計人員提供了一種非常簡單的方法,可以直接參與並處理一些非常簡單的事情。

2)總是有一些邊緣情況需要考慮。當然,一個簡單的常量會做你最想要的時間,但是你最終必須在這裏破解一些東西,並在那裏偷偷摸摸。您開始編寫的「簡單」界面代碼將會增長並不斷增長。其他開發人員將不得不維護該代碼。您將不得不維護該代碼。你將不得不提交和修復錯誤,調整這個,除了這個,等等。它將不可避免地變成一團糟。

3)您編寫的代碼越多,寫入的錯誤就越多。界面構建器用於構建大多數iOS應用程序的'外觀'。用它。不要太聰明。

注意: 據我所知,界面生成器不能爲所有應用程序做所有事情。有些情況下,編碼接口是唯一的解決方案。這個答案只是我在大部分應用程序中使用的一般「最佳實踐」。

+2

+1。只需製作不同風格的單獨筆尖並重新加載視圖即可。 –

+1

我仍然遇到需要通過Objective-C管理或設計UI的應用程序。很高興知道如何去做。 – BlueConga

9

更新:我建議從理解UIAppearance API開始,看看它們能夠滿足您的需求。 UIAppearance是一種提供多個級別(例如全局或上下文)中特定控件屬性的自定義默認樣式的便捷方式。


我原來的答案,這早UIAppearance的可用性:


因爲我們有一個基於對象的語言工作......

的實施,這取決於你希望如何表現/執行。當實現變得平淡無奇時,我會經常創建一個協議。你可以使用類方法或實例方法和顯著,因爲你創造較少的中間顏色,字體,圖像等

優化這些類型爲您的使用情況基本的接口可以採取以下形式:

@protocol MONLabelThemeProtocol 

- (UIFont *)labelFont; 
- (UIColor *)labelTextColor; 
- (UITextAlignment)labelTextAlignment; 
// ... 
@end 

@protocol MONTableViewCellThemeProtocol 

- (UIFont *)tableViewCellFont; 
- (UIColor *)tableViewCellTextColor; 
- (UIImage *)tableViewCellImage; 
- (NSInteger)tableViewCellIndentationLevel; 
- (CGFloat)tableViewCellIndentationWidth; 
// ... 
@end 

然後簡單的合併將主題可以聲明如下:

@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 
在這個例子中

,該合併將定義getter和dealloc中,預計子類初始化實例變量。如果初始化時間很長(例如使用很多圖像),您也可以支持延遲初始化。

然後專業化可以採取以下形式:

@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 

然後只是重複使用整個應用程序的主題的實例(例如MONDarkTheme)風格化的觀點。如果你有很多主題或者他們不是微不足道的構建,那麼你可能想創建一個主題集合(主題管理器)。如果您的需求很簡單,合併器也可以採用一個參數,例如帶主題的init。如果您需要支持動態更改,則甚至可以配置對象以註冊主題更改。

最後,你可以創建一個簡單的主題施加使生活更輕鬆 - 像這樣:

@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 
+0

我喜歡這個答案,雖然它很老。現在我們擁有UIAppearance API的適用性如何? – bandejapaisa

+0

@bandejapaisa我已經更新了我的答案。在iOS7中有105次出現了'UI_APPEARANCE_SELECTOR' - 對於大多數應用程序的需求都有足夠的控制。如果您需要更多粒度或控制內存,屬性,樣式或應用程序功能(實際上,我剛剛開始了可能性),那麼上述方法可以爲您提供所有可用的控制。我也喜歡它,因爲它不一定是全球性的,也不是侵入性的。我看到了類似的方法,但是'UIAppearance'傾向於方便,而我的傾向是控制。另外,我傾向於編寫用戶界面... – justin

+0

@bandejapaisa ...以編程方式,所以這往往是一個反覆出現的問題與高地方(當所有的細節存在於同一個地方很容易應用和推動主題)。當細節存在於多個地方時 - 當您合併故事板,XIB和一些代碼時,它變得更加困難。不過,當初始化從源代碼移動到SB/XIB加載時,引入和應用這些程序化主題將不太方便。在這種情況下,您可能會覆蓋僅適用於主題。 – justin

1

我用的Plist。就像我本地化字符串一樣,我使用相同的過程來更改主題。我編寫了一個加載當前主題plist和備用plist的單身人士。然後,我用鍵和宏函數替換資源的名稱,這些函數從單例中抽取實際資源名稱。

缺點:您必須爲每個元素設置資源,而不是將其設置在NIB中。
優點:一旦你完成,下一個主題大部分涉及Photoshop和textmate,而不是IB或代碼。

3

可以使用UIAppearance的第三方抽象:

使用故事板有很多的好處,但是許多樣式選項不可用,其中最重要的是自定義字體。如果你想要一個深度定製的UI,你將需要一些樣式代碼來實現它。

相關問題