Create radio button in SwiftUI
In this tutorial, we will learn how to make radio buttons in SwiftUI. If we need to choose a single option from multiple options, then we have to use radio buttons.
First of all, we must build a state variable to control the state of our views. In this case, the state variable will be utilized to maintain track of the selected choice in the radio button group. Simply put the following code within the ContentView struct to create a state variable.
@State var selectedOption: Int = 1
In the above code, I declared a state property called selectedOption
with a starting value of 1. The @State
attribute is then used to indicate a mutable property that the framework instantly updates when its value changes.
Now we will create a custom view for the radio button. A custom view is a user-defined view that we create to encapsulate specific functionality or design. It allows us to create reusable components for usage across our SwiftUI application.
We have to define a new struct or class to create a custom view that conforms to the View protocol. The View
protocol requires implementing a body
property that returns a view order, which describes the content and layout of the custom view.
struct RadioButtonView: View { var index: Int @Binding var selectedIndex: Int var body: some View { Button(action: { selectedIndex = index }) { HStack { Image(systemName: selectedIndex == index ? "largecircle.fill.circle" : "circle") .foregroundColor(.black) Text("Option \(index)") } } } }
In the above program, I have defined a struct called RadioButtonView that conforms to the View protocol in SwiftUI.
It has two properties which are mentioned below.
- index: An Int value that represents the index of the radio button.
- selectedIndex: A binding to an Int value that represents the currently selected index.
After that, Inside the body property, I have created a button view with an action closure. The button view will execute when the button is pressed.
The content of the button is defined by the HStack view. It has two properties which are mentioned below.
- The first one is the
image view
that is used to display whether a circle (“largecircle.fill.circle
“) is filled or not (“circle
“) based on matching the current index with theselectedIndex
. The color of the image is set to black using.foregroundColor(.black)
. - The second one is the
Text view
that is used to display the text “Option
” followed by the current index.
When the button is pressed, the action closure updates the selected index value by setting the selectedIndex
binding to the current index.
Now, In the ContentView
struct I will create a VStack
with three instances of the RadioButtonView
and a Text
view to display the selected option.
struct ContentView: View { @State var selectedOption: Int = 1 var body: some View { Text("Select an option").font(.headline) VStack (spacing: 20) { RadioButtonView(index: 1, selectedIndex: $selectedOption) RadioButtonView(index: 2, selectedIndex: $selectedOption) RadioButtonView(index: 3, selectedIndex: $selectedOption) Text("Selected option: \(selectedOption)") } .padding() } }
In the above program, I have created three instances of RadioButtonView
with different index values and the same selected index binding. I have also displayed the selected option below the radio buttons using a Text
view. The selected index is tracked using the selectedOption
property.
Now have a look at the complete code below.
import SwiftUI struct ContentView: View { @State var selectedOption: Int = 1 var body: some View { Text("Select an option").font(.headline) VStack (spacing: 20) { RadioButtonView(index: 1, selectedIndex: $selectedOption) RadioButtonView(index: 2, selectedIndex: $selectedOption) RadioButtonView(index: 3, selectedIndex: $selectedOption) Text("Selected option: \(selectedOption)") } .padding() } } struct RadioButtonView: View { var index: Int @Binding var selectedIndex: Int var body: some View { Button(action: { selectedIndex = index }) { HStack { Image(systemName: self.selectedIndex == self.index ? "largecircle.fill.circle" : "circle") .foregroundColor(.black) Text("Option \(index)") } } } }
Output:
Leave a Reply