I have a problem that when I write in the first textFiled it be repeated in the rest textfields, like it's shown in the picture:
And here is my code:
First here is the model and viewModel:
struct Person: Identifiable {
var id: String
var name : String
var age : String
}
class PersonViewModel : ObservableObject{
#Published var PersonArray = [Person]()
func emptyPersonArray() {
self.PersonArray.append(Person(id: "", name: "", age: ""))
}
}
and here is my view:
struct ContentView: View {
#ObservedObject var personViewModel = PersonViewModel()
var body: some View {
VStack{
Button(action: {
personViewModel.emptyPersonArray()
}) {
HStack {
Text("Add")
.font(.title3)
.bold()
}
}
.padding()
.foregroundColor(Color.black)
.frame(width: 150.72, height: 40)
.background(RoundedRectangle(cornerRadius: 6).stroke(Color(red: 0.463, green: 0.483, blue: 1.034), lineWidth: 2))
List{
ForEach(personViewModel.PersonArray) {person in
PersonView(name: person.name, age: person.age)
}
}
}
}
}
Finally, here is the PersonView:
struct PersonView: View {
#State var name = ""
#State var age = ""
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 9)
.fill(Color.white)
.frame(width: 650, height: 180)
VStack (alignment: .center) {
Text("Person")
.font(.title3)
.fontWeight(.bold)
VStack{
Text("Enter Name:")
TextField("", text: $name)
.frame(width: 289, height: 40.0)
.background(RoundedRectangle(cornerRadius: 6).stroke(Color.black))
Text("Enter Age:")
TextField("", text: $age).padding()
.frame(width: 289, height: 40.0)
.background(RoundedRectangle(cornerRadius: 6).stroke(Color.black))
} .padding(.leading)
}
}
}
}
Yes, because you are giving the same id to all the persons each time you instantiate a new object, and you basically end up modifying the same person. Try giving a UUID like this to the Person:
struct Person: Identifiable {
var id: UUID = UUID()
var name : String
var age : String
}
class PersonViewModel : ObservableObject{
#Published var PersonArray = [Person]()
func emptyPersonArray() {
self.PersonArray.append(Person(name: "", age: ""))
}
}
Related
Model
I have different variables in Travel.
import Foundation
struct Travel: Identifiable, Codable {
var id = UUID()
var name: String
var date = Date()
var location: String
var isFav: Bool
var score: Float
var comment: String
}
View model
I load and save data with UserDefaults. Always its work but in this model not.
import Foundation
class TravelViewModel: ObservableObject {
#Published var travelList = [Travel] ()
#Published var travelled = 0
init(){
load()
}
func load() {
guard let data = UserDefaults.standard.data(forKey: "travelList"),
let savedTravels = try? JSONDecoder().decode([Travel].self, from: data) else { travelList = []; return }
travelList = savedTravels
}
func save() {
do {
let data = try JSONEncoder().encode(travelList)
UserDefaults.standard.set(data, forKey: "travelList")
} catch {
print(error)
}
}
}
Adding Item View
I have addItems func and use this func in addItem button.
import SwiftUI
struct AddTravelView: View {
#StateObject var VM = TravelViewModel()
#State var name = ""
#State var location = ""
#State var isFav = false
#State var score = 0.00
#State var comment = ""
var body: some View {
VStack {
ZStack {
Rectangle()
.fill(.black.opacity(0.2))
.cornerRadius(20)
.frame(width: 350, height: 350)
VStack{
HStack {
Text("Name:")
.font(.system(size: 16 , weight: .medium))
TextField("Type..", text: $name)
}
HStack {
Text("Location:")
.font(.system(size: 16 , weight: .medium))
TextField("Type..", text: $location)
}
HStack {
Text("Score: \(Int(score))")
.font(.system(size: 16 , weight: .medium))
Slider(value: $score, in: 0...10, step: 1)
}
Spacer()
ZStack(alignment: .topLeading) {
Rectangle()
.fill(.white)
.cornerRadius(20)
.frame(height: 200)
VStack(alignment: .leading) {
TextField("Comment...", text: $comment, axis: .vertical)
}.padding()
}
}
.padding()
.frame(width: 300, height: 200)
}
Button {
addTravel()
} label: {
ZStack{
Rectangle()
.fill(.black.opacity(0.2))
.cornerRadius(20)
.frame(width: 350 , height: 100)
Text("ADD TRAVEL")
.font(.system(size: 25, weight: .medium, design: .monospaced))
.foregroundColor(.black)
}.padding()
}
}
}
func addTravel(){
VM.travelList.append(Travel(name: name, location: location, isFav: isFav, score: Float(score), comment: comment))
}
}
struct AddTravelView_Previews: PreviewProvider {
static var previews: some View {
AddTravelView()
}
}
Recent Adds view
In this page i wanna see Items i add before
import SwiftUI
struct RecentTravels: View {
#StateObject var VM = TravelViewModel()
var body: some View {
VStack {
ForEach(VM.travelList) {Travel in
HStack{
Image(systemName: "questionmark")
.frame(width: 50, height: 50)
.padding()
.overlay {
RoundedRectangle(cornerRadius: 5)
.stroke(.black, lineWidth: 2)
}
VStack(alignment: .leading) {
Text(Travel.name)
.font(.subheadline)
.bold()
.lineLimit(1)
Text("\(Travel.date)")
.font(.footnote)
.opacity(0.9)
.lineLimit(1)
}
Spacer()
VStack {
Image(systemName: "heart")
Spacer()
Text("\(Travel.score)")
}
.frame(height: 50)
.font(.system(size: 22))
}
}
}
}
}
struct RecentTravels_Previews: PreviewProvider {
static var previews: some View {
RecentTravels()
}
}
And ContentView
and calling those 2 views in ContentView.
import SwiftUI
struct ContentView: View {
#StateObject var VM = TravelViewModel()
var body: some View {
VStack {
AddTravelView()
RecentTravels()
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
When i write the all code in only ContentView is work but when i call another pages its not work. Usually it was work when i presss add item button and restart app but now its nothing. Its not work even restart the app.
The problem you have is that you have multiple VM, that have no relations to each other. You must not have more than one source of truth
in #StateObject var VM = TravelViewModel().
Keep the one you have in ContentView,
and pass it to the other view like this:
VStack {....}.environmentObject(VM).
In your AddTravelView and RecentTravels ,
add #EnvironmentObject var VM: TravelViewModel instead of #StateObject var VM = TravelViewModel().
Have a look at this link, it gives you some good examples of how to manage data in your app:
https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app
This question already has answers here:
What is the difference between ObservedObject and StateObject in SwiftUI
(6 answers)
Saving Date/Time to UserDefaults through didSet on #Published var (from TimePicker component of SwiftUI)
(1 answer)
Closed 8 months ago.
I trying to update the array when the user change the input.
Here is the viewModel
struct Person: Identifiable {
var id = UUID()
var name : String
var age : String
}
class PersonViewModel : ObservableObject{
#Published var PersonArray = [Person]()
func emptyPersonArray() {
self.PersonArray.append(Person(name: "", age: ""))
}
}
struct ContentView: View {
#ObservedObject var personViewModel = PersonViewModel()
var body: some View {
VStack{
Button(action: {
personViewModel.emptyPersonArray()
}) {
HStack {
Text("Add")
.font(.title3)
.bold()
}
}
.padding()
.foregroundColor(Color.black)
.frame(width: 150.72, height: 40)
.background(RoundedRectangle(cornerRadius: 6).stroke(Color(red: 0.463, green: 0.483, blue: 1.034), lineWidth: 2))
List{
ForEach(personViewModel.PersonArray) {person in
PersonView(person: person,name: person.name, age: person.age)
}.padding(.leading, -150)
}
Button(action: {
for person in personViewModel.PersonArray{
print("Person Name: \(person.name)")
print("Person Age: \(person.age)")
}
}) {
HStack {
Text("Show data")
.font(.title3)
.bold()
}
}
}
}
}
here is PersonView:
struct PersonView: View {
#State var person: Person
#State var name = ""
#State var age = ""
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 9)
.fill(Color.white)
.frame(width: 650, height: 180)
VStack (alignment: .center) {
Text("Person")
.font(.title3)
.fontWeight(.bold)
VStack{
Text("Enter Name:")
TextField("", text: $name)
.onChange(of: name, perform: { newValue in
person.name = newValue
})
.frame(width: 289, height: 40.0)
.background(RoundedRectangle(cornerRadius: 6).stroke(Color.black))
Text("Enter Age:")
TextField("", text: $age).padding()
.onChange(of: age, perform: { newValue in
person.age = newValue
})
.frame(width: 289, height: 40.0)
.background(RoundedRectangle(cornerRadius: 6).stroke(Color.black))
} .padding(.leading)
}
}
}
}
when I tried to print it shows empty and did not update:
The problem have be solved
by changing the #State to #Binding in PersonView
struct PersonView: View {
#Binding var person: Person
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 9)
.fill(Color.white)
.frame(width: 650, height: 180)
VStack (alignment: .center) {
Text("Person")
.font(.title3)
.fontWeight(.bold)
VStack{
Text("Enter Name:")
TextField("", text: $person.name)
.onChange(of: person.name, perform: { newValue in
person.name = newValue
})
.frame(width: 289, height: 40.0)
.background(RoundedRectangle(cornerRadius: 6).stroke(Color.black))
Text("Enter Age:")
TextField("", text: $person.age).padding()
.onChange(of: person.age, perform: { newValue in
person.age = newValue
})
.frame(width: 289, height: 40.0)
.background(RoundedRectangle(cornerRadius: 6).stroke(Color.black))
} .padding(.leading)
}
}
}
}
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
am trying to change the color of the button according to the isSelected state but not working
struct Box: Identifiable {
var id: Int
var title: String
#State var isSelected: Bool
}
struct BoxView: View {
var box: Box
var body: some View{
Button(action: {
self.box.isSelected.toggle()
}){
Text(box.title)
.foregroundColor(.white)
}
.frame(width: 130, height: 50)
.background(self.box.isSelected ? Color.red : Color.blue)
.cornerRadius(25)
.shadow(radius: 10)
.padding(10)
}
}
Try this way.
struct Box: Identifiable {
var id: Int
var title: String
}
struct BoxView: View {
var box: Box
#State var selectedBtn: Int = 1
var body: some View {
ForEach((1...10).reversed(), id: \.self) { item in
Button(action: {
self.selectedBtn = item
}){
Text(self.box.title)
.foregroundColor(.white)
}
.frame(width: 130, height: 50)
.background(self.selectedBtn == item ? Color.red : Color.blue)
.cornerRadius(25)
.shadow(radius: 10)
.padding(10)
}
}
}
you can also observe when value change like this way.
class Box: ObservableObject {
let objectWillChange = ObservableObjectPublisher()
var isSelected = false { willSet { objectWillChange.send() } }
}
struct ContentView: View {
#ObservedObject var box = Box()
var body: some View {
VStack{
Button(action: {
self.box.isSelected.toggle()
}){
Text("tap")
.foregroundColor(.white)
}
.background(box.isSelected ?? false ? Color.red : Color.blue)
.cornerRadius(25)
.shadow(radius: 10)
.padding(10)
}
}
}
You can change Button background Color on click using below code
struct ContentView: View {
#State var isSelected : Bool = false
var body: some View {
VStack {
Button(action: {
self.isSelected.toggle()
}){
Text("State")
.foregroundColor(.white)
}
.frame(width: 130, height: 50)
.background(self.isSelected ? Color.red : Color.blue)
}
}
}
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)
}
}
}
}
}
}