Giter Site home page Giter Site logo

wxxsw / swifttheme Goto Github PK

View Code? Open in Web Editor NEW
2.5K 54.0 307.0 2.63 MB

🎨 Powerful theme/skin manager for iOS 9+ 主题/换肤, 暗色模式

License: MIT License

Swift 88.81% Objective-C 9.91% Ruby 0.68% C 0.60%
swift ios ui theme skin night-mode dark-mode

swifttheme's Introduction

SwiftTheme

Introduction - Demos - Installation - Documents - FAQ - Contribution - 中文文档

Screenshot

Running:open SwiftTheme.xcworkspace, run target PlistDemo

Introduction

The Beginning Of The Story

As part of our project requirement, we need to add night mode to our app. It's not as simple as just changing brightness or alpha on the top-level view—in fact, it needs an entirely new interface: different colors, different alpha, different image cuts. More accurately, "night mode" is a theme/skinning feature that can switch between bright theme and dark themes.

So how do we achieve this? Maybe we can set a global variable that represents the currently selected theme, and use different background colors or image cuts based on the variable during the controller's initialization. But then how do we deal with views that have already been initialized? Yes, we could use notifications to change their colors or image cuts, but this leads to controllers unnecessarily full of notification register/unregister, if...else and UI updating code. Worse, if you forget to unregister the notifications, your 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:

view.theme_backgroundColor = ["#FFF", "#000"]

Vary text color of UILabel and UIButton:

label.theme_textColor = ["#000", "#FFF"]
button.theme_setTitleColor(["#000", "#FFF"], forState: .Normal)

Vary image of UIImageView:

imageView.theme_image = ["day", "night"]

// It's ok by using UIImage instances if you don't want to use image names.
imageView.theme_image = ThemeImagePicker(images: image1, image2)

A miracle happens after you execute the single line of code below!

// these numbers represent the parameters' index. 
// eg. "view.theme_backgroundColor = ["#FFF", "#000"]", index 0 represents "#FFF", index 1 represents "#000"
ThemeManager.setTheme(index: isNight ? 1 : 0)

Get current theme index.

ThemeManager.currentThemeIndex	// Readonly

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

Notice About Literal:

// Wrong example:
let colors = ["#FFF", "#000"]
view.theme_backgroundColor = colors

// You should write like this:
view.theme_backgroundColor = ["#FFF", "#000"]
// or this:
let colorPickers: ThemeColorPicker = ["#FFF", "#000"]
view.theme_backgroundColor = colorPickers

Because theme_backgroundColor accepts an argument of type ThemeColorPicker,not Array. Nevertheless, "view.theme_backgroundColor = ["#FFF", "#000"]" does the same as initializing an instance of ThemeColorPicker by "Literal" and passing it to the theme_backgroundColor.

Plist/JSON Mode

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

Usage demo of plist mode.

view.theme_backgroundColor = "Global.backgroundColor"
imageView.theme_image = "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.

ThemeManager.setTheme(plistName: "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:

Objective-C

Fully compatible with Objective-C, usage demo:

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

Features

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

Installation

CocoaPods

pod 'SwiftTheme'
use_frameworks!

Carthage

github "wxxsw/SwiftTheme"

Swift Package Manager

  1. Select Xcode -> File -> Swift Packages -> Add Package Dependency...
  2. Enter https://github.com/wxxsw/SwiftTheme.
  3. Click Next, then select the version, complete.

Source files

Copy all the files in "Sources" folder into your project

Documents

Note: usage of index mode usage of plist mode

Basic Usage


Configure Appearance

SwiftTheme provides new properties for views, they all beigin with theme_. Such as theme_backgroundColor corresponds backgroundColor.

①
view.theme_backgroundColor = ThemeColorPicker(colors: "#FFF", "#000")
view.theme_image = ThemeImagePicker(names: "day", "night")
②
view.theme_backgroundColor = ThemeColorPicker(keyPath: "SomeColorKeyPath")
view.theme_image = ThemeImagePicker(keyPath: "SomeImageKeyPath")

Different type of properties receive different type of Pickers. Thus, IDE will warn you if you pass a wrong parameter.

Switch Themes

When you switch themes, all the theme_ properties you set will update with animation. Usage:

①
ThemeManager.setTheme(index: 0) // ThemePickers will use the first parameter, eg. "#FFF" "day"
ThemeManager.setTheme(index: 1) // ThemePickers will use the second parameter, eg. "#000" "night"// use "day.plist" in the appllication bundle as the theme configuration file. 
// In this mode, SwiftTheme will find the resource files in the appllication bundle.
ThemeManager.setTheme(plistName: "day", path: .mainBundle)
// use "night.plist" in the sandbox as the theme configuration file, "someURL" is its file path. 
// In this mode, SwiftTheme will find the resource files in the same path.
ThemeManager.setTheme(plistName: "night", path: .sandbox(someURL))
// use a dictionary as the theme configuration, but find resource files in the sandbox.(Not recommend)
ThemeManager.setTheme(dict: dict, path: .sandbox(someURL))

Custom Behaviors

SwiftTheme posts a notification named ThemeUpdateNotification when theme changes, you can observe this notification anywhere and do whatever you want:

NotificationCenter.default.addObserver(
	self, 
	selector: #selector(doSomethingMethod),
	name: NSNotification.Name(rawValue: ThemeUpdateNotification), 
	object: nil
)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doSomethingMethod) name:@"ThemeUpdateNotification" object:nil];

Now Supported Properties


Child classes inherit the properties from their super class, such as UILabel have theme_alpha inherited from UIView. These properties will not be list in child classes below.

UIView
  • var theme_alpha: ThemeCGFloatPicker?
  • var theme_backgroundColor: ThemeColorPicker?
  • var theme_tintColor: ThemeColorPicker?
UIApplication
  • func theme_setStatusBarStyle(picker: ThemeStatusBarStylePicker, animated: Bool)
UIBarButtonItem
  • var theme_tintColor: ThemeColorPicker?
UILabel
  • var theme_font: ThemeFontPicker?
  • var theme_textColor: ThemeColorPicker?
  • var theme_textAttributes: ThemeStringAttributesPicker?
  • var theme_highlightedTextColor: ThemeColorPicker?
  • var theme_shadowColor: ThemeColorPicker?
UINavigationBar
  • var theme_barStyle: ThemeBarStylePicker?
  • var theme_barTintColor: ThemeColorPicker?
  • var theme_titleTextAttributes: ThemeDictionaryPicker?
UITabBar
  • var theme_barStyle: ThemeBarStylePicker?
  • var theme_barTintColor: ThemeColorPicker?
UITableView
  • var theme_separatorColor: ThemeColorPicker?
UITextField
  • var theme_font: ThemeFontPicker?
  • var theme_keyboardAppearance: ThemeKeyboardAppearancePicker?
  • var theme_textColor: ThemeColorPicker?
  • var theme_placeholderAttributes: ThemeDictionaryPicker?
UITextView
  • var theme_font: ThemeFontPicker?
  • var theme_textColor: ThemeColorPicker?
UIToolbar
  • var theme_barStyle: ThemeBarStylePicker?
  • var theme_barTintColor: ThemeColorPicker?
UISegmentedControl
  • var theme_selectedSegmentTintColor: ThemeColorPicker?
  • func theme_setTitleTextAttributes(_ picker: ThemeStringAttributesPicker?, forState state: UIControl.State)
UISwitch
  • var theme_onTintColor: ThemeColorPicker?
  • var theme_thumbTintColor: ThemeColorPicker?
UISlider
  • var theme_thumbTintColor: ThemeColorPicker?
  • var theme_minimumTrackTintColor: ThemeColorPicker?
  • var theme_maximumTrackTintColor: ThemeColorPicker?
UISearchBar
  • var theme_barStyle: ThemeBarStylePicker?
  • var theme_barTintColor: ThemeColorPicker?
UIProgressView
  • var theme_progressTintColor: ThemeColorPicker?
  • var theme_trackTintColor: ThemeColorPicker?
UIPageControl
  • var theme_pageIndicatorTintColor: ThemeColorPicker?
  • var theme_currentPageIndicatorTintColor: ThemeColorPicker?
UIImageView
  • var theme_image: ThemeImagePicker?
UIActivityIndicatorView
  • var theme_activityIndicatorViewStyle: ThemeActivityIndicatorViewStylePicker?
UIButton
  • func theme_setImage(picker: ThemeImagePicker?, forState state: UIControlState)
  • func theme_setBackgroundImage(picker: ThemeImagePicker?, forState state: UIControlState)
  • func theme_setTitleColor(picker: ThemeColorPicker?, forState state: UIControlState)
  • func theme_setAttributedTitle(picker: ThemeAttributedStringPicker?, forState state: UIControlState)
CALayer
  • var theme_backgroundColor: ThemeCGColorPicker?
  • var theme_borderWidth: ThemeCGFloatPicker?
  • var theme_borderColor: ThemeCGColorPicker?
  • var theme_shadowColor: ThemeCGColorPicker?
CATextLayer
  • var theme_foregroundColor: ThemeCGColorPicker?
CAGradientLayer
  • var theme_colors: ThemeAnyPicker?
UIRefreshControl
  • var theme_titleAttributes: ThemeDictionaryPicker?
UIVisualEffectView
  • var theme_effect: ThemeVisualEffectPicker?

Picker


ThemeColorPicker

// supported formats:
// "#ffcc00"		RGB
// "#ffcc00dd"		RGBA
// "#FFF"			RGB in short
// "#013E"			RGBA in short
①
ThemeColorPicker(colors: "#FFFFFF", "#000")
ThemeColorPicker(colors: UIColor.red, UIColor.blue)
ThemeColorPicker.pickerWithColors(["#FFFFFF", "#000"])
ThemeColorPicker.pickerWithUIColors([UIColor.red, UIColor.blue])ThemeColorPicker(keyPath: "someStringKeyPath")
ThemeColorPicker.pickerWithKeyPath("someStringKeyPath")

ThemeImagePicker

①
ThemeImagePicker(names: "image1", "image2")
ThemeImagePicker.pickerWithNames(["image1", "image2"])
ThemeImagePicker(images: UIImage(named: "image1")!, UIImage(named: "image2")!)
ThemeImagePicker.pickerWithImages([UIImage(named: "image1")!, UIImage(named: "image2")!])ThemeImagePicker(keyPath: "someStringKeyPath")
ThemeImagePicker.pickerWithKeyPath("someStringKeyPath")

ThemeCGFloatPicker

①
ThemeCGFloatPicker(floats: 1.0, 0.7)
ThemeCGFloatPicker.pickerWithFloats([1.0, 0.7])ThemeCGFloatPicker(keyPath: "someNumberKeyPath")
ThemeCGFloatPicker.pickerWithKeyPath("someNumberKeyPath")

ThemeCGColorPicker

①
ThemeCGColorPicker(colors: "#FFFFFF", "#000")
ThemeCGColorPicker(colors: UIColor.red, UIColor.blue)
ThemeCGColorPicker(colors: UIColor.red.cgColor, UIColor.blue.cgColor)
ThemeCGColorPicker.pickerWithColors(["#FFFFFF", "#000"])
ThemeCGColorPicker.pickerWithUIColors([UIColor.blue, UIColor.red])ThemeCGColorPicker(keyPath: "someStringKeyPath")
ThemeCGColorPicker.pickerWithKeyPath("someStringKeyPath")

ThemeFontPicker

①
ThemeFontPicker(fonts: UIFont.systemFont(ofSize: 10), UIFont.systemFont(ofSize: 11))
ThemeFontPicker.pickerWithFonts([UIFont.systemFont(ofSize: 10), UIFont.systemFont(ofSize: 11)])// name the key you like, but the available values format like this: "PingFangSC-Regular,16"
ThemeFontPicker(keyPath: "someStringKeyPath")
ThemeFontPicker.pickerWithKeyPath("someStringKeyPath")

ThemeDictionaryPicker

①
ThemeDictionaryPicker(dicts: ["key": "value"], ["key": "value"])
ThemeDictionaryPicker.pickerWithDicts([["key": "value"], ["key": "value"]])ThemeDictionaryPicker(keyPath: "someStringKeyPath") { (Any?) -> [String: AnyObject]? in ... }

ThemeStringAttributesPicker

①
ThemeStringAttributesPicker(["key": "value"], ["key": "value"])
ThemeStringAttributesPicker.pickerWithAttributes([NSAttributedStringKey.font: UIFont.systemFont(ofSize: 16)])ThemeStringAttributesPicker(keyPath: "someStringKeyPath") { (Any?) -> [NSAttributedString.Key: Any]? in ... }

ThemeAttributedStringPicker

①
ThemeAttributedStringPicker(NSAttributedString(...), NSAttributedString(...))
ThemeAttributedStringPicker.pickerWithAttributedStrings([NSAttributedString(...)])ThemeAttributedStringPicker(keyPath: "someStringKeyPath") { (Any?) -> NSAttributedString? in ... }

ThemeBarStylePicker

①
ThemeBarStylePicker(styles: .default, .black)
ThemeBarStylePicker.pickerWithStyles([.default, .black])
ThemeBarStylePicker.pickerWithStringStyles(["default", "black"])// name the key you like, but the available values are "default" and "black"
ThemeBarStylePicker(keyPath: "someStringKeyPath")
ThemeBarStylePicker.pickerWithKeyPath("someStringKeyPath")

ThemeStatusBarStylePicker

①
ThemeStatusBarStylePicker(styles: .default, .lightContent, .darkContent)
ThemeStatusBarStylePicker.pickerWithStyles([.default, .lightContent, .darkContent])
ThemeStatusBarStylePicker.pickerWithStringStyles(["default", "lightContent", "darkContent"])// name the key you like, but the available values are "default", "lightContent" and "darkContent"
ThemeStatusBarStylePicker(keyPath: "someStringKeyPath")
ThemeStatusBarStylePicker.pickerWithKeyPath("someStringKeyPath")

ThemeKeyboardAppearancePicker

①
ThemeKeyboardAppearancePicker(styles: .default, .dark, .light)
ThemeKeyboardAppearancePicker.pickerWithStyles([.default, .dark, .light])
ThemeKeyboardAppearancePicker.pickerWithStringStyles(["default", "dark", "light"])// name the key you like, but the available values are "default", "dark" and "light"
ThemeKeyboardAppearancePicker(keyPath: "someStringKeyPath")
ThemeKeyboardAppearancePicker.pickerWithKeyPath("someStringKeyPath")

ThemeActivityIndicatorViewStylePicker

①
ThemeActivityIndicatorViewStylePicker(styles: .whiteLarge, .white, .gray)
ThemeActivityIndicatorViewStylePicker.pickerWithStyles([.whiteLarge, .white, .gray])
ThemeActivityIndicatorViewStylePicker.pickerWithStringStyles(["whiteLarge", "white", "gray"])// name the key you like, but the available values are "whiteLarge", "white" and "gray"
ThemeActivityIndicatorViewStylePicker(keyPath: "someStringKeyPath")
ThemeActivityIndicatorViewStylePicker.pickerWithKeyPath("someStringKeyPath")

ThemeVisualEffectPicker

①
ThemeVisualEffectPicker(effects: UIBlurEffect(style: .light), UIBlurEffect(style: .dark))
ThemeVisualEffectPicker.pickerWithEffects([UIBlurEffect(style: .light), UIBlurEffect(style: .dark)])
ThemeVisualEffectPicker.pickerWithStringEffects(["light", "dark", "extralight", "prominent", "regular"])// name the key you like, but the available values are "light", "dark", "extralight", "prominent" and "regular"
ThemeVisualEffectPicker(keyPath: "someStringKeyPath")
ThemeVisualEffectPicker.pickerWithKeyPath("someStringKeyPath")

ThemeAnyPicker

①
ThemeAnyPicker(anys: 0, "123", UIColor.red)
ThemeAnyPicker.pickerWithAnys([0, "123", UIColor.red])ThemeAnyPicker(keyPath: "someStringKeyPath")
ThemeAnyPicker.pickerWithKeyPath("someStringKeyPath")

More

Download this project and find more. There are four demo targets:

  • Demo shows how to use index mode and how to save the last selection of themes and other general usages.
  • PlistDemo shows how to use plist mode and how to download themes that packaged in zip files.
  • JsonDemo is like PlistDemo, but use json.
  • OCDemo is Demo's Objective-C version.
  • TVOSDemo is used to test tvos compatibility.

FAQ

  1. Why doesn't theme_setStatusBarStyle work as expected?

    In your app's Info.plist you will need to set View Controller-based status bar appearence to NO.

  2. Can I manually cancel the theme of a property?

    Sure, just make it nil—example: view.theme_backgroundColor = nil.

Contribution

Issue

If you find a bug or need a help, you can create a issue

Pull Request

We are happy to accept pull requests :D. But please make sure it's needed by most developers and make it simple to use. If you are not sure, create an issue and we can discuss it before you get to coding.

Contributors

Gesen, Zhoujun, Kevin Cramer

Lisence

The MIT License (MIT)

swifttheme's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swifttheme's Issues

How to make fonts themeable ?

May be this sound noob but I am looking to make fonts available from theme. Is there any way to achieve this using this awesome library ?

OC 调用Bug

下载到Documents里的plist文件,在调用setThemeWithPlistInSandbox方法的时候,会自动在plist文件名参数后拼接一个.plist后缀,导致原本的文件名由xxx.plist变成xxx.plist.plist,然后识别失败。

SwiftTheme WARNING: Not read plist 'momentsBear_theme.plist' with: /Users/fiber/Library/Developer/CoreSimulator/Devices/1FEF7344-AA28-494C-9B96-B4DF9D6F285F/data/Containers/Data/Application/D9F52344-3E99-42A8-819B-2C471D349709/Documents/Theme/1/theme3x/momentsBear_theme.plist.plist

tabBar.barStyle and navigationBar.barStyle stopped working with Swift 4

Hello, I recently updated to Swift 4 and noticed that this stopped working:

let navigationBar = UINavigationBar.appearance()
navigationBar.theme_barStyle = [.default, .black]

let tabBar = UITabBar.appearance()
tabBar.theme_barStyle = [.default, .black]

All I see is the default style that doesn't change when switching theme. Tested on both real device and simulator. However setting tabBar.barStyle = .black manually seems to work just fine. Any help?

textField.layer.theme_borderColor不生效

    textField.layer.theme_borderColor = ThemeCGColorPicker(keyPath: " LogInColors.textFieldLineColor") 一直是黑色 但我文件设置的是白色; 

我这样设置就能生效:
if let colorString = ThemeManager.value(for: "LogInColors.textFieldLineColor") as? String {
textField.layer.borderColor = UIColor.colorWithCSS(css: colorString).cgColor
}
麻烦您看下

特殊情况:结合SDWebImage使用

我在实际使用中遇到这种情况

[self.avatar sd_setBackgroundImageWithURL:[NSURL URLWithString:self.avatar]
                                     forState:UIControlStateNormal
                             placeholderImage:[UIImage imageWithName:@"img_avatar_user_default"]];

要求placeholderImage根据主题不同使用不同图片,不知道有什么合适的方法

can not use Plist Mode in Objective-C

plist模式无法在OC中使用。
.h文件中只生成了+ (void)setTheme:(NSInteger)index;方法

SWIFT_CLASS_NAMED("ThemeManager")
@interface ThemeManager : NSObject
+ (double)animationDuration;
+ (void)setAnimationDuration:(double)value;
+ (NSDictionary * _Nullable)currentTheme;
+ (void)setCurrentTheme:(NSDictionary * _Nullable)value;
+ (NSInteger)currentThemeIndex;
+ (void)setCurrentThemeIndex:(NSInteger)value;
+ (void)setTheme:(NSInteger)index;
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end

原因:
ThemePath使用了Swift中的enum,而OC只支持简单的枚举,ThemePath无法导出给OC使用。

Swift的enum很强大,但为了支持OC,建议更改ThemePath的实现(有意贡献代码)

ThemePicker初始化方法pickerWithKeyPath的问题

pickerWithKeyPath传入的路径有误,或者对应路径的值不存在,ThemePicker的对象仍旧会创建成功,并且没有其他属性来判断对象的值是否真实有效。这对于开发的容错处理造成了很大麻烦。本地的Plist文件因为自己控制可以完全避免,但是网络上的Plist皮肤文件就很有必要做这个处理了,App会随着更新改变Plist的结构来满足新的皮肤更改需求。这时候就涉及到新老Plist文件兼容,在这种情况下,这个容错处理逻辑变得极为重要,一不小心App就会随时崩溃。

Keyboard appearance

Hi!

Is there any plans to support .keyboardAppearance for textfields?

Thanks for great lib :)

SwiftTheme WARNING: Not found string key path

SwiftTheme WARNING: Not found string key path: Global.backgroundColor

I keep receiving this warning when I use setTheme in the viewDidLoad method. However, it is actually working fine and recognizes the Global.backgroundColor and sets it to the correct color depending on the current theme; there isn't any actual problem. I don't know how to stop this warning.

Swift compiler warning

Hey guys,

Thanks for creating this! Super useful!

Got a question:

  • is anyone is working on this?

Swift compiler warning

If not, I can see about submitting a PR? (Just didn't want to duplicate work in case someone already fixed it ^_^)

Thank you,
Alex

Setting tab bar image icon and background Image

Thanks for great library, I'm trying to add themes in my tab bar application, I've different images to set for icons, but I wasn't able to find anything to achieve this scenario

Adding a notification in sub class of UITabbar or tabbarcontroller is something in my mind , you think it's good way?

Change alpha for ighlighting rows with theme_backgroundColor

Hi,

Thanks for your awesome repo. 👌🏼

Before using SwiftTheme I set highlight row as follow:

`override func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath) {

        let cell = tableView.cellForRow(at: indexPath)
        
        cell?.contentView.backgroundColor = UIColor(red: 0, green: 169/255, blue: 168/255, alpha: 0.25)
}`

So as you can see I need alpha = 0.25, alpha just for the backgroundColor not for the contentView.

Is there a way to set alpha using theme_backgroundColor ??

cell?.contentView.theme_backgroundColor = ["#00a9a8", "#292b38"]

Thanks.

ThemePicker keypath 方式初始化的一些疑问

看了下代码,发现 ThemeFontPicker 和 ThemeDictionaryPicker 没有以keyPath为参数的初始化方法,ThemeFontPicker 没有比较好好理解,字符串确实不太好表达 Font,ThemeDictionaryPicker 没有就比较奇怪了(plist中是可以表达dictionary的呀),而且 ThemeManager+Plist 中也定义了 dictionaryForKeyPath(_),可能是我还没太理解,希望能够解释以下,谢谢~。

另外,上述两者如果没有 keypath初始化方法,那么使用的时候就会和其他picker不一致了,其他的picker只要指定 keypath,就可以自动完成根据theme切换属性值的功能,而如果是上述的两个picker的话,恐怕要外界自行根据theme去init?

Cocoapods not working

I installed the cocoapods and them tried to set the theme (plist mode) in App Delegate using following code :

ThemeManager.setTheme(plistName: "Red", path: .mainBundle)

I was not able to get autocomplete predictions, as well as, on building the project, I was getting error on this line

Please help!!!

theme_setStatusBarStyle doesn't work as expected

Hi, thanks for your awesome project, it helps me a lot. But I got a problem.
theme colour and images works well but the status bar doesn't change respond to ThemeManager.setTheme

I add code below in my didFinishLaunchingWithOptions

UIApplication.sharedApplication().theme_setStatusBarStyle(ThemeStatusBarStylePicker(styles: .Default, .LightContent), animated: true)

It doesn't work, anything else I need to do to change my status bar style?

编译出错了

你好,我编译PlistDemo时出现编译错误,在NSObject+Theme.swift页面中提示:Expcted','separator。

我对swift不熟悉,请多指教,谢谢

how can i set button state?

怎样给一个按钮 设置点击和正常不同状态的背景色? 我用的是配置plist 的方式
how can i switch button's background color with diffrent state?


v.theme_backgroundColor = "" 没有设置状态的参数 ,,谢谢

颜色扩展在iOS10后有些不同

在开发的时候发现同一个16进制的颜色在自己写的工具类和使用SwiftTheme时颜色不太一样
发现在UIColorExtension.swift中初始化颜色的时候只使用了

self.init(red: red, green: green, blue: blue, alpha: alpha)

因为在iOS10后苹果推荐使用sRGB,举其中一个函数为例子:

public convenience init(hex8: UInt32) {
        let divisor = CGFloat(255)
        let red     = CGFloat((hex8 & 0xFF000000) >> 24) / divisor
        let green   = CGFloat((hex8 & 0x00FF0000) >> 16) / divisor
        let blue    = CGFloat((hex8 & 0x0000FF00) >>  8) / divisor
        let alpha   = CGFloat( hex8 & 0x000000FF       ) / divisor
	if #available(iOS 10.0, *) {
		self.init(displayP3Red: red, green: green, blue: blue, alpha: alpha)
	} else {
		self.init(red: red, green: green, blue: blue, alpha: alpha)
	}
}

最后说一句,感谢开发者们,这款工具真的十分不错~

Navigation Bar themable title

I'm trying to set the navigation bar title a themable value, so I have in AppDelegate

        private func setupTheming() {
        let _ = UITextField.appearance().backgroundColor?.toHexString() ?? "000000"
        let attributes = [NSAttributedStringKey.foregroundColor.rawValue: UIColor.red.toHexString()] as [String: AnyObject]
        UINavigationBar.appearance().theme_barTintColor = [UIColor.blue.toHexString(), UIColor.nightDarkGray.toHexString()]
        UINavigationBar.appearance().theme_tintColor = [UIColor.cream.toHexString(), UIColor.nightOrange.toHexString()]
        UINavigationBar.appearance().theme_titleTextAttributes = ThemeDictionaryPicker.pickerWithDicts([attributes])

So it should be set to red, but nothing happens.
If I set the value to a a UILabel.appearance it works

UILabel.appearance().theme_textColor = [UIColor.blueGray.toHexString(), UIColor.orange.toHexString()]

Any idea on how to proceed?

Color of UITextField placeholder

Is there a way to style the color of an UITextField placeholder text?

Without SwiftTheme I use the attributedPlaceholder to change the color.

Named colors in plist

Thanks for this wonderful library! I am missing just one feature at the moment and that is to name colors in the plist file so we can reference them via their name within the plist file. This way we can change just the hex value of one named color to change many elements at once. It will be convenient and will lead to less errors.

Like the color #ECF0F1 in the PlistDemo used in several places https://github.com/jiecao-fm/SwiftTheme/blob/master/PlistDemo/Night.plist

EDIT:
Maybe even shared named colors palette between multiple themes/plists? I am adding a night mode to an app and they both use the same palette.

an advice

maybe could add a travis auto testing to the project? so developer could see the building pass conditions
😃

Cheers

和#11类似的问题

看了#11的问题,感觉差不多,就是一些地方的控件需要跟随夜间模式一起更改,我就扩写了UIView

extension UIView {
// 是否跟随主题自动切换背景色
    @IBInspectable var isThemed: Bool? {
        get {
            return false
        }
        
        set {
            guard let _ = newValue else { return }
            guard let _ = newValue else { return }
            //globalThemeCommonBackgroundColor是一个全局的颜色,大概就是夜间模式变黑色,其他则是白色
            theme_backgroundColor = newValue! ? globalThemeCommonBackgroundColor : nil
        }
    }
}

在StoryBoard中我勾选了一个view的Is Themed属性为On,但是在切换至夜间模式的时候并没有效果,不知道为啥,是代码的问题?

Error Ambiguous use of init(rgba_throws:)

I'm trying to implement Plist demo inside my project after I copied the plist files from the demo then I copied your AppDelegate to my project:

     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    
    // default: Red.plist
    
    ThemeManager.setTheme(plistName: "Red", path: .mainBundle)
    
    // status bar
    
    UIApplication.shared.theme_setStatusBarStyle("UIStatusBarStyle", animated: true)
    
    // navigation bar
    
    let navigationBar = UINavigationBar.appearance()
    
    navigationBar.theme_tintColor = "Global.barTextColor"
    navigationBar.theme_barTintColor = "Global.barTintColor"
    
    navigationBar.theme_titleTextAttributes = ThemeDictionaryPicker(keyPath: "Global.barTextColor", map: { value in
        guard
            let rgba = value as? String,
            let color = try? UIColor(rgba_throws: rgba) else {
                return nil
        }
        
        let shadow = NSShadow(); shadow.shadowOffset = CGSize.zero
        let titleTextAttributes = [
            NSForegroundColorAttributeName: color,
            NSFontAttributeName: UIFont.systemFont(ofSize: 16),
            NSShadowAttributeName: shadow
        ]
        
        return titleTextAttributes
    })
    
    // tab bar
    
    let tabBar = UITabBar.appearance()
    
    tabBar.theme_tintColor = "Global.barTextColor"
    tabBar.theme_barTintColor = "Global.barTintColor"
    
    
    UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
    UINavigationBar.appearance().shadowImage = UIImage()
  }

Any ideas to solve it ?

Add Changelog

Could you please add a changelog? It'd be nice to know the differences when new versions come out.

Theme doesn't change

I'm trying to add night mode to an app, but nothing happens. My current implementation:
I have a settings view controller which is managed by a settings presenter. That settings presenter has a segmented control for night mode On/Off.

            configurationManager.nightModeState = state
    }

Switching the state from the presenter calls a configuration manager to set and persist the night mode state

 var nightModeState: NightState {
        didSet {
            defaults.setValue(nightModeState.rawValue, forKey: ConfigurationKeys.NightModeState)
            setNightModeFor(nightModeState)
        }
    }

func setNightModeFor(_ state: NightState) {
        switch state {
        case .On:
            ThemeManager.setTheme(index: 1)
        case .Off:
            ThemeManager.setTheme(index: 0)
        }
    }

And my colors are set in appDelegate didFinishLaunching

private func setupTheming() {
        UINavigationBar.appearance().theme_backgroundColor = [UIColor.blue.description, UIColor.darkBlueNavBar.description]
        UIView.appearance().theme_backgroundColor = [UIColor.cream.description, UIColor.darkBlue.description]
    }

following with breakpoints, I can see that the notification is fired from

    public class func setTheme(index: Int) {
        currentThemeIndex = index
        NotificationCenter.default.post(name: Notification.Name(rawValue: ThemeUpdateNotification), object: nil)
    }

but nothing happens.

Anyone has any idea? Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.