$30 off During Our Annual Pro Sale. View Details »

CodeFest 2019. Антон Спивак (ВКонтакте) — iOS. ...

CodeFest
April 06, 2019

CodeFest 2019. Антон Спивак (ВКонтакте) — iOS. Переход на тёмную сторону

У нас было три сотни экранов, страх все сломать, монструозный UIKit, огромная куча старого кода и жгучее желание сделать тёмную тему.

Этот рассказ будет о том, как подружить свою архитектуру с дизайнерами и JS-разработчиками, добавить цветовые схемы, не прогореть по производительности и в итоге, зауважать создателей UIKit.

CodeFest

April 06, 2019
Tweet

More Decks by CodeFest

Other Decks in Technology

Transcript

  1. RGB

  2. HUE

  3. Автоподбор HUEColor ls = [leftColor HSV]; HUEColor rs = [rightColor

    HSV]; CGFloat dh = fmin(fabs(ls.hue - rs.hue), 360.0f - fabs(ls.hue - rs.hue)) / 180.0f; CGFloat ds = fabs(ls.saturation - rs.saturation); CGFloat dv = fabs(ls.brightness - rs.brightness) / 255.0f; CGFloat distance = sqrtf((dh * dh) + (ds * ds) + (dv * dv));
  4. Условия Максимально простое решение Минимум изменений в текущем коде Работа

    с CoreGraphics (CALayer’s and etc.) Работа с TextKit, CoreText (NSAttributedString) Работа с UIKit VKUI (VK Apps, VK Connect) Android (а вдруг?)
  5. Ух, что сейчас будет • Быстро подберем формат • Подумаем

    над хранением • Определимся с архитектурой (VIPER) • Чуть-чуть покодим
  6. Colors.h @interface UIColor (Palette) @property (nonatomic, readonly, strong, class) UIColor

    *azure300; @end @interface Color (Scheme) @property (nonatomic, readonly, strong, class) Color *accent; @end
  7. Библиотеки https://github.com/regexident/Gestalt 
 (много кода, нет поддержки NSAttributedString) https://github.com/draveness/DKNightVersion 


    (много кода, нет поддержки NSAttributedString) И вообще их нужно поддерживать, в топку такое
  8. CoreGraphics int CGColorCreate(int space, int components) { rax = (*_CGColorCreate_ptr)(space,

    components); return rax; } void CGContextSetFillColorWithColor(CGContextRef, CGColorRef)
  9. UIKit @interface UIDeviceRGBColor : UIColor { double alphaComponent double blueComponent

    double greenComponent double redComponent } @interface UIDeviceWhiteColor : UIColor { double alphaComponent double whiteComponent }
  10. NSProxy - (void)forwardInvocation:(NSInvocation *)aInvocation { [aInvocation invokeWithTarget:[self _keyedColor]]; } -

    (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { return [[self _keyedColor] methodSignatureForSelector:aSelector]; }
  11. NSProxy - (UIColor *)_keyedColor { UIColor *color = [self.colors valueForKey:[Appearance

    appearance].palette.name]; // Here we need to cache CGColor for system usage [color CGColor]; return color; }
  12. Независимая палитра! @interface Appearance : NSObject <Painter> @property (nonatomic, strong,

    nullable) Palette *palette; @end @interface UIResponder (Painter) <Painter> @property (nonatomic, strong, nullable) Palette *palette; @end
  13. И обновим хитрый цвет - (UIColor *)_keyedColor { UIColor *color

    = [self.colors valueForKey:[self _painter].palette.name]; // Here we need to cache CGColor for system usage [color CGColor]; return color; }
  14. Цвета с сервера? - (instancetype)overridedValues:(NSDictionary<NSString *, UIColor *> *)v {

    NSMutableDictionary *currentColors = [self.colors mutableCopy]; [v enumerateKeysAndObjectsUsingBlock:^(NSString *k, UIColor *o, BOOL *stop) { [currentColors setObject:o forKey:k]; }]; return [[Color alloc] initWithIdentifier:[self.identifier copy] colors:[currentColors copy] alpha:self.alpha painter:self.painter]; }
  15. Другое значение alpha? - (UIColor *)colorWithAlphaComponent:(CGFloat)alpha { Color *color =

    [[Color alloc] initWithIdentifier:[self.identifier copy] colors:[self.colors copy] alpha:alpha painter:self.painter]; return (id)color; }
  16. KPACUBO - (UIColor *)_keyedColor { UIColor *color = [self.colors valueForKey:[self

    _painter].palette.name]; color = self.alpha < 1.0 ? [color colorWithAlphaComponent:self.alpha] : color; // Here we need to cache CGColor for system usage [color CGColor]; return color; }
  17. DEBUG void UpdateSchemeColor(SEL selector, UIColor *c, NSString *paletteName) { Color

    *color = (Color *)[Color performSelector:selector]; NSMutableDictionary *colors = [[color colors] mutableCopy]; [colors setValue:color forKey:paletteName]; [color updateColorsWithDictionary:[colors copy]]; }
  18. Ну почти :D • -[UIView backgroundColor] - вычислимое свойство •

    -[UIView tintColor] - нужно дернуть tintColorDidChange • -[UILabel attributedText] - нужно немного зафорсить • И другие небольшие особенности UIKit’а • Дизассемблируй это - https://hopperapp.com