Каков рекомендуемый метод стилевого оформления приложения для iOS? - PullRequest
23 голосов
/ 22 августа 2011

Каков рекомендуемый метод стилевого оформления приложения для iOS?Например, если имеется несколько меток или текстовых представлений, как обновление стиля / цвета шрифта в одном месте может обновить стиль / цвет во всех других местах?

Я знаю, что подклассификация может быть одним из способов ... есть ли другой способ?

Ответы [ 7 ]

9 голосов
/ 23 августа 2011

Обновление: Я бы рекомендовал начать с понимания 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
9 голосов
/ 22 августа 2011

Вы можете импортировать стандартный заголовочный файл во все ваши контроллеры с несколькими константами, установленными для стиля ... пример:

Styles.h

#define kFontSize 14
#define kFontFamily @"Helevetica"

Контроллер

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

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

Лично я считаю, что Interface Builder - лучший способ стилизовать, однако это напрямую отвечает на ваш вопрос.

6 голосов
/ 23 августа 2011

Честно говоря, лучший способ сделать это - использовать Interface Builder. Хотя может показаться целесообразным изменить одну константу где-то в коде и изменить стили всего приложения, это никогда не сработает. Вот мои рассуждения:

1) Разработчики не пишут код интерфейса, как это делает строитель интерфейса. Интерфейсный конструктор - это инструмент, который был усовершенствован, протестирован и внедрен в течение лет . Он предлагает шрифты, выравнивание текста, тени и т. Д. Он обратно совместим так далеко, как вы когда-либо хотели. Он предоставляет очень простой способ для любого числа разработчиков и дизайнеров подключиться и поработать над чем-то очень простым.

2) Всегда есть крайние случаи, которые вы должны учитывать. Конечно, простая константа будет делать то, что вы хотите больше всего времени, но вам в конечном итоге придется что-то здесь взломать и пробраться туда что-нибудь «Простой» интерфейсный код, который вы написали для начала, будет расти, расти и расти. Другие разработчики должны будут поддерживать этот код. Вам придется поддерживать этот код. Вам придется регистрировать и исправлять ошибки, настраивать их, кроме того, и т. Д. Это неизбежно превратится в кучу беспорядка.

3) Чем больше кода вы пишете, тем больше ошибок вы пишете. Конструктор интерфейса предназначен для создания «внешнего вида» большинства приложений iOS. Используй это. Не становись слишком умным.

Примечание: Я понимаю, что Интерфейсный конструктор не может сделать все для всех приложений. Есть случаи, когда кодирование интерфейса является единственным решением. Этот ответ - просто общая «лучшая практика», которую я использую в большинстве своих приложений.

3 голосов
/ 03 июня 2013

Вы можете использовать стороннюю абстракцию UIAppearance:

Использование раскадровки имеет много преимуществ, но многие опции стиля недоступны, не в последнюю очередь это пользовательские шрифты.Если вы хотите глубоко настроенный пользовательский интерфейс, вам потребуется код стиля, чтобы это произошло.

3 голосов
/ 23 августа 2011

По аналогии с идеей Алекса, вы можете создать статический класс под названием 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;
}
1 голос
/ 23 августа 2011

Я использую списки. Так же, как я локализую строки, я использую ту же процедуру для изменения тем. Я кодировал синглтон, который загружает текущий список тем и запасной список. Затем я заменяю имена ресурсов ключами и макро-функциями, которые извлекают реальное имя ресурса из синглтона.

Минусы: вы должны установить ресурс для каждого элемента, а не просто установить его в NIB.
Плюсы: как только вы закончите, большая часть следующей темы включает фотошоп и текстового партнера, а не IB или код.

0 голосов
/ 31 мая 2014

Возможно, вам придется взглянуть на эту библиотеку. Он поддерживает несколько тем / скинов на лету. Поддерживает изображения и цвета в настоящее время. Поддержка шрифтов будет добавлена ​​в будущем.

https://github.com/charithnidarsha/MultiThemeManager

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...