[英]What is the recommended method of styling an iOS app?
設計iOS應用程序的推薦方法是什么? 例如,如果有多個標簽或文本視圖,如何在一個地方更新字體樣式/顏色更新所有其他位置的樣式/顏色?
我知道子分類可能是一種方式......還有其他方法嗎?
您可以將標准頭文件導入到所有控制器中,並為樣式設置幾個常量...示例:
Styles.h
#define kFontSize 14
#define kFontFamily @"Helevetica"
調節器
#import "Styles.h" // at the top
myLabel.font = [UIFont fontWithName:kFontFamily size:kFontSize];
我個人認為Interface Builder是最好的樣式方式,但是這可以直接回答你的問題。
更新:我建議首先了解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
在此示例中,amalgamate定義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)來設置視圖的樣式。 如果你有很多主題或者它們不是很容易構建,那么你可能想要為主題創建一個集合(主題管理器)。 如果你的需求很簡單,amalgamate也可以帶一個參數,比如帶主題的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
坦率地說,最好的方法是使用Interface Builder。 雖然在代碼中的某個地方更改單個常量並讓整個應用程序更改樣式似乎很不錯,但它從來都不會那樣。 以下是我的推理:
1)開發人員不像接口構建器那樣編寫接口代碼。 接口生成器是被提煉,測試,並應允了多年來的工具。 它提供字體,文本對齊,陰影等。它可以向后兼容,因為它可以追溯到你想要的地方。 它為任何數量的開發人員和設計人員提供了一種非常簡單的方法,可以非常直接地進入並開展工作。
2)您總是需要考慮邊緣情況。 當然,一個簡單的常數會做你想要的最多的時間,但你最終必須在這里破解一些東西並在那里潛行。 您開始編寫的“簡單”界面代碼將會增長,增長和增長。 其他開發人員必須維護該代碼。 您將不得不維護該代碼。 你將不得不提交和修復錯誤,調整它,除了等等。它將不可避免地成為一堆亂七八糟的東西。
3)你寫的代碼越多,你寫的錯誤就越多。 界面構建器用於構建大多數iOS應用程序的“外觀”。 用它。 不要太聰明。
注意:我知道“界面”構建器無法為所有應用程序執行所有操作。 有些情況下編碼接口是唯一的解決方案。 這個答案只是我在大部分應用中使用的一般“最佳實踐”。
您可以使用UIAppearance的第三方抽象:
使用Storyboard有很多好處,但很多樣式選項都不可用,其中最不自然的是自定義字體。 如果您想要一個深度定制的UI,您將需要一些樣式代碼來實現它。
與Alex的想法類似,您可以創建一個名為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;
}
我用plist。 正如我本地化字符串一樣,我使用相同的過程來更改主題。 我編寫了一個加載當前主題plist和后備plist的單例。 然后我用鍵和宏函數替換資源的名稱,從單例中提取真實的資源名稱。
缺點:您必須為每個元素設置資源,而不僅僅是在NIB中設置它。
優點:一旦你完成,下一個主題的大部分涉及photoshop和textmate,而不是IB或代碼。
您可能需要查看此庫。 它支持多個主題/皮膚。 目前支持圖像和顏色。 將來會添加字體支持。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.