Button Group

A stack of buttons with multiple layout options

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 Round

All rounds Two Buttons

All rounds Two Buttons

All rounds Three Buttons

All rounds Three Buttons

All rounds Error

All rounds Error

Prominent Grouped

Prominent Grouped

Prominent Relaxed

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