Button in a subview not working with SwiftUI - ios

I want to create a list of ready-made cards. I wrote the card in another file, the code below.
struct PopulationPlace: View {
let image: String
let score: String
let title: String
#State private var isFavorite: Bool = false
var body: some View {
Image(image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 200, height: 210)
.clipShape(RoundedRectangle(cornerRadius: 25.0))
.overlay(alignment: .topTrailing, content: {
Button {
withAnimation{
isFavorite = false
}
} label: {
Image(systemName: "heart.circle.fill")
.symbolRenderingMode(.palette)
.foregroundStyle(.red, .yellow)
.foregroundColor(.red)
.padding(.vertical, 8)
.padding(.leading, 8)
}
.padding()
})
}
}
When I launch it in the preview, the buttons respond to clicks, but when I create a list of cards, the buttons cease to be active. What am I doing wrong?
It doesn't work for me
ScrollView(.horizontal, showsIndicators: false){
HStack{
ForEach(sampleList, id: \SamplePopulation.self){
item in
PopulationPlace(image: item.image, score: item.score, title:item.title)
}
}
}
Sample data
struct SamplePopulation: Identifiable, Hashable{
let id: String = UUID().uuidString
let image: String
let score: String
let title: String
}

Related

Swift List row background color not changing

I am working on minimizable side menu with collapsable sub menus in swift. Currently both the minimizing and collapsable submenu components are working. I have spent all evening trying to set the background color of the menu items. As it stands listRowBackground does nothing. I have come across other stack overflow (and other websites) posts talking about this. Some say to use for each loops. Below I have another SideMenu struct using a for each loop. This loop moves the side menu to the center of the screen. Can someone help me with either of these approaches to keep the menu on the left hand side of the screen and change the row background color?
Any help is appreciated!
Edit: I have also updated Xcode to version 14, but it did not help.
import SwiftUI
struct SideMenu: View {
let width: CGFloat
#Binding var menuOpened: Bool
var items: [Menu] = [.item0, .a, .b, .c]
var body: some View {
ZStack {
VStack(alignment: .leading){
HStack{
List(items, children: \.items){ row in
HStack{
if row.imageName != ""{
let image = Image(systemName: row.imageName)
image.resizable()
.aspectRatio(contentMode: .fit)
.foregroundColor(.black)
.frame(width: 32, height: 32, alignment: .center)
}else{
Text(row.name).listRowBackground(Color.orange)
}
}.listRowBackground(Color.orange)
.onTapGesture {
if row.imageName == "line.horizontal.3"{
menuOpened.toggle()
}
}
}
.background(Color.red)
.listStyle(.plain)
.frame(width: menuOpened ? 275 : 80)
Spacer()
}
}
}
}
}
struct Menu: Identifiable{
let id = UUID()
var name = ""
var imageName = ""
var items: [Menu]?
}
struct ContentView: View {
#State var menuOpened = true
var body: some View {
SideMenu(width: UIScreen.main.bounds.width/1.6, menuOpened: $menuOpened)
}
}
extension Menu{
static var item1 = Menu(name: "a1")
static var item2 = Menu(name: "a2")
static var item3 = Menu(name: "a3")
static var item0 = Menu(imageName: "line.horizontal.3")
static var a = Menu(name: "a", items: [.item1, .item2, item3])
static var b = Menu(name: "b")
static var c = Menu(name: "Settings")
}
Here is a struct with a for each loop
struct SideMenu: View {
let width: CGFloat
#Binding var menuOpened: Bool
var items: [Menu] = [.item0, .a, .b, .c]
var body: some View {
ZStack {
VStack(alignment: .leading){
HStack{
List {
ForEach(items) { row in
HStack{
if row.imageName != ""{
let image = Image(systemName: row.imageName)
image.resizable()
.aspectRatio(contentMode: .fit)
.foregroundColor(.black)
.frame(width: 32, height: 32, alignment: .center)
}else{
Text(row.name).listRowBackground(Color.orange)
}
}.listRowBackground(Color.orange)
.onTapGesture {
if row.imageName == "line.horizontal.3"{
menuOpened.toggle()
}
}
}
.background(Color.red)
.listStyle(.plain)
.frame(width: menuOpened ? 275 : 80)
Spacer()
}
}
}
}
}
}

New To Swift: Im not sure why the names of the users are not displaying? Swift UI

So I created this project to learn Swift Ui but I am stuck. I can't figure out why the HomeView isn't displaying the name of the contact. I created the ContactModel to store the contact details and the ContactViewModel to store all of the contacts in userDefaults.I stored the information in UserDefaults, but for some reason it just isn't working. I added all my files from the Xcode project. Thanks for the help!
#main
struct ContactsAppApp: App {
#StateObject var contactViewModel: ContactViewModel = ContactViewModel()
var body: some Scene {
WindowGroup {
NavigationView{
ContentView()
}
.environmentObject(contactViewModel)
}
}
}
struct ContentView: View {
var body: some View {
TabView{
HomeView()
.tabItem {
Image(systemName: "house")
.foregroundColor(.white)
Text("home")
}
AddContactView()
.tabItem{
Image(systemName: "laptopcomputer")
Text("work")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct ContactModel: Identifiable, Codable {
let id: String
let name: String
let phoneNumber: String
let email: String
init(id: String = UUID().uuidString, name: String, phoneNumber: String, email: String) {
self.id = id
self.name = name
self.phoneNumber = phoneNumber
self.email = email
}
func updateCompletion() -> ContactModel {
return ContactModel(id: id, name: name, phoneNumber: phoneNumber, email: email)
}
}
class ContactViewModel: ObservableObject {
#Published var items: [ContactModel] = [] {
didSet {
saveItems()
}
}
let itemsKey: String = "items_list"
init() {
getItems()
}
func getItems() {
guard
let data = UserDefaults.standard.data(forKey: itemsKey),
let savedItems = try? JSONDecoder().decode([ContactModel].self, from: data)
else { return }
self.items = savedItems
}
func deleteItem(indexSet: IndexSet) {
items.remove(atOffsets: indexSet)
}
func moveItem(from: IndexSet, to: Int) {
items.move(fromOffsets: from, toOffset: to)
}
func addItem(name: String, phoneNumber: String, email: String) {
let newItem = ContactModel(name: name, phoneNumber: phoneNumber, email: email)
items.append(newItem)
}
func updateItem(item: ContactModel) {
if let index = items.firstIndex(where: { $0.id == item.id }) {
items[index] = item.updateCompletion()
}
}
func saveItems() {
if let encodedData = try? JSONEncoder().encode(items) {
UserDefaults.standard.set(encodedData, forKey: itemsKey)
}
}
}
import SwiftUI
struct HomeView: View {
#EnvironmentObject var contactViewModel: ContactViewModel
var body: some View {
NavigationView {
VStack {
HStack{
Text("Contacts")
.font(.system(size: 35, weight: .bold))
.padding(.leading,30)
.padding(.top,20)
.foregroundColor(.white)
Spacer()
}
Spacer()
ScrollView{
ForEach(contactViewModel.items) { item in
contactWidget(name: item.name)
}
}
.padding(.top,20)
Button(action: {
print("touched")
}, label: {
NavigationLink(destination: AddContactView().navigationBarBackButtonHidden(true)) {
HStack{
ZStack{
RoundedRectangle(cornerRadius: 40)
.frame(width: 200, height: 50)
.foregroundColor(.blue)
Text("Add Contact")
.foregroundColor(.white)
}
}
}
.navigationBarHidden(true)
})
}
.background(.black)
}
.navigationBarHidden(true)
}
}
struct contactWidget : View{
let name: String
var body: some View{
ZStack {
RoundedRectangle(cornerRadius: 20)
.frame(width: 350, height: 100)
.foregroundColor(.gray)
HStack {
Image(systemName: "person")
.resizable()
.clipShape(Circle())
.frame(width: 40, height: 40)
Text(name)
.font(.system(size: 18, weight: .semibold))
Spacer()
HStack{
Circle()
.frame(width: 40, height: 40)
.foregroundColor(.orange)
Circle()
.frame(width: 40, height: 40)
.foregroundColor(.blue)
Circle()
.frame(width: 40, height: 40)
.foregroundColor(.pink)
}
}
.padding(.leading,40)
.padding(.trailing,30)
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
NavigationView{
HomeView()
}
.environmentObject(ContactViewModel())
}
}
import SwiftUI
struct AddContactView: View {
#EnvironmentObject var contactViewModel: ContactViewModel
#State var contactName: String = ""
#State var phoneNumber: String = ""
#State var email: String = ""
var body: some View {
NavigationView {
VStack {
HStack{
Text("Contacts")
.font(.system(size: 35, weight: .bold))
.padding(.leading,30)
.padding(.top,20)
.foregroundColor(.white)
Spacer()
}
TextField("Enter name", text: $contactName)
.frame(width: 330, height: 30)
.padding()
.background(.white)
.cornerRadius(10)
TextField("Enter Phone Number", text: $phoneNumber)
.frame(width: 330, height: 30)
.padding()
.background(.white)
.cornerRadius(10)
TextField("Enter Email", text: $email)
.frame(width: 330, height: 30)
.padding()
.background(.white)
.cornerRadius(10)
Text(contactName)
.foregroundColor(.white)
Spacer()
.padding(.top,20)
Button(action: {
contactViewModel.addItem(name: contactName, phoneNumber: phoneNumber, email: email)
contactName = ""
phoneNumber = ""
email = ""
}, label: {
NavigationLink(destination: HomeView().navigationBarBackButtonHidden(true)) {
HStack{
ZStack{
RoundedRectangle(cornerRadius: 40)
.frame(width: 200, height: 50)
.foregroundColor(.blue)
Text("Done")
.foregroundColor(.white)
}
}
}
.navigationBarHidden(true)
})
}
.background(.black)
}
.navigationBarHidden(true)
}
}
struct AddContactView_Previews: PreviewProvider {
static var previews: some View {
NavigationView{
AddContactView()
}
.environmentObject(ContactViewModel())
}
}
The reason "...why the HomeView isn't displaying the name of the contact..." is
because you have NavigationLink(destination: HomeView().... inside the button label in AddContactView. That is, the tap is caught by the NavigationLink
and goes to the HomeView without doing the button action
of adding the contact, contactViewModel.addItem( ...). So restructure your code with the
NavigationLink outside of it.
The example code below should fix your problem.
struct AddContactView: View {
#EnvironmentObject var contactViewModel: ContactViewModel
#State var contactName: String = ""
#State var phoneNumber: String = ""
#State var email: String = ""
#State var goHome = false // <-- here
var body: some View {
NavigationView {
VStack {
HStack{
Text("Contacts")
.font(.system(size: 35, weight: .bold))
.padding(.leading,30)
.padding(.top,20)
.foregroundColor(.white)
Spacer()
}
TextField("Enter name", text: $contactName)
.frame(width: 330, height: 30)
.padding()
.background(.white)
.cornerRadius(10)
TextField("Enter Phone Number", text: $phoneNumber)
.frame(width: 330, height: 30)
.padding()
.background(.white)
.cornerRadius(10)
TextField("Enter Email", text: $email)
.frame(width: 330, height: 30)
.padding()
.background(.white)
.cornerRadius(10)
Text(contactName).foregroundColor(.white)
Spacer().padding(.top,20)
Button(action: {
contactViewModel.addItem(name: contactName, phoneNumber: phoneNumber, email: email)
contactName = ""
phoneNumber = ""
email = ""
goHome = true // <-- here
}, label: {
HStack{
ZStack{
RoundedRectangle(cornerRadius: 40)
.frame(width: 200, height: 50)
.foregroundColor(.blue)
Text("Done")
.foregroundColor(.white)
}
}
})
// -- here
NavigationLink(destination: HomeView().navigationBarBackButtonHidden(true), isActive: $goHome) {
EmptyView()
}.navigationBarHidden(true)
}
.background(.black)
}
.navigationBarHidden(true)
}
}
Similarly for the button in HomeView, or remove the Button part, just keep the NavigationLink

SwiftUI - TabBar Button Change

Hi I'm learning SwiftUI and I encountered a problem while trying to build an app. My question is how can I make a tab bar that changes a systemImage while active (when the home button is active it shows "home.fill", and when the user presses the search button, the home button changes to "home").
If you see any improvement that I could make in the code below it's appreciated as well. Thank you, have a nice day, and stay safe.
import SwiftUI
struct ContentView: View {
#State private var fullScreenCover = false
init() {
UITabBar.appearance().isTranslucent = false
}
var body: some View {
VStack {
ForEach(0..<6) { num in
Spacer()
}
HStack {
Spacer()
Button(action: {}, label: {
Image(systemName: "message")
.font(.system(size: 20))
})
.padding(.horizontal, 15)
}
.foregroundColor(Color("Reverse"))
.padding(.vertical, 8)
TabView {
Main_Home()
.tabItem {
Image(systemName: "house")
.font(.system(size: 30))
}
Main_Search()
.tabItem {
Image(systemName: "magnifyingglass")
.font(.system(size: 30))
}
Main_AddContent()
.tabItem {
Image(systemName: "plus.viewfinder")
.font(.system(size: 30))
}
Main_Message()
.tabItem {
Image(systemName: "pencil.circle.fill")
.font(.system(size: 30))
}
Main_Profile()
.tabItem {
Image(systemName: "person.crop.circle")
.font(.system(size: 30))
}
}
.accentColor(Color("Reverse"))
}
.background(Color("Normal"))
.edgesIgnoringSafeArea(.all)
}
}
Here is a custom ViewModifier that you can use for adding tab items:
public struct TabViewItem<SelectionValue>: ViewModifier where SelectionValue: Hashable {
#Binding private var selectedIndex: SelectionValue
private let index: SelectionValue
private let text: String
private let imageName: String
public init(selectedIndex: Binding<SelectionValue>, index: SelectionValue, text: String, imageName: String) {
self._selectedIndex = selectedIndex
self.index = index
self.text = text
self.imageName = imageName
}
public func body(content: Content) -> some View {
content
.tabItem {
image
Text(text)
}
.tag(index)
}
private var image: some View {
guard selectedIndex == index else {
return Image(systemName: imageName)
}
let imageName = self.imageName + ".fill"
if let uiImage = UIImage(systemName: imageName) {
return Image(uiImage: uiImage)
}
return Image(systemName: self.imageName)
}
}
public extension View {
func tabItem<Selection>(
_ text: String,
imageName: String,
index: Selection,
selection: Binding<Selection>
) -> some View where Selection: Hashable {
modifier(TabViewItem(selectedIndex: selection, index: index, text: text, imageName: imageName))
}
}
Then, creating the TabView is more straightforward:
struct ContentView: View {
#State private var selectedTab = 3
var body: some View {
TabView(selection: $selectedTab) {
Text("Main_Home")
.tabItem("Home", imageName: "house", index: 1, selection: $selectedTab)
Text("Main_Search")
.tabItem("Search", imageName: "magnifyingglass", index: 2, selection: $selectedTab)
Text("Main_AddContent")
.tabItem("AddContent", imageName: "plus.viewfinder", index: 3, selection: $selectedTab)
Text("Main_Message")
.tabItem("Message", imageName: "pencil.circle", index: 4, selection: $selectedTab)
Text("Main_Profile")
.tabItem("Profile", imageName: "person.crop.circle", index: 5, selection: $selectedTab)
}
}
}
Note: The above implementation is for generic purposes - if you don't need some parts (like text in tabs) just remove it or make them optional.

How to put RadioButtons into Form?

I following the link to create RadioButtons.
import SwiftUI
//MARK:- Single Radio Button Field
struct RadioButtonField: View {
let id: String
let label: String
let size: CGFloat
let color: Color
let textSize: CGFloat
let isMarked:Bool
let callback: (String)->()
init(
id: String,
label:String,
size: CGFloat = 20,
color: Color = Color.black,
textSize: CGFloat = 14,
isMarked: Bool = false,
callback: #escaping (String)->()
) {
self.id = id
self.label = label
self.size = size
self.color = color
self.textSize = textSize
self.isMarked = isMarked
self.callback = callback
}
var body: some View {
Button(action:{
self.callback(self.id)
}) {
HStack(alignment: .center, spacing: 10) {
Image(systemName: self.isMarked ? "largecircle.fill.circle" : "circle")
.renderingMode(.original)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: self.size, height: self.size)
Text(label)
.font(Font.system(size: textSize))
Spacer()
}.foregroundColor(self.color)
}
.foregroundColor(Color.white)
}
}
//MARK:- Group of Radio Buttons
enum Gender: String {
case male = "Male"
case female = "Female"
}
struct RadioButtonGroups: View {
let callback: (String) -> ()
#State var selectedId: String = ""
var body: some View {
VStack {
radioMaleMajority
radioFemaleMajority
}
}
var radioMaleMajority: some View {
RadioButtonField(
id: Gender.male.rawValue,
label: Gender.male.rawValue,
isMarked: selectedId == Gender.male.rawValue ? true : false,
callback: radioGroupCallback
)
}
var radioFemaleMajority: some View {
RadioButtonField(
id: Gender.female.rawValue,
label: Gender.female.rawValue,
isMarked: selectedId == Gender.female.rawValue ? true : false,
callback: radioGroupCallback
)
}
func radioGroupCallback(id: String) {
selectedId = id
callback(id)
}
}
struct ContentView: View {
var body: some View {
HStack {
Text("Gender")
.font(Font.headline)
RadioButtonGroups { selected in
print("Selected Gender is: \(selected)")
}
}.padding()
}
}
The code above works well. But when I put the HStack of RadioButtons into Form, the RadioButtons does not work. I cannot select the RadioButtons in this situation. The code is as following:
Form {
HStack {
Text("Gender")
.font(Font.headline)
RadioButtonGroups { selected in
print("Selected Gender is: \(selected)")
}
}.padding()
}
Thanks for any help.
Use instead the following body for RadioButtonField (tested with Xcode 11.4)
var body: some View {
HStack(alignment: .center, spacing: 10) {
Image(systemName: self.isMarked ? "largecircle.fill.circle" : "circle")
.renderingMode(.original)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: self.size, height: self.size)
Text(label)
.font(Font.system(size: textSize))
Spacer()
}.foregroundColor(self.color)
.onTapGesture {
self.callback(self.id)
}
}

SwiftUI: How to implement Radio button in SwiftUI

I'm creating a simple form app. In that, I have checkboxes and Radio buttons, but I don't know how to do it.
I have done below code to dynamically change the selected option's colour. But it can be select multiple values. I need to select only one value among 5 values like a radio button.
E.g:
I'm taping on the second radio button. Now if I select the fourth radio button, the second one should deselect and the fourth one should get selected.
struct DCTableCell: View {
#Binding var dcValue: String
#State var isSelected: Bool = false
var body: some View {
Button(action: {
print("Tapped")
self.isSelected.toggle()
}){
ZStack {
RoundedRectangle(cornerRadius: 8)
.stroke(self.isSelected ? Color.init("borderSelected"): Color.init("border"))
.frame(height: 56)
.foregroundColor(.clear)
HStack {
Text(dcValue)
.font(.custom("Montserrat", size: 16))
.fontWeight(.medium)
.foregroundColor(self.isSelected ? Color.init("borderSelected") : .white)
.padding()
Spacer()
ZStack {
Circle()
.stroke(self.isSelected ? Color.init("borderSelected") : Color("circleBorder"))
.frame(width: 18, height: 18)
.padding()
Circle()
.frame(width: 10, height: 10)
.foregroundColor(self.isSelected ? Color.init("borderSelected"): Color.clear)
}
}
}
}
}
}
check this out...an easy to use SwiftUI RadiobuttonGroup for iOS
you can use it like this:
RadioButtonGroup(items: ["Rome", "London", "Paris", "Berlin", "New York"], selectedId: "London") { selected in
print("Selected is: \(selected)")
}
and here is the code:
struct ColorInvert: ViewModifier {
#Environment(\.colorScheme) var colorScheme
func body(content: Content) -> some View {
Group {
if colorScheme == .dark {
content.colorInvert()
} else {
content
}
}
}
}
struct RadioButton: View {
#Environment(\.colorScheme) var colorScheme
let id: String
let callback: (String)->()
let selectedID : String
let size: CGFloat
let color: Color
let textSize: CGFloat
init(
_ id: String,
callback: #escaping (String)->(),
selectedID: String,
size: CGFloat = 20,
color: Color = Color.primary,
textSize: CGFloat = 14
) {
self.id = id
self.size = size
self.color = color
self.textSize = textSize
self.selectedID = selectedID
self.callback = callback
}
var body: some View {
Button(action:{
self.callback(self.id)
}) {
HStack(alignment: .center, spacing: 10) {
Image(systemName: self.selectedID == self.id ? "largecircle.fill.circle" : "circle")
.renderingMode(.original)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: self.size, height: self.size)
.modifier(ColorInvert())
Text(id)
.font(Font.system(size: textSize))
Spacer()
}.foregroundColor(self.color)
}
.foregroundColor(self.color)
}
}
struct RadioButtonGroup: View {
let items : [String]
#State var selectedId: String = ""
let callback: (String) -> ()
var body: some View {
VStack {
ForEach(0..<items.count) { index in
RadioButton(self.items[index], callback: self.radioGroupCallback, selectedID: self.selectedId)
}
}
}
func radioGroupCallback(id: String) {
selectedId = id
callback(id)
}
}
struct ContentView: View {
var body: some View {
HStack {
Text("Example")
.font(Font.headline)
.padding()
RadioButtonGroup(items: ["Rome", "London", "Paris", "Berlin", "New York"], selectedId: "London") { selected in
print("Selected is: \(selected)")
}
}.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct ContentViewDark_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environment(\.colorScheme, .dark)
.darkModeFix()
}
}
Ok this is not an ideal solution but it works and hopefully opens your eyes to improve what you have. I give every RadioButton an ID and when the selected ID changes it updates:
struct DCTableCell: View {
var id: Int
#Binding var dcValue: String
#Binding var selectedID: Int
var body: some View {
Button(action: {
print("Tapped")
self.selectedID = self.id
}){
ZStack {
RoundedRectangle(cornerRadius: 8)
.stroke(self.id == self.selectedID ? Color.blue : Color.white)
.frame(height: 56)
.foregroundColor(.clear)
HStack {
Text(dcValue)
.font(.custom("Montserrat", size: 16))
.fontWeight(.medium)
.foregroundColor(self.id == self.selectedID ? .blue : .white)
.padding()
Spacer()
ZStack {
Circle()
.stroke(self.id == self.selectedID ? Color.blue : .black)
.frame(width: 18, height: 18)
.padding()
Circle()
.frame(width: 10, height: 10)
.foregroundColor(self.id == self.selectedID ? Color.blue: Color.clear)
}
}
}
}
}
}
And here how to use it. maybe you should create an array with ids and the strings that you want to pass in.
struct ContentView: View {
#State var str = "lolz"
#State var selectedID = -1
var body: some View {
VStack {
ForEach((1...5), id: \.self) { index in
DCTableCell(id: index, dcValue: self.$str, selectedID: self.$selectedID)
}
}
}
}
I hope this helps!
I have a similar solution, use the labels as the hashable tag which makes it very straight. So you only need to setting the outer layer: CustomDCPicker, like a general picker.
UIHostingController(rootView: CustomDCPicker())
struct CustomDCPicker: View {
#State var dcValue: String = ""
var body: some View {
VStack{
Text(dcValue).bold()
DCTable.init(dcValue: $dcValue, Labels: ["sample1","sample2","sample3","sample4","sample5"])
}
}
}
struct DCTable: View {
#Binding var dcValue: String
var Labels: [String] = []
var body: some View {
ForEach(Labels, id:\.self){
DCTableCell(dcValue: self.$dcValue, myLabel: $0)
}
}
}
struct DCTableCell: View {
#Binding var dcValue: String
var isSelected: Bool {
get{ self.dcValue == self.myLabel}
}
var myLabel : String
var body: some View {
Button(action: {
print("Tapped")
self.dcValue = self.myLabel
}){
ZStack {
RoundedRectangle(cornerRadius: 8.0)
.stroke(self.isSelected ? Color.red: Color.yellow)
.frame(height: 56)
.foregroundColor(.clear)
HStack {
Text(myLabel)
//.font(.custom("Montserrat", size: 16))
.fontWeight(.medium)
.foregroundColor(self.isSelected ? Color.red : .black)
.padding()
Spacer()
ZStack {
Circle()
.stroke(self.isSelected ? Color.red : Color.black)
.frame(width: 18, height: 18)
.padding()
Circle()
.frame(width: 10, height: 10)
.foregroundColor(self.isSelected ? Color.red: Color.clear)
}
}
}
}
}
}

Resources