Branding and Theming
The SAPFiori framework embeds a fork of the open source NUI
project, which enables styling of UI controls using a CSS-like stylesheet (the .nss
file).
The UI components in SAPFiori are styled during initialization according to the SAP Fiori Design Language Guidelines, but are also assigned one or more FioriStyle
instances. These instances are similar to a CSS class
attribute, such that at runtime, if a style definition override exists in the .nss
file for that FioriStyle
, it will be applied on top of the default attributes.
Each styleable component in SAPFiori is assigned style class references by default, so that developers can define style overrides for those class references, without invoking Swift API’s. These default style classes are assigned, according to the following standard:
"fdl" + <#ComponentClassName#> + "_" + <#PropertyName#>
For example, to assign an override styles for the FUIObjectTableViewCell
, using the following style classes:
fdlFUIObjectView_headlineLabel {
font-style: subheadline;
font-color: #1EE68A00;
}
fdlFUIObjectTableViewCell {
background-color-selected: negative_darkBackground;
}
Refer to the header documentation for controls, to check for exceptions to these patterns.
Usage
Activate Styling
To activate the theming engine, add your ".nss"
resource to the application project.
The
NUI
library is embedded inSAPFiori
, so no dependency management is required.
In your AppDelegate
, invoke the static initializer in didFinishLaunchingWithOptions:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
// setup logger (requires `import SAPCommon`)
let logger = Logger.root
logger.logLevel = .info
// initialize stylesheet by name
NUISettings.initWithStylesheet(name: "Palette")
return true
}
Color Palette Customization
Every time a UIColor
is set in the SAPFiori framework, the color is obtained from the extension method:
func preferredFioriColor(forStyle style: FUIColorStyle, background scheme: FUIBackgroundColorScheme = .lightBackground) -> UIColor
The FUIColorStyle
cases correspond to the colors of the Fiori for iOS Design Guidelines palette. It is important to note the distinctions between the “base” color (UIColor.preferredFioriColor(forStyle: .primary1)
), the “dark” variant which is displayed on a “light” background (also UIColor.preferredFioriColor(forStyle: .primary1)
, or UIColor.preferredFioriColor(forStyle: .primary1, background: .lightBackground)
), and the “light” variant which is displayed on a “dark” background (UIColor.preferredFioriColor(forStyle: .primary1, background: .darkBackground)
)
To remember easily, keep in mind that: lighter colors are brighter on dark backgrounds, and dark colors have better contrast on light backgrounds.
Because all colors are set through this API, it is possible to override the global constants used for the FUIColorStyle
case. The technique for this is to add these definitions to the head of your ".nss"
file, using the regular nss @global_constant
pattern. The strings used as the global_constant
should match the string values of the FUIColorStyle
enums, and optionally append _lightBackground
, _darkBackground
, _elevatedDarkBackground
, _elevatedLightBackground
, _contrastDarkBackground
, _contrastLightBackground
to specialize the background
parameter passed to the preferredFioriColor(forStyle: background:) -> UIColor
invocation.
For example:
@tintColor: blue; /* equivalent to @tintColor_lightBackground */
@tintColor_darkBackground: cyan;
@tintColorTapState_lightBackground: purple; /* equivalent to @tintColorTapState */
@tintColorTapState_darkBackground : magenta;
Like style definitions, palette global overrides only modify their corresponding attributes; all other color definitions for which an override is not provided retain their original values.
As per the Fiori guidelines, when the background is not explicitly specified it defaults to the light background. For example, the global constants, tintColor
and tintColor_lightBackground
are equivalent. Similarly, primary1
and primary1_lightBackground
are equivalent. When overriding global constants in the .nss
file, if two equivalent constants are overridden, then the order of precedence is as shown below, where UIColor.cyan
will be used for all invocations of UIColor.preferredFioriColor(forStyle: .tintColor)
or UIColor.preferredFioriColor(forStyle: .tintColor, background: .lightBackground)
:
@tintColor_lightBackground: cyan; /* This takes precedence over tintColor */
@tintColor: blue;
@tintColorDark: green;
tintColor
andtintColor_lightBackground
also have another equivalent constant :tintColorDark
. This has the last precedence. The dark background variant of it istintColorLight
, that is,tintColorLight
andtintColor_darkBackground
are equivalent. SimilarlytintColorTapStateDark
is equivalent totintColorTapState
andtintColorTapState_lightBackground
whereastintColorTapStateLight
andtintColorTapState_darkBackground
are equivalent.
Using Colors in Style Definitions
You need to choose one of two notations when you want to refer to colors in style definitions.
1) For custom colors use the @global_constant pattern, e.g. @myCustomColor.
@myCustomColor: blue;
fdlFUIObjectTableViewCell {
tint-color: @myCustomColor;
}
2) For predefined Fiori Colors use the specific name, e.g. tintColor.
fdlFUIObjectTableViewCell {
tint-color: tintColor; /* the standard `FUIColorStyle.tintColor` is used */
}
You may override the default Fiori colors using the `@global_constant` pattern.
```swift
@primaryLabel: blue;
@primaryLabel_darkBackground: green;
fdlFUIObjectTableViewCell_title {
font-color: primaryLabel;
}
```
> The supported suffixes for overriding a default Fiori color are: `_lightBackground`, `_darkBackground`, `_elevatedDarkBackground`, `_elevatedLightBackground`, `_contrastDarkBackground`, `_contrastLightBackground`.
SAPFiori Component Style Customization
The screenshot below illustrates the FUIWelcomeScreen
before (default) and after setting different styles in NUI
, by modifying the text color and logo:
The stylesheet file can include a set of generic Fiori Design Language style definitions for font-style and font-color. Then, for each control, an individual style class configuration can be included; this per-component
style setting can override the style declared in the global definition and add other styles.
The stylesheet should follow these conventions for naming the style strings starting with fdl
which represents Fiori Design Language
For global definitions:
fdl<lower-camel-case enum name>_<property name>
For example:fdlFontStyle_subheadline
For per-component definitions:
fdl<class name>_<property name>
For example:fdlFUIWelcomeScreen_demoLabel
fdlFontStyle_subheadline {
font-style: subheadline;
font-color: #33cc33;
}
fdlFUIWelcomeScreen_headlineLabel {
font-color: #FF0000;
}
fdlFUIWelcomeScreen_primaryActionButton {
/* alpha value should be in 0% to 100% range. If value is more than 100% (64 in hex value), the system resets the value to 100%. */
font-color: #1EE68A00; /* where `1E` is the hex value of 30% in alpha value, and `E68A00` is the hex value for RGB. */
font-color-highlighted: green;
}
fdlFUIWelcomeScreen_logoImageView {
image-name: ProfilePic.png;
}
See the
NUI
README
for additional information about setting style syntax in the stylesheet.
-
Declaration
Swift
extension UIColor
-
Declaration
Swift
extension UIFont
-
An enum that represents the different component style classes for Fiori Design Language
See moreDeclaration
Swift
public enum FDLStyle
-
Undocumented
See moreDeclaration
Swift
public enum FUIColorStyle : String, CaseIterable
extension FUIColorStyle: CustomDebugStringConvertible
-
An enum that represents the different font style classes for Fiori Design Language
See moreDeclaration
Swift
public enum FDLFontStyle
-
An struct that represents style classes
See moreDeclaration
Swift
public struct FioriStyle : Hashable
extension FioriStyle: RawRepresentable
-
The style class settings class that provides a list of static functions for applying-style-related functionalities
See moreDeclaration
Swift
public class NUISettings : NSObject
-
The master renderer class that provides a list of static functions for individual component rendering
See moreDeclaration
Swift
@objcMembers public class NUIRenderer : NSObject