<commit_before>![SwiftTheme](https://raw.githubusercontent.com/jiecao-fm/SwiftThemeResources/master/Screenshots/logo.png)

<p align="center">
<a href="#introduction">Introduction</a> -
<a href="#demos">Demos</a> -
<a href="#installation">Installation</a> -
<a href="#documents">Documents</a> -
<a href="#contribution">Contribution</a> -
<a href="README_CN.md">中文文档</a>
</p>

<p align="center">
<a href="https://developer.apple.com/swift"><img src="https://img.shields.io/badge/language-swift2-f48041.svg?style=flat"></a>
<a href="https://developer.apple.com/ios"><img src="https://img.shields.io/badge/platform-iOS%207%2B-blue.svg?style=flat"></a>
<a href="https://github.com/Carthage/Carthage"><img src="https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat"></a>
<a href="http://cocoadocs.org/docsets/SwiftTheme"><img src="https://img.shields.io/badge/Cocoapods-compatible-4BC51D.svg?style=flat"></a>
<a href="https://github.com/jiecao-fm/SwiftTheme/blob/master/LICENSE"><img src="http://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat"></a>
<a href="https://github.com/jiecao-fm/SwiftTheme/tree/0.2"><img src="https://img.shields.io/badge/release-0.2-blue.svg"></a>
<a href="https://travis-ci.org/jiecao-fm/SwiftTheme"><img src="https://travis-ci.org/jiecao-fm/SwiftTheme.svg"></a>
</p>

## Screenshot

![](https://github.com/jiecao-fm/SwiftThemeResources/blob/master/Screenshots/switch.gif)

> Running：open `SwiftTheme.xcworkspace`, run target `PlistDemo`

## Introduction
### The Beginning Of The Story

As the project requirement, we need to add night mode to our app "节操精选". It's not as simple as changing brightness or alpha only on the top-level view. In fact, it need a entirely new interface: different colors, different alpha, different image cuts. More accurately, so called "night mode" is themes/skinning feature that can switch between a bright theme and a dark theme.

How to achieve this? Maybe we can set a global variable represents current selected theme, use different background colors or different image cuts based on the variable during the controllers initialization. But how to deal with the views that have been initialized? Yes, maybe you think we can use notification to change their colors or image cuts. Thought here, you should premonition that your controllers will be filled up with notification register/unregister, if...else and UI updating codes. Worse, if you forget to unregister the notifications app may crash.

After some consideration, we put forward higher requirements on the task: create a simple and reusable themes/skinning framework, here as you see.

### Goals

Make SwiftTheme a simple, powerful, high-performance, extensible themes/skinning framework. Provide a unified solution for iOS.

## Demos


### Index Mode

Vary background color of UIView according to the theme setting?

```swift
view.theme_backgroundColor = ThemeColorPicker(colors: "#FFF", "#000")
```

Vary text color of UILable and UIButton?

```swift
label.theme_textColor = ThemeColorPicker(colors: "#000", "#FFF")
button.theme_setTitleColor(ThemeColorPicker(colors: "#000", "#FFF"), forState: .Normal)
```

Vary image of UIImageView?

```swift
imageView.theme_image = ThemeImagePicker(names: "day", "night")
```

No problem! A miracle happens after you executing the one line of code below!

```swift
// these numbers represent the parameters' index. 
// eg. "ThemeColorPicker(colors: "#000", "#FFF")", index 0 represents "#000", index 1 represents "#FFF"
ThemeManager.setTheme(isNight ? 1 : 0)
```

> Index mode is a fast way for these situation: a few themes, but not many, no need to download more new themes.


### Plist Mode
You may want to make you app download and install an indefinite number of themes. To fulfill this requirement, we provide the plist mode. Simply put, you write the configurations in a plist file, such as colors, image cuts and so on. Then, you can use their keys in the logic code. So, the plist file and the resource files it used constitute a theme package.

Usage demo of plist mode.

```swift
view.theme_backgroundColor = ThemeColorPicker(keyPath: "Global.backgroundColor")
imageView.theme_image = ThemeImagePicker(keyPath: "SelectedThemeCell.iconImage")
```
> Similar with the index mode. Only the specific parameters become keys. And as such, we give it the extension ability.


The plist file name is the first paramter of the switching method. In this example, the plist file and other resource files are in the application bundle. It's also ok if they are in sandbox.

```swift
ThemeManager.setTheme("Red", path: .MainBundle)
```

> plist mode allow you install more themes without modifying logic code. So, you can add the feature that, downloading and installing themes for your app.

the screenshots of the plist and image files we used above:

![](https://github.com/jiecao-fm/SwiftThemeResources/blob/master/Screenshots/2.pic.jpg)
![](https://github.com/jiecao-fm/SwiftThemeResources/blob/master/Screenshots/1.pic.jpg)

### Objective-C

Fully compatible with Objective-C, usage demo:

```objective-c
lbl.theme_backgroundColor = [ThemeColorPicker pickerWithColors:@[@"#FAF9F9", @"#E2E2E2"]];
```

### Features
- [x] Written in Swift
- [x] Fully compatible with Objective-C
- [x] Based on runtime
- [x] Simple integration
- [x] Extension property prefix with "theme_*", friendly with IDE auto-completion
- [x] Support UIAppearance
- [x] Index mode, fast integration
- [x] Plist mode, extend infinite themes
- [x] Friendly error logs
- [x] Strongly typed ThemePicker, detect errors during compilling
- [x] Complete demos


## Installation

> *Swift code is built as dynamic framework by Cocoapods, Carthage and the project itself, so dynamic frameworks works on iOS8+*
>
> **If you want it work on iOS7, you should copy the source files into you project**

#### Cocoapods
```swift
pod 'SwiftTheme'
use_frameworks!
```

#### Carthage
```swift
github "jiecao-fm/SwiftTheme"
```

#### Framework
Build the source project, drop the SwiftTheme.framework into your project

#### Source files（iOS7）
Copy all the files in "Source" folder into your project

## Documents

Note：`①` usage of index mode `②` usage of plist mode
<commit_msg>Correct the spelling of CocoaPods in README<commit_after>![SwiftTheme](https://raw.githubusercontent.com/jiecao-fm/SwiftThemeResources/master/Screenshots/logo.png)

<p align="center">
<a href="#introduction">Introduction</a> -
<a href="#demos">Demos</a> -
<a href="#installation">Installation</a> -
<a href="#documents">Documents</a> -
<a href="#contribution">Contribution</a> -
<a href="README_CN.md">中文文档</a>
</p>

<p align="center">
<a href="https://developer.apple.com/swift"><img src="https://img.shields.io/badge/language-swift2-f48041.svg?style=flat"></a>
<a href="https://developer.apple.com/ios"><img src="https://img.shields.io/badge/platform-iOS%207%2B-blue.svg?style=flat"></a>
<a href="https://github.com/Carthage/Carthage"><img src="https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat"></a>
<a href="http://cocoadocs.org/docsets/SwiftTheme"><img src="https://img.shields.io/badge/CocoaPods-compatible-4BC51D.svg?style=flat"></a>
<a href="https://github.com/jiecao-fm/SwiftTheme/blob/master/LICENSE"><img src="http://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat"></a>
<a href="https://github.com/jiecao-fm/SwiftTheme/tree/0.2"><img src="https://img.shields.io/badge/release-0.2-blue.svg"></a>
<a href="https://travis-ci.org/jiecao-fm/SwiftTheme"><img src="https://travis-ci.org/jiecao-fm/SwiftTheme.svg"></a>
</p>

## Screenshot

![](https://github.com/jiecao-fm/SwiftThemeResources/blob/master/Screenshots/switch.gif)

> Running：open `SwiftTheme.xcworkspace`, run target `PlistDemo`

## Introduction
### The Beginning Of The Story

As the project requirement, we need to add night mode to our app "节操精选". It's not as simple as changing brightness or alpha only on the top-level view. In fact, it need a entirely new interface: different colors, different alpha, different image cuts. More accurately, so called "night mode" is themes/skinning feature that can switch between a bright theme and a dark theme.

How to achieve this? Maybe we can set a global variable represents current selected theme, use different background colors or different image cuts based on the variable during the controllers initialization. But how to deal with the views that have been initialized? Yes, maybe you think we can use notification to change their colors or image cuts. Thought here, you should premonition that your controllers will be filled up with notification register/unregister, if...else and UI updating codes. Worse, if you forget to unregister the notifications app may crash.

After some consideration, we put forward higher requirements on the task: create a simple and reusable themes/skinning framework, here as you see.

### Goals

Make SwiftTheme a simple, powerful, high-performance, extensible themes/skinning framework. Provide a unified solution for iOS.

## Demos


### Index Mode

Vary background color of UIView according to the theme setting?

```swift
view.theme_backgroundColor = ThemeColorPicker(colors: "#FFF", "#000")
```

Vary text color of UILable and UIButton?

```swift
label.theme_textColor = ThemeColorPicker(colors: "#000", "#FFF")
button.theme_setTitleColor(ThemeColorPicker(colors: "#000", "#FFF"), forState: .Normal)
```

Vary image of UIImageView?

```swift
imageView.theme_image = ThemeImagePicker(names: "day", "night")
```

No problem! A miracle happens after you executing the one line of code below!

```swift
// these numbers represent the parameters' index. 
// eg. "ThemeColorPicker(colors: "#000", "#FFF")", index 0 represents "#000", index 1 represents "#FFF"
ThemeManager.setTheme(isNight ? 1 : 0)
```

> Index mode is a fast way for these situation: a few themes, but not many, no need to download more new themes.


### Plist Mode
You may want to make you app download and install an indefinite number of themes. To fulfill this requirement, we provide the plist mode. Simply put, you write the configurations in a plist file, such as colors, image cuts and so on. Then, you can use their keys in the logic code. So, the plist file and the resource files it used constitute a theme package.

Usage demo of plist mode.

```swift
view.theme_backgroundColor = ThemeColorPicker(keyPath: "Global.backgroundColor")
imageView.theme_image = ThemeImagePicker(keyPath: "SelectedThemeCell.iconImage")
```
> Similar with the index mode. Only the specific parameters become keys. And as such, we give it the extension ability.


The plist file name is the first paramter of the switching method. In this example, the plist file and other resource files are in the application bundle. It's also ok if they are in sandbox.

```swift
ThemeManager.setTheme("Red", path: .MainBundle)
```

> plist mode allow you install more themes without modifying logic code. So, you can add the feature that, downloading and installing themes for your app.

the screenshots of the plist and image files we used above:

![](https://github.com/jiecao-fm/SwiftThemeResources/blob/master/Screenshots/2.pic.jpg)
![](https://github.com/jiecao-fm/SwiftThemeResources/blob/master/Screenshots/1.pic.jpg)

### Objective-C

Fully compatible with Objective-C, usage demo:

```objective-c
lbl.theme_backgroundColor = [ThemeColorPicker pickerWithColors:@[@"#FAF9F9", @"#E2E2E2"]];
```

### Features
- [x] Written in Swift
- [x] Fully compatible with Objective-C
- [x] Based on runtime
- [x] Simple integration
- [x] Extension property prefix with "theme_*", friendly with IDE auto-completion
- [x] Support UIAppearance
- [x] Index mode, fast integration
- [x] Plist mode, extend infinite themes
- [x] Friendly error logs
- [x] Strongly typed ThemePicker, detect errors during compilling
- [x] Complete demos


## Installation

> *Swift code is built as dynamic framework by CocoaPods, Carthage and the project itself, so dynamic frameworks works on iOS8+*
>
> **If you want it work on iOS7, you should copy the source files into you project**

#### CocoaPods
```swift
pod 'SwiftTheme'
use_frameworks!
```

#### Carthage
```swift
github "jiecao-fm/SwiftTheme"
```

#### Framework
Build the source project, drop the SwiftTheme.framework into your project

#### Source files（iOS7）
Copy all the files in "Source" folder into your project

## Documents

Note：`①` usage of index mode `②` usage of plist mode

{'fraction_non_alphanumeric': 0.12247191011235956, 'fraction_numerical': 0.007865168539325843, 'mean_word_length': 5.07557289127255, 'pattern_counts': {'":': 0, '<': 77, '<?xml version=': 0, '>': 91, 'https://': 32, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2154741', 'n_tokens_mistral': 3960, 'n_tokens_neox': 3699, 'n_words': 1344}