SwiftTheme alternatives and similar libraries
Based on the "UI" category.
Alternatively, view SwiftTheme alternatives based on common mentions on social networks and blogs.
-
DZNEmptyDataSet
DISCONTINUED. A drop-in UITableView/UICollectionView superclass category for showing empty datasets whenever the view has no content to display -
IQKeyboardManager
Codeless drop-in universal library allows to prevent issues of keyboard sliding up and cover UITextField/UITextView. Neither need to write any code nor any setup required and much more. -
TTTAttributedLabel
A drop-in replacement for UILabel that supports attributes, data detectors, links, and more -
SkeletonView
☠️ An elegant way to show users that something is happening and also prepare them to which contents they are awaiting -
animated-tab-bar
:octocat: RAMAnimatedTabBarController is a Swift UI module library for adding animation to iOS tabbar items and icons. iOS library made by @Ramotion -
MGSwipeTableCell
An easy to use UITableViewCell subclass that allows to display swippable buttons with a variety of transitions. -
JTAppleCalendar
The Unofficial Apple iOS Swift Calendar View. Swift calendar Library. iOS calendar Control. 100% Customizable -
SWTableViewCell
An easy-to-use UITableViewCell subclass that implements a swippable content view which exposes utility buttons (similar to iOS 7 Mail Application) -
JVFloatLabeledTextField
UITextField subclass with floating labels - inspired by Matt D. Smith's design: http://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users -
XLForm
XLForm is the most flexible and powerful iOS library to create dynamic table-view forms. Fully compatible with Swift & Obj-C. -
FSPagerView
FSPagerView is an elegant Screen Slide Library. It is extremely helpful for making Banner View、Product Show、Welcome/Guide Pages、Screen/ViewController Sliders. -
SideMenu
Simple side/slide menu control for iOS, no code necessary! Lots of customization. Add it to your project in 5 minutes or less. -
SwipeCellKit
Swipeable UITableViewCell/UICollectionViewCell based on the stock Mail.app, implemented in Swift. -
Alerts & Pickers
Advanced usage of UIAlertController and pickers based on it: Telegram, Contacts, Location, PhotoLibrary, Country, Phone Code, Currency, Date... -
SwiftEntryKit
SwiftEntryKit is a presentation library for iOS. It can be used to easily display overlays within your iOS apps. -
TPKeyboardAvoiding
A drop-in universal solution for moving text fields out of the way of the keyboard in iOS -
PageMenu
A paging menu controller built from other view controllers placed inside a scroll view (like Spotify, Windows Phone, Instagram) -
Material Components
[In maintenance mode] Modular and customizable Material Design UI components for iOS -
SWRevealViewController
A UIViewController subclass for presenting side view controllers inspired on the FaceBook and Wunderlist apps, done right ! -
expanding-collection
:octocat: ExpandingCollection is an animated material design UI card peek/pop controller. iOS library made by @Ramotion -
CSStickyHeaderFlowLayout
UICollectionView replacement of UITableView. Do even more like Parallax Header, Sticky Section Header. Made for iOS 7.
SaaSHub - Software Alternatives and Reviews
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of SwiftTheme or a related project?
README
Introduction - Demos - Installation - Documents - FAQ - Contribution - 中文文档
Screenshot
Running:open
SwiftTheme.xcworkspace
, run targetPlistDemo
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
- [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
CocoaPods
pod 'SwiftTheme'
use_frameworks!
Carthage
github "wxxsw/SwiftTheme"
Swift Package Manager
- Select
Xcode -> File -> Swift Packages -> Add Package Dependency...
- Enter
https://github.com/wxxsw/SwiftTheme
. - 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 likePlistDemo
, but usejson
.OCDemo
isDemo
's Objective-C version.TVOSDemo
is used to test tvos compatibility.
FAQ
Why doesn't theme_setStatusBarStyle work as expected?
In your app's
Info.plist
you will need to setView Controller-based status bar appearence
toNO
.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
Lisence
The MIT License (MIT)
*Note that all licence references and agreements mentioned in the SwiftTheme README section above
are relevant to that project's source code only.