FUIButton
open class FUIButton : UIButton, FUIButtonClosureHandling, FUIStateSelectable, FUIBackgroundSchemeSupporting, PrepareForReuse
Subclass of UIButton
, which provides for rounded edge and rounded fill styles. It also provides for per-state tint colors, persistent selection, and a closure-styled tap handler.
The FUIButton
implements the Fiori Design Language in default configuration.
Usage
Initialization
Init button with expected style (for default, use .none
).
To use
FUIButton
style variants in Interface Builder, the convenience subclassesFUIRoundedButton
(.fuiRounded
) andFUIRoundedFillButton
(.fuiRoundedFilled
) are also available.
// init with expected style.
let normalButton = FUIButton() // equivalent to FUIButton(style: .none)
let roundedOutlineButton = FUIButton(style: .fuiRounded) // equivalent to `FUIRoundedButton()`
let roundedFilledButton = FUIButton(style: .fuiRoundedFilled) // equivalent to `FUIRoundedFillButton()`
Setting title(s)
UIButton
provides two techniques for setting its title:
setTitle(_:, for:)
titleLabel.text
The behavior of the (2) is inconsistent, and discouraged by Apple. As a result, titleLabel.text
should be avoided in favor of technique setTitle(_:_:)
. The FUIButton
will correct the behavior of titleLabel.text
, if setTitle(_:_:)
is not used. However, if the developer at any point invokes setTitle(_:, for:)
directly, FUIButton
will cease to correct for titleLabel.text
, and will defer to the developer to use the API correctly.
button.setTitle("Follow", for: .normal)
button.setTitle("Unfollow", for: .selected)
Specify Selection Behavior
The default behavior of UIButton
is to toggle between .normal
and .highlighted
UIControlState
, on user touches started and touches ended. The .selected
state is never used.
FUIButton
supports toggling between .normal
and .selected
UIControlState
, by setting the isPersistentSelection
flag to true
. This is particularly useful, if using the button to toggle a property. The developer may use the isSelected: Bool
API to toggle cause this transition.
button.isPersistentSelection = true // causes button to toggle between `.normal` and `.selected` states on user touch
When isPersistentSelection == true
, the button may transition briefly through the .highlighted
state, between .selected
and .normal
on user touches. Configure settings for [.selected, .highlighted]
, if implementing custom behavior here.
Color Configuration
Call setTintColor(_:_:)
to configure tint color for states. Setting tintColor
is equivalent to call setTintColor(color, for: UIControlState.normal)
. Default tintColor
is UIColor.preferedFioriColor(for: .tintColor, background: self.backgroundColorScheme)
.
// set the `.normal` and `.disabled` tint colors
button.setTintColor(.preferredFioriColor(forStyle: .tintColor), for: .normal)
button.setTintColor.setTintColor(.preferredFioriColor(forStyle: .primary4), for: .disabled)
// set *either* the `.highlighted` or `.selected` tint colors
button.setTintColor(UIColor.preferredFioriColor(forStyle: .tintColorTapState), for: .highlighted)
// --or--
button.setTintColor.setTintColor(UIColor.preferredFioriColor(forStyle: .tintColorTapState), for: .highlighted)
These tint colors will be applied differently, depending upon the .style
of the button. In the .fuiRounded
style, the tint is applied to the layer
edge and titleLabel.textColor
; in the .fuiRoundedFill
style, the tint is applied to the background color.
In any style, you may choose to override the background color for state, which is useful for applying an inverted style.
button.setBackgroundColor(UIColor.preferredFioriColor(forStyle: .tintColorLight), for: .highlighted)
The FUIButton
also implements the FUIBackgroundSchemeSupporting
protocol, which enables developers to inform the control whether it is being presented against a ‘light’ background, or ‘dark’ background. The default style of the button will adapt to the background color scheme; defaults to .light
.
Size Calculation
The FUIButton
calculates an intrinsicContentSize
from its imageView
and titleLabel
, its various insets, and its layoutMargins
.
To manage the width of the text in the titleLabel
, use the regular UILabel
API to configure the wrapping behavior.
button.titleLabel?.preferredMaxLayoutWidth = 200
button.titleLabel?.lineBreakMode = .byWordWrapping
As an additional configuration option, the FUIButton
provides a flag isPreservingPreferredMaxLayoutWidth
, which uses the preferredMaxLayoutWidth
as a minimum width for the titleLabel
when calculating intrinsicContentSize
. This is useful, when implementing a fixed-width button with variable texts, or toggling variable-width texts on state.
Note: This will not affect the
titleLabel
text wrapping behavior.
button.isPreservingPreferredMaxLayoutWidth = true
Selection handler:
Optional closure-based substitute for addTarget(_:_:_:)
method for handling user taps. Passes self
as input parameter.
Is compatible with addTarget(_:_:_:)
selector registration.
If used in combination with the target-action selector registration, handlers will be invoked in the following order:
didSelectHandler
- target-action selector
Theming
Support Button
class paths:
Button {}
fdlFUIButton {}
Supported Button
attributes:
tint-color { -selected | -highlighted | -selected-highlighted | -selected-disabled | -disabled } (Color)
background-color { -normal | -selected | -highlighted | -selected-highlighted | -selected-disabled | -disabled } (Color)
background-image { -selected | -highlighted | -selected-highlighted | -selected-disabled | -disabled } (Image)
content-insets (Box)
image-insets (Box)
title-insets (Box)
shadow-color (Color)
shadow-offset (Offset)
shadow-opacity (Number)
shadow-radius (Number)
Supported Text
attributes:
font-color { -selected | -highlighted | -selected-highlighted | -selected-disabled | -disabled } (Color)
font-name (FontName)
font-style (UIFontTextStyle)
font-size (Number)
text-align (TextAlign)
text-alpha (Number)
text-auto-fit (Boolean)
text-line-clamp (Integer)
text-shadow-color { -selected | -highlighted | -selected-highlighted | -selected-disabled | -disabled } (Color)
text-shadow-offset (Offset)
Supported ImageView
attributes:
image { -highlighted | -selected | -selected-highlightecd | -selected-disabled | -disabled } (Image)
Remark
Thetint-color { -* }
attribute will override the font-color { -* }
attribute on a state-by-state basis. E.g. tint-color-highlighted
will override font-color-highlighted
, but will not affect font-color
.
-
Specialized init method, implementing the common ‘rounded’ button style.
Applies default
contentEdgeInsets = UIEdgeInsets(top: 7, left: 16, bottom: 7, right: 16)
Declaration
Swift
public convenience init(style: FUIButtonStyle)
Parameters
style
{
.none
,.fuiRounded
,.fuiRoundedFilled
} -
Initializer with
type == .custom
andstyle == .none
Declaration
Swift
public convenience init()
-
Sets button style
Declaration
Swift
public var style: FUIButtonStyle { get set }
-
Declaration
Swift
public var backgroundColorScheme: FUIBackgroundColorScheme { get set }
-
Sets tint color for
UIControlState
provided.When
style == { .none | .fuiRounded
} , invokessetTitleColor(_:_:)
forstate
, and ifstyle
is not.none
, applies tint color toimageView
.When
style == .fuiRoundedFilled
, invokes thesetBackgroundColor(_:_:)
forstate
.Declaration
Swift
open func setTintColor(_ color: UIColor, for state: UIControlState)
Parameters
color
tint color
state
control state (as determined by
UIButton
superclass) -
Sets background color for
UIControlState
for most button configurations.Declaration
Swift
public func setBackgroundColor(_ color: UIColor, for state: UIControlState)
Parameters
color
background color
state
control state (as determined by
UIButton
superclass) -
Undocumented
Declaration
Swift
public func setIsApplyingBorderColor(_ value: Bool, for state: UIControlState)
-
Undocumented
Declaration
Swift
open override func setTitle(_ title: String?, for state: UIControlState)
-
Optional closure handler, for responding to
UIControlEvent.primaryActionTriggered
.Declaration
Swift
open var didSelectHandler: ((FUIButton) -> Void)?
-
Enables
UIControlState.selected
to be persisted after user tap. Requires that user re-tap button to de-select, or that developer invokeisSelected = false
setter. Defaults tofalse
.Note
If set totrue
, button will skipUIControlState.highlighted
on tap, and returnUIControlState.selected
, whileisSelected == true
.Declaration
Swift
public var isPersistentSelection: Bool { get set }
-
Instructs the
intrinsicContentSize
calculation to use the button’stitleLabel?.preferredMaxLayoutWidth
as the constant width of thetitleLabel
subview.Declaration
Swift
public var isPreservingPreferredMaxLayoutWidth: Bool
-
Undocumented
Declaration
Swift
open override func prepareForInterfaceBuilder()