KnightWatson 0.1.3

KnightWatson 0.1.3

TestsTested
LangLanguage Obj-CObjective C
License MIT
ReleasedLast Release Mar 2016

Maintained by coppercash.



  • By
  • CopperCash

Knight Watson

Knight Watson is a theme managing library, with which an iOS app can easily add functions like Night Version. Benefiting from the runtime of ObjC, Knight Watson can add theme to an instance with simply a suffix following it. Thus, it would save you from many hours of learning unfamiliar new methods.

Demo

Demo

How to Use

The Most Basic

All magic starts from the suffix knw_themable, and then what left are only familiar Cocoa methods.

    // Configure the instance with values by theme
    //
    UIView
    *view = [[UIView alloc] init];
    view.knw_themable.backgroundColor = (id)@{@"daylight": UIColor.whiteColor,
                                                 @"night": UIColor.blackColor,};

    // Change the theme sometime later
    //
    KNWThemeContext.defaultThemeContext.theme = @"night";

Themed Arguments

An argument will be regarded as themed if it conforms to protocol KNWObjectArgument. Class KNWThemedArgument is provided with the library as an example. Take a look at how method knw_valueWithThemeContext: is implemented, so you can implement your own THEMED ARGUMENTS. For example, to make NSDictionary themed argument:

@interface NSDictionary (KNWObjectArgument) <KNWObjectArgument>
@end

@implementation NSDictionary (KNWObjectArgument)

- (id)knw_valueWithThemeContext:(KNWThemeContext *)context
{
    return self[context.theme];
}

@end

Non-object Arguments

Non-object arguments are supported as well:

    UIView
    *view = [[UIView alloc] init];
    NSDictionary
    *framesByTheme =
    @{@"theme_a": [NSValue valueWithCGRect:CGRectMake(1., 1., 1., 1.)],
      @"theme_b": [NSValue valueWithCGRect:CGRectMake(2., 2., 2., 2.)],};

    [view
     .knw_themable
     .argAtIndex(0, framesByTheme)
     setFrame:CGRectZero];

To be used as themed argument for non-object value, a class muse conform protocol KNWNonObjectArgument. Also, take a look at the implementation of the example method KNWThemedArgument#knw_invocation:setArgumentAtIndex:withThemeContext:.

Instance with Short Lifetime

Sometimes, we just want the value for the current theme instead of its changing with the theme. In that case, we need one more line:

    UIView
    *view = [[UIView alloc] init];
    NSDictionary
    *colorsByTheme = @{@"daylight": UIColor.whiteColor,
                       @"night": UIColor.blackColor,};
    [view
     .knw_themable
     .keepThemable(NO)
     setBackgroundColor:(id)colorsByTheme];

Or simply use the convenient suffix (notice that the suffix is replaced with knw_themed):

    view.knw_themed.backgroundColor = (id)@{@"daylight": UIColor.whiteColor,
                                            @"night": UIColor.blackColor,};

What can be a Theme?

KNWThemeContext#theme is of type id. So it can be of any class as long as your implementation for KNWObjectArgument (or KNWNonObjectArgument) can handle it. For example, if instances of NSNumber are used as themes, NSArray will be able to be passed as themed argument:

    KNWThemeContext.defaultThemeContext.theme = @1;

    UIButton
    *button = [[UIButton alloc] init];
    NSArray
    *colorsByTheme = @[UIColor.whiteColor, UIColor.blackColor,];
    [button.knw_themable setTitleColor:(id)colorsByTheme
                              forState:UIControlStateNormal];

Todo

  • [x] [UIButton, UILabel, UIImageView...] support
  • [x] [UIColor, UIImage, NSAttributedString...] support
  • [x] Mutiple themes support
  • [x] Custom theme type support
  • [x] Cocoapods support
  • [x] Non-object (primitive types, C struct) argument support
  • [x] Custom argument implementation support
  • [x] Dot expression support
  • [ ] Multiple threads (multiple theme contexts) support
  • [ ] Class methods support
  • [ ] Duplicate registered invocations removal
  • [ ] Notifications for theme-switching
  • [ ] Support OS X
  • [ ] Support Cathage
  • [ ] Documentation