ButtonGroup
ButtonGroup is a container view that displays a set of buttons with configurable layouts and overflow handling.
Platform availability: iOS 17.0+
When to use:
- Use ButtonGroup when you need to display multiple related actions together with consistent spacing and overflow handling.
- Consider using individual Button components when actions are not closely related or need independent positioning.
- Consider using FloatingActionButton when you have a single prominent action that should float above content.
Import
import BackbaseDesignSystem
Visual reference
All Round |
All rounds Two Buttons |
All rounds Three Buttons |
All rounds Error |
Prominent Grouped |
Prominent Relaxed |
API reference
ButtonGroup
A UIView that displays a set of buttons with a given configuration and layout.
Properties
|
Property |
Type |
Description |
|---|---|---|
|
presentActionSheet |
((UIAlertController?) -> Void)? |
The presentActionSheet closure presents the action sheet for overflow items. |
|
navigateAction |
((ButtonGroup.Configuration) -> Void)? |
The navigateAction closure is called when a button with navigationAction is tapped. |
Initializers
- init(parameters:configurations:)
|
Parameter |
Type |
Description |
|---|---|---|
|
parameters |
Parameters |
Layout parameters. Default is DesignSystem.shared.parameters.buttonGroup. |
|
configurations |
[Configuration] |
Array of button configurations. Default is []. |
Methods
- update(with:) Updates the configurations of buttons in the group.
|
Parameter |
Type |
Description |
|---|---|---|
|
configurations |
[ButtonGroup.Configuration] |
Updated configurations for each button. |
ButtonGroup.Parameters
|
Property |
Type |
Description |
|---|---|---|
|
layout |
Layout |
The layout specifies how buttons are arranged in the group. |
|
moreIcon |
UIImage |
The moreIcon specifies the image for the "More" button. |
|
strings |
Strings |
The strings specifies text for the alert controller and more button. |
ButtonGroup.Configuration
|
Property |
Type |
Description |
|---|---|---|
|
title |
String |
The title specifies the button text. |
|
icon |
UIImage? |
The icon specifies the button's icon image. |
|
accessibilityLabel |
String? |
The accessibilityLabel specifies the VoiceOver label. |
|
accessibilityIdentifier |
String? |
The accessibilityIdentifier specifies the testing identifier. |
|
action |
(() -> Void)? |
The action closure is called on .touchUpInside. |
|
navigationAction |
((UINavigationController) -> Void)? |
The navigationAction closure receives a UINavigationController for navigation. |
ButtonGroup.Layout
|
Case |
Description |
|---|---|
|
.allRound(configuration:) |
The .allRound layout displays all buttons with rounded corners and equal distribution. |
|
.prominent(configuration:) |
The .prominent layout displays the first button as prominent, others as secondary. |
ButtonGroup.Strings
|
Property |
Type |
Description |
|---|---|---|
|
alertTitle |
String? |
The alertTitle specifies the title for the overflow action sheet. |
|
alertMessage |
String? |
The alertMessage specifies the message for the overflow action sheet. |
|
alertCancelButtonTitle |
String |
The alertCancelButtonTitle specifies the cancel button title. |
|
moreButtonAccessibilityLabel |
String |
The moreButtonAccessibilityLabel specifies the VoiceOver label for the more button. |
Configuration
|
Property |
Type |
Default |
|---|---|---|
|
layout |
Layout |
.allRound() |
|
moreIcon |
UIImage |
DesignSystem.Assets.icMoreHoriz |
|
strings |
Strings |
ButtonGroup.Strings() |
Usage
Basic usage with allRound layout
let configuration = ButtonGroup.Configuration(title: "Statements")
let buttonGroup = ButtonGroup(configurations: [configuration])
Multiple buttons
let configurations: [ButtonGroup.Configuration] = [
.init(title: "Details"),
.init(title: "Statements")
]
let buttonGroup = ButtonGroup(configurations: configurations)
With More button (more than 3 configurations)
let configurations: [ButtonGroup.Configuration] = [
.init(title: "Pay"),
.init(title: "Cash Advance"),
.init(title: "Transfer"),
.init(title: "History")
]
let buttonGroup = ButtonGroup(configurations: configurations)
buttonGroup.presentActionSheet = { alert in
guard let alert else { return }
if let popoverPresentationController = alert.popoverPresentationController {
popoverPresentationController.sourceView = self.view
popoverPresentationController.sourceRect = CGRect(
x: self.view.bounds.midX,
y: self.view.bounds.midY,
width: 0,
height: 0
)
popoverPresentationController.permittedArrowDirections = []
}
self.present(alert, animated: true, completion: nil)
}
Custom spacing
let configurations: [ButtonGroup.Configuration] = [
.init(title: "Transfer"),
.init(title: "Pay"),
.init(title: "History")
]
let group = ButtonGroup(
parameters: .init(
layout: .allRound(
configuration: .init(
spacing: DesignSystem.shared.spacer.lg
)
)
),
configurations: configurations
)
Prominent relaxed layout
let configurations: [ButtonGroup.Configuration] = [
.init(title: "Transfer"),
.init(title: "Pay", icon: .named(DesignSystem.Assets.icInfo, in: .design)),
.init(title: "History", icon: .named(DesignSystem.Assets.icDock, in: .design))
]
let buttonGroup = ButtonGroup(
parameters: .init(
layout: .prominent(
configuration: .init(
type: .relaxed,
spacing: DesignSystem.shared.spacer.xxs,
cornerRadiusType: .large()
)
)
),
configurations: configurations
)
Prominent grouped layout
let configurations: [ButtonGroup.Configuration] = [
.init(title: "Transfer"),
.init(title: "Pay", icon: .named(DesignSystem.Assets.icInfo, in: .design)),
.init(title: "History", icon: .named(DesignSystem.Assets.icDock, in: .design))
]
let buttonGroup = ButtonGroup(
parameters: .init(
layout: .prominent(
configuration: .init(
type: .grouped,
spacing: DesignSystem.shared.spacer.xxs,
cornerRadiusType: .large()
)
)
),
configurations: configurations
)
With action closure
let configurations: [ButtonGroup.Configuration] = [
.init(
title: "Share",
icon: .named(DesignSystem.Assets.icShare, in: .design),
action: {
print("Share tapped")
}
)
]
let group = ButtonGroup(configurations: configurations)
With navigation action
let configurations: [ButtonGroup.Configuration] = [
.init(
title: "Make a Payment",
icon: .named(DesignSystem.Assets.icMenu, in: .main, .design),
navigationAction: { navigationController in
let paymentVC = PaymentViewController()
navigationController.pushViewController(paymentVC, animated: true)
}
)
]
let group = ButtonGroup(configurations: configurations)
group.navigateAction = { config in
config.navigationAction?(navigationController)
}
Updating configurations
let group = ButtonGroup(configurations: [.init(title: "Initial")])
let updatedConfiguration = ButtonGroup.Configuration(
title: "Updated",
icon: .named(DesignSystem.Assets.icShare, in: .design),
action: {
print("Updated action")
}
)
group.update(with: [updatedConfiguration])
States and variants
The ButtonGroup component supports two layout types:
|
Layout |
Variant |
Description |
|---|---|---|
|
.allRound |
Default |
All buttons with rounded corners and equal distribution |
|
.prominent |
.relaxed |
First button prominent, secondary buttons with spacing |
|
.prominent |
.grouped |
First button prominent, secondary buttons grouped together |
When more than three configurations are added, a "More" button automatically appears with an action sheet for overflow items.
Customization
Overriding default parameters
let layout: ButtonGroup.Layout = .prominent(
configuration: .init(
type: .relaxed,
spacing: DesignSystem.shared.spacer.xxs,
cornerRadiusType: .large()
)
)
DesignSystem.shared.parameters.buttonGroup = .init(layout: layout)
Events
|
Event |
Type |
Description |
|---|---|---|
|
presentActionSheet |
((UIAlertController?) -> Void)? |
Called when the "More" button is tapped. |
|
navigateAction |
((ButtonGroup.Configuration) -> Void)? |
Called when a button with navigationAction is tapped. |
Accessibility
The ButtonGroup component has built-in accessibility support with configurable labels and identifiers.
|
Configuration |
Description |
|---|---|
|
accessibilityLabel |
VoiceOver label for each button |
|
accessibilityIdentifier |
Testing identifier for each button |
|
moreButtonAccessibilityLabel |
VoiceOver label for the "More" button |
Best practices:
- Set meaningful accessibilityLabel values for each button configuration
- Configure moreButtonAccessibilityLabel in ButtonGroup.Strings to describe overflow actions
Dependencies
- External dependencies: None
- Internal dependencies: Button, DesignSystem.CornerRadiusTypes
Design tokens
Component styling is applied automatically through the design system's theming infrastructure.
JSON tokens
Tokens are defined in defaultTokens.json, which is integrated in the bundle of the framework, and can be customized by providing your own theme JSON file.
Token groups used by ButtonGroup:
- color/button/primary: Primary button background, foreground, and border colors
- color/button/secondary: Secondary button styling with brand border
- color/button/tertiary: Tertiary button styling
- color/button/success: Success-themed button colors
- color/button/danger: Danger-themed button colors
- color/button/link: Link-style button colors
ButtonGroup uses the same tokens as the Button component. See Button Design tokens for the complete token reference.
Semantic tokens
These tokens are accessed via the public DesignSystem.shared API.
|
Token |
API Reference |
Description |
|---|---|---|
|
Typography |
DesignSystem.shared.fonts.preferredFont(.body, .semibold) |
Button text font |
|
Spacing |
DesignSystem.shared.spacer.lg |
Large spacing between buttons |
|
Spacing |
DesignSystem.shared.spacer.xxs |
Extra small spacing for grouped layouts |
|
Corner Radius |
DesignSystem.shared.cornerRadius.large |
Large corner radius for buttons |
|
Styles |
DesignSystem.shared.styles.primaryButton |
Primary button style |
|
Styles |
DesignSystem.shared.styles.secondaryButton |
Secondary button style |
See also
- Button - Individual button component
- FloatingActionButton - Floating primary action button