Overlay is a very flexible UI framework designed for Swift.
Note: Overlay is still under development and many things are subject to change.
- Protocol oriented design
- Interface Builder support
- Comprehensive unit test coverage
- Complete documentation
iOS 9+ / Xcode 9+ / Swift 4+
Carthage is a decentralized dependency manager. To install Overlay, add the following line to your Cartfile
:
github "TintPoint/Overlay" ~> 0.7
CocoaPods is a centralized dependency manager. To install Overlay, add the following line to your Podfile
:
pod 'Overlay', '~> 0.7'
Overlay allows one to write declarative yet type-safe UI code, something looks like this:
@IBDesignable
class StandardTextField: UITextField, CustomTextColor, CustomPlaceholderTextColor, CustomFont, CustomTextAlignment {
let textColorStyle: ColorStyle = Color.primary
let placeholderTextColorStyle: ColorStyle = Color.secondary
let fontStyle: FontStyle = Font.default
let textAlignmentStyle: TextAlignmentStyle = TextAlignment.body
}
Define a custom class that conforms to protocols with Custom
prefix (list of available protocols can be found here). For example, to customize the background color attribute of a view, write the following code.
class CustomView: UIView, CustomBackgroundColor {
let backgroundColorStyle: ColorStyle = UIColor.white
}
The compiler will emit an error if CustomView
's superclass (in this case, UIView
) is not BackgroundColorCustomizable
, or backgroundColorStyle
is not implemented by CustomView
. UIColor
is already conformed to ColorStyle
protocol so it can be used here. Font and other attributes can also be customized similarly.
CustomView
can be used like other views, but it is recommended to use it with Interface Builder.
Open the storyboard file (or nib file), select the view you want to change, navigate to Identity Inceptor, and set
Custom Class
toCustomView
.
Creating views programmatically is also supported.
let customView = CustomView()
customView.refresh() // make sure to call refresh() after initialization
In order to fully take advantage of the power of Swift's type checker, it is recommended to define custom enums (or structs with private initializers) that conform to protocols with Style
postfix (list of available styles can be found here).
enum CustomColor: ColorStyle {
case normal, disabled
func normal() -> UIColor {
switch self {
case .normal: return UIColor.white
case .disabled: return UIColor.black
}
}
}
Previous example can be rewritten as the following code.
class CustomView: UIView, CustomBackgroundColor {
let backgroundColorStyle: ColorStyle = CustomColor.normal
}
For views which have more than one states (e.g. UIButton
), their appearance usually needs to change base on state changes. All custom styles have corresponding style groups that support this feature (list of available style groups can be found here).
class CustomButton: UIButton, CustomBackgroundColor {
let backgroundColorStyle: ColorStyle = ColorGroup(normal: CustomColor.normal, disabled: CustomColor.disabled)
}
It is also possible to implement app-specific style groups by conforming to protocols with StyleGroup
postfix.
enum CustomColorGroup: ColorStyleGroup {
case standard
func normal() -> UIColor {
return UIColor.white
}
func disabled() -> UIColor? {
return UIColor.black
}
}
class CustomButton: UIButton, CustomBackgroundColor {
let backgroundColorStyle: ColorStyle = CustomColorGroup.standard
}
States defined in a style group but aren't supported by the view using it will be ignored. Currently, it is required to call refresh()
after changing the state.
button.isEnabled = true
button.refresh()
Overlay supports customizing views' colors, fonts, images, texts and text alignments.
However, it is still possible to customize other attributes by adopting protocols with Design
postfix.
class BorderView: UIView, CustomViewDesign {
let design: (UIView) -> Void = { view in
view.layer.borderWidth = 1
}
}
Most views contain subviews. Overlay is designed with this in mind, but it's not its goal to handle subview layouts. Overlay should only handle views' style attributes (like colors and fonts), and the main application should handle views' layouts (like origin and size). CustomLayout
protocol allows Overlay to work with Interface Builder together seamlessly.
Define a custom class that conforms to CustomLayout
protocol. Then create a nib file and set its File's Owner
to the newly defined class.
class ComplexView: UIView, CustomLayout {
let contentNib: UINib = UINib(nibName: "ComplexView", bundle: Bundle(for: ComplexView.self))
}
The first root view inside ComplexView.xib
will be loaded and added as a content view of ComplexView
. Note: Added view's background color usually should be clear color.
Create IBOutlet
and connect them like usual, if needed.
class ComplexView: UIView, CustomLayout {
let contentNib: UINib = UINib(nibName: "ComplexView", bundle: Bundle(for: ComplexView.self))
@IBOutlet weak var button: CustomButton?
}
- CustomCell
- CustomHeaderFooterView
- CustomReusableView
- CustomActivityIndicatorViewDesign
- CustomBarButtonItemDesign
- CustomBarItemDesign
- CustomButtonDesign
- CustomCollectionViewDesign
- CustomControlDesign
- CustomDatePickerDesign
- CustomDesign
- CustomImageViewDesign
- CustomLabelDesign
- CustomNavigationBarDesign
- CustomPageControlDesign
- CustomPickerViewDesign
- CustomProgressViewDesign
- CustomScrollViewDesign
- CustomSearchBarDesign
- CustomSegmentedControlDesign
- CustomSliderDesign
- CustomStackViewDesign
- CustomStepperDesign
- CustomSwitchDesign
- CustomTabBarDesign
- CustomTabBarItemDesign
- CustomTableViewDesign
- CustomTextFieldDesign
- CustomTextViewDesign
- CustomToolbarDesign
- CustomViewDesign
- CustomWebViewDesign
- CustomLayout
- CustomBackgroundColor
- CustomBadgeColor
- CustomBarTintColor
- CustomBorderColor
- CustomColor
- CustomMaximumTrackTintColor
- CustomMinimumTrackTintColor
- CustomOnTintColor
- CustomPlaceholderTextColor
- CustomProgressTintColor
- CustomSectionIndexBackgroundColor
- CustomSectionIndexColor
- CustomSectionIndexTrackingBackgroundColor
- CustomSeparatorColor
- CustomShadowColor
- CustomTextColor
- CustomThumbTintColor
- CustomTintColor
- CustomTitleColor
- CustomTitleShadowColor
- CustomTrackTintColor
- CustomUnselectedItemTintColor
- CustomFont
- CustomTitleFont
- CustomBackgroundImage
- CustomDecrementImage
- CustomHighlightedImage
- CustomImage
- CustomIncrementImage
- CustomLandscapeImagePhone
- CustomMaximumTrackImage
- CustomMaximumValueImage
- CustomMinimumTrackImage
- CustomMinimumValueImage
- CustomOffImage
- CustomOnImage
- CustomProgressImage
- CustomScopeBarButtonBackgroundImage
- CustomSearchFieldBackgroundImage
- CustomSelectedImage
- CustomShadowImage
- CustomThumbImage
- CustomTrackImage
- CustomPlaceholder
- CustomPrompt
- CustomScopeButtonTitles
- CustomSegmentTitles
- CustomText
- CustomTitle
- CustomTextAlignment
- CustomTitleTextAlignment
- ColorStyle
- ColorStyleGroup
- FontStyle
- FontStyleGroup
- ImageStyle
- ImageStyleGroup
- TextAlignmentStyle
- TextAlignmentStyleGroup
- TextStyle
- TextStyleGroup
- ColorGroup
- FontGroup
- ImageGroup
- TextAlignmentGroup
- TextGroup
- UIView and its subclasses
- UIView and its subclasses
- UIBarButtonItem
- UIBarItem
- UIButton
- UIControl
- UIDatePicker
- UILabel
- UIPageControl
- UIRefreshControl
- UISegmentedControl
- UISlider
- UIStepper
- UISwitch
- UITabBarItem
- UITextField
- UIButton
- UIControl
- UIDatePicker
- UIPageControl
- UIRefreshControl
- UISegmentedControl
- UISlider
- UIStepper
- UISwitch
- UITableViewCell
- UITextField
- UIButton
- UIControl
- UIDatePicker
- UIImageView
- UILabel
- UIPageControl
- UIRefreshControl
- UISegmentedControl
- UISlider
- UIStepper
- UISwitch
- UITableViewCell
- UITextField