Spring animation in SwiftUI, IOS14 is broken - swiftui

struct ContentView: View {
#State var search: String = ""
let data = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"]
var body: some View {
VStack {
TextField("search", text: self.$search)
.foregroundColor(.primary)
.padding(EdgeInsets(top: 8, leading: 6, bottom: 8, trailing: 6))
.background(Color(.secondarySystemBackground))
.cornerRadius(10.0)
.padding(.horizontal)
List(data.filter { $0.contains(self.search.lowercased()) || self.search.isEmpty }, id:\.self) { str in
HStack {
Text(str)
.font(.title)
.padding(.leading)
Spacer()
}
.frame(height: 45)
}
.animation(.spring())
.listStyle(GroupedListStyle())
}
}
}
Video example
When I quickly edit the search text List doesn't work correctly.
This bug happens only in IOS 14+ with .animation(.spring()) modifier.

Related

Swiftui Navigation Question Using NavigationLink to specific Tab

Basically I have the below listed code working with the exception of getting to view 4. I'm guessing I've messed up the binding in some way, I just can't figure out what. Can anyone help make this happen? Here's where I am with code:
import SwiftUI
struct ContentView: View {
#State var activeView: Int = 0
#State var activeNavigationLink: Int = 0
let items = ["View1", "View2", "View3", "View4"]
func navigationLinkBinding(id: Int) -> Binding<Bool> {
.init { () -> Bool in
activeNavigationLink == id
} set: { (newValue) in
if newValue {
activeNavigationLink = id
} else {
activeNavigationLink = 0
}
}
}
var body: some View {
TabView(selection: Binding<Int> (
get: {
activeView
}, set: {
activeView = $0
activeNavigationLink = 0
}))
{
NavigationView {
HStack(spacing: 40) {
VStack {
NavigationLink(
destination: NewView(), isActive: navigationLinkBinding(id: 2), label: {
Rectangle()
.fill(Color.red)
.cornerRadius(12)
.frame(width: 70, height: 70)
}).isDetailLink(false)
Text("To View 3")
}
VStack{
NavigationLink(
destination: NewView(), isActive: navigationLinkBinding(id: 3), label: {
Rectangle()
.fill(Color.red)
.cornerRadius(12)
.frame(width: 70, height: 70)
}).isDetailLink(false)
Text("To View 4")
}
}.navigationTitle("")
.navigationBarHidden(true)
}
.tabItem {
Image(systemName: "a.circle")
Text("Main")
}
.tag(0)
Text("View 5")
.padding()
.tabItem {
Image(systemName: "b.circle")
Text("View 3")
}
.tag(1)
}
}
}
The below is in the same file as the above. It is where view 4 resides:
struct NewView: View {
let items = ["View1", "View2", "View3", "View4"]
var body: some View {
HStack {
TabView {
VStack {
Rectangle()
.fill(Color.green)
.cornerRadius(12)
.frame(width: 70, height: 70)
Text(items[2])
}
.tabItem {Image(systemName: "a.circle"); Text("GREEN")}
.id(2)
VStack {
Rectangle()
.fill(Color.blue)
.cornerRadius(12)
.frame(width: 70, height: 70)
Text(items[3])
}
.tabItem {Image(systemName: "b.circle"); Text("BLUE")}
.id(3)
}
.navigationTitle("")
.navigationBarHidden(true)
.tabViewStyle(.page)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Here's the working code:
// ContentView.swift
// navtest
//
// Created by MRBarclay on 4/9/22.
//
import SwiftUI
struct ContentView: View {
#State var activeView: Int = 0
#State var activeNavigationLink: Int = 0
func navigationLinkBinding(id: Int) -> Binding<Bool> {
.init { () -> Bool in
activeNavigationLink == id
} set: { (newValue) in
if newValue {
activeNavigationLink = id
} else {
activeNavigationLink = 0
}
}
}
var body: some View {
TabView(selection: Binding<Int> (
get: {
activeView
}, set: {
activeView = $0
activeNavigationLink = 0
}))
{
VStack {
Text("Main 1")
Rectangle()
.fill(Color.yellow)
.cornerRadius(12)
.frame(width: 70, height: 70)
}
.tabItem {Image(systemName: "1.circle"); Text("Main 1")}
.tag(1)
NavigationView {
HStack(spacing: 40) {
VStack {
Text("Main 2")
NavigationLink(
destination: NewView(selectedItem: 1), isActive: navigationLinkBinding(id: 1), label: {
Rectangle()
.fill(Color.red)
.cornerRadius(12)
.frame(width: 70, height: 70)
}).isDetailLink(false)
Text("To Sub 1")
}
VStack{
Text("Main 2")
NavigationLink(
destination: NewView(selectedItem: 2), isActive: navigationLinkBinding(id: 2), label: {
Rectangle()
.fill(Color.red)
.cornerRadius(12)
.frame(width: 70, height: 70)
}).isDetailLink(false)
Text("To Sub 2")
}
VStack{
Text("Main 2")
NavigationLink(
destination: NewView(selectedItem: 3), isActive: navigationLinkBinding(id: 3), label: {
Rectangle()
.fill(Color.red)
.cornerRadius(12)
.frame(width: 70, height: 70)
}).isDetailLink(false)
Text("To Sub 3")
}
}.navigationTitle("")
.navigationBarHidden(true)
}
.tabItem {Image(systemName: "2.circle"); Text("Main 2")}
.tag(2)
NavigationView {
HStack(spacing: 40) {
VStack {
Text("Main 3")
NavigationLink(
destination: NewView(selectedItem: 1), isActive: navigationLinkBinding(id: 1), label: {
Rectangle()
.fill(Color.blue)
.cornerRadius(12)
.frame(width: 70, height: 70)
}).isDetailLink(false)
Text("To Sub 1")
}
VStack{
Text("Main 3")
NavigationLink(
destination: NewView(selectedItem: 2), isActive: navigationLinkBinding(id: 2), label: {
Rectangle()
.fill(Color.blue)
.cornerRadius(12)
.frame(width: 70, height: 70)
}).isDetailLink(false)
Text("To Sub 2")
}
VStack{
Text("Main 3")
NavigationLink(
destination: NewView(selectedItem: 3), isActive: navigationLinkBinding(id: 3), label: {
Rectangle()
.fill(Color.blue)
.cornerRadius(12)
.frame(width: 70, height: 70)
}).isDetailLink(false)
Text("To Sub 3")
}
}.navigationTitle("")
.navigationBarHidden(true)
}
.tabItem {Image(systemName: "3.circle"); Text("Main 3")}
.tag(3)
NavigationView {
HStack(spacing: 40) {
VStack {
Text("Main 4")
NavigationLink(
destination: NewView(selectedItem: 1), isActive: navigationLinkBinding(id: 1), label: {
Rectangle()
.fill(Color.green)
.cornerRadius(12)
.frame(width: 70, height: 70)
}).isDetailLink(false)
Text("To Sub 1")
}
VStack{
Text("Main 4")
NavigationLink(
destination: NewView(selectedItem: 2), isActive: navigationLinkBinding(id: 2), label: {
Rectangle()
.fill(Color.green)
.cornerRadius(12)
.frame(width: 70, height: 70)
}).isDetailLink(false)
Text("To Sub 2")
}
VStack{
Text("Main 4")
NavigationLink(
destination: NewView(selectedItem: 3), isActive: navigationLinkBinding(id: 3), label: {
Rectangle()
.fill(Color.green)
.cornerRadius(12)
.frame(width: 70, height: 70)
}).isDetailLink(false)
Text("To Sub 3")
}
}.navigationTitle("")
.navigationBarHidden(true)
}
.tabItem {Image(systemName: "4.circle"); Text("Main 4")}
.tag(4)
}
}
}
struct NewView: View {
#State var selectedItem: Int
#State var activeNavigationLink: Int = 0
var body: some View {
TabView(selection: $selectedItem) {
VStack {
Rectangle()
.fill(Color.blue)
.cornerRadius(12)
.frame(width: 70, height: 70)
Text("One")
}
.tabItem {Image(systemName: "a.circle"); Text("BLUE")}
.tag(1)
VStack {
Rectangle()
.fill(Color.green)
.cornerRadius(12)
.frame(width: 70, height: 70)
Text("Two")
}
.tabItem {Image(systemName: "b.circle"); Text("GREEN")}
.tag(2)
VStack {
Rectangle()
.fill(Color.orange)
.cornerRadius(12)
.frame(width: 70, height: 70)
Text("Three")
}
.tabItem {Image(systemName: "b.circle"); Text("ORANGE")}
.tag(3)
}
.navigationTitle("")
.navigationBarHidden(true)
.tabViewStyle(.page)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

Make a VStack height according to content in SwiftUI

I want to make a "card" but the height depends a list of items, I don't how to set a different value according to my sizes list... Example:
ContentView Struct
struct ContentView: View {
#State private var orderList : [Order] = [
Order(id: 0, productList: [Product(id: 0, name: "itemA", quantity: "24", isEvaluated: true), Product(id: 0, name: "itemB", quantity: "2", isEvaluated: false)]),
Order(id: 1, productList: [Product(id: 0, name: "itemC", quantity: "4", isEvaluated: true), Product(id: 0, name: "itemD", quantity: "12", isEvaluated: false),Product(id: 0, name: "itemE", quantity: "6", isEvaluated: false), Product(id: 0, name: "itemF", quantity: "5", isEvaluated: false)]),
Order(id: 2, productList: [Product(id: 0, name: "itemG", quantity: "24", isEvaluated: true)]),
Order(id: 3, productList: [Product(id: 0, name: "itemH", quantity: "5", isEvaluated: true), Product(id: 0, name: "itemI", quantity: "2", isEvaluated: false),Product(id: 0, name: "itemJ", quantity: "16", isEvaluated: false), Product(id: 0, name: "itemK", quantity: "4", isEvaluated: false), Product(id: 0, name: "itemL", quantity: "2", isEvaluated: false)]),
Order(id: 4, productList: [Product(id: 0, name: "itemM", quantity: "8", isEvaluated: true)])
]
var body: some View {
VStack{
ForEach(orderList, id: \.self){order in
ScrollView(showsIndicators: false){
VStack(alignment: .leading){
Group{
HStack{
Text("#Order " + "\(order.id)").multilineTextAlignment(.center)
Spacer()
Text("In Progress").multilineTextAlignment(.center)
}.padding([.bottom],5)
}
Group{
VStack{
ForEach(order.productList.indices) { currentIndex in
ItemRow(getProduct(productList: order.productList, index: currentIndex))
.padding(.bottom, 5)
}
}
}.padding([.bottom], 10)
HStack{
Text("Products")
Spacer()
Text("$00.00")
}
HStack{
Text("Shipping Expenses")
Spacer()
Text("$00.00")
}
HStack{
Text("Total")
Spacer()
Text("$0.00")
}
Spacer()
}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
.padding(10)
}
.background(
RoundedRectangle(cornerRadius: 2)
.fill(Color.white)
.shadow(color: .gray, radius: 2, x: 0, y: 2)
)
.padding(.bottom, 10)
}
}
.padding(16)
}
func getProduct(productList: [Product], index: Int)-> Product{
return productList[index]
}
}
ItemRow Struct
struct ItemRow: View {
let currentProduct: Product
init(_ currentProduct: Product) {
self.currentProduct = currentProduct
}
var body: some View {
HStack{
HStack{
Text("• \(currentProduct.name)")
Spacer()
}
HStack{
Text("quantity \(currentProduct.quantity)")
Spacer()
}
if !currentProduct.isEvaluated{
HStack{
Spacer()
Button(action:{
// do sth
}){
Text("rate now!")
}
}
}
}
}
}
PS. in itemsList you must create a struct called Order like this: (Don't mind on hardcode values, I made it to make the example easier)
struct Order: Hashable {
var id: Int
var productList: [Product]
}
PS2. in productList you must create a struct called Product like this:
struct Product: Hashable {
var id: Int
var name: String
var quantity : String
var isEvaluated : Bool
}
If I understand you correctly you want the cards (red frame) to take as much space as they need to display the content they have without the need of scrolling on the card itself?
Short answer. You don't need to.
SwiftUI does it for you. You only have one small mistake in your code in ContentView. Move the ScrollView up to the level where you have the VStack and remove the VStack. You ContentView body should now look like this:
var body: some View {
ScrollView {
ForEach(orderList, id: \.self){order in
VStack(alignment: .leading){
Group{
HStack{
Text("#Order " + "\(order.id)").multilineTextAlignment(.center)
Spacer()
Text("In Progress").multilineTextAlignment(.center)
}.padding([.bottom],5)
}
Group{
VStack{
ForEach(order.productList.indices) { currentIndex in
ItemRow(getProduct(productList: order.productList, index: currentIndex))
.padding(.bottom, 5)
}
}
}.padding([.bottom], 10)
HStack{
Text("Products")
Spacer()
Text("$00.00")
}
HStack{
Text("Shipping Expenses")
Spacer()
Text("$00.00")
}
HStack{
Text("Total")
Spacer()
Text("$0.00")
}
Spacer()
}.background(
RoundedRectangle(cornerRadius: 2)
.fill(Color.white)
.shadow(color: .gray, radius: 2, x: 0, y: 2)
)
.padding(.bottom, 10)
}
}
.padding(16)
}
This gives you the following result:

SwiftUI Binding Data

trying to bring data from LeadDetailUI to formUI to be able to edit the data in formUI and for the life of me can't figure this out, not sure on way to go (Bindings or environmentObject). eighthor way can't get it to work. I tried with bindings couldn't get it to work. please help with example on how to do this.
struct LeadDetailUI: View {
#ObservedObject var viewModel: getCustomerData
#State var tbl11 = ""
#State var tbl12 = ""
#State var tbl13 = ""
#State var tbl14 = ""
#State var tbl15 = ""
#State var tbl16 = ""
#State var tbl17 = ""
#State var tbl21 = ""
#State var tbl22 = 0
#State var tbl23 = 0
#State var tbl24 = 0
#State var tbl25 = 0
#State var tbl26 = ""
#State var tbl27 = ""
#State var l11 = ""
#State var l12 = ""
#State var l13 = ""
#State var l14 = ""
#State var l15 = ""
#State var l16 = ""
#State var l17 = ""
#State var l21 = ""
#State var l22 = ""
#State var l23 = ""
#State var l24 = ""
#State var l25 = ""
#State var l26 = ""
#State var l27 = ""
var body: some View {
NavigationView {
VStack() {
ScrollView(self.height > 700 ? .init() : .vertical, showsIndicators: true) {
VStack(alignment: .trailing, spacing: 13) {
HStack {
TextField("Peter Balsamo", text: $name).font(.title)
.padding(.top, 3)
.padding(.leading, 20)
.padding(.bottom, -10)
//.redacted(reason: .placeholder)
Text("Following").font(.headline)
.padding(.top, 10)
Button(action: {
}) {
Image(systemName: "star.fill")
.resizable()
.frame(width: 20, height: 20)
.foregroundColor(Color.orange)
.padding(.top, 7)
.padding(.trailing, 15)
}
}
Divider()
VStack {
HStack {
VStack(alignment: .leading, spacing: 5, content: {
TextField("Amount", text: $amount).font(.largeTitle)
.offset(y: -3)
TextField("Address", text: $address).font(.title3)
TextField("City", text: $city).font(.title3)
TextField("Sale Date:", text: $l1datetext).font(.caption2)
.padding(.top, 15)
TextField("Date:", text: $date).font(.headline)
.padding(.top, -5)
})
.padding(.bottom, 0)
.padding(.leading, 15)
Spacer()
VStack(alignment: .trailing, spacing: 0, content: {
Image("taylor_swift_profile")
.resizable()
.frame(width: 115, height: 115)
.clipShape(Circle())
.overlay(Circle().stroke(Color.white, lineWidth: 2))
.padding(.top, -25)
TextField("Lead#", text: $id).font(.caption2)
.multilineTextAlignment(.trailing)
.padding(.top, 15)
})
.frame(width: 120)
.padding(.trailing, 10)
Spacer()
}
HStack {
VStack(alignment: .leading, spacing: 0, content: {
HStack {
Toggle("", isOn: $showingSold.animation(.spring()))
.frame(width:80, height: 30)
.toggleStyle(SwitchToggleStyle(tint: .blue))
.clipShape(RoundedRectangle(cornerRadius: 10))
if showingSold {
Text("Priority").font(.headline)
.background(Color.red.cornerRadius(10))
.foregroundColor(.white)
.padding(.leading, 10)
}
}
})
Spacer()
Button(action: {
showFullscreen.toggle()
}) {
Text("Map")
.fontWeight(.bold)
.frame(width:115, height: 30)
.foregroundColor(.white)
.background(Color(.systemBlue))
.clipShape(RoundedRectangle(cornerRadius: 10))
}
.padding(.trailing, 20)
}
.padding(.bottom, 30)
}
.fullScreenCover(isPresented: $showFullscreen, content: {
HomeMap()
})
}
.foregroundColor(self.color == 0 ? Color.black : Color.white)
.background(self.color == 0 ? Color.yellow : Color.purple)
.clipShape(CustomShape(corner: .bottomLeft, radii: 55))
ScrollView(self.height > 800 ? .init() : .vertical, showsIndicators: false) {
let first = DataUI(name: tbl11, label: l11)
let second = DataUI(name: tbl12, label: l12)
let third = DataUI(name: tbl13, label: l13)
let fourth = DataUI(name: tbl14, label: l14)
let fifth = DataUI(name: tbl15, label: l15)
let sixth = DataUI(name: tbl16, label: l16)
let seventh = DataUI(name: tbl17, label: l17)
let eighth = DataUI(name: tbl21, label: l21)
let ninth = DataUI(name: "\(tbl22)", label: l22)
let tenth = DataUI(name: "\(tbl23)", label: l23)
let eleven = DataUI(name: "\(tbl24)", label: l24)
let twelve = DataUI(name: "\(tbl25)", label: l25)
let thirteen = DataUI(name: tbl26, label: l26)
let fourteen = DataUI(name: tbl27, label: l27)
let customers = [first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleven, twelve,thirteen, fourteen]
List(customers) { customer in
CenterViewUI(formData: customer)
}
}
.edgesIgnoringSafeArea(.all)
.statusBar(hidden: true)
.animation(.default)
BottomViewUI(comments: self.$comments, lnewsTitle: self.$lnewsTitle, index: $index)
}
.shadow(color: Color.white.opacity(0.2), radius: 5, x: 0, y: 2)
}
.navigationTitle("Profile")
.navigationBarHidden(false)
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems (
leading:
Button(action: {
showActionSheet.toggle()
}) {
Image(systemName: "square.and.arrow.up")
.resizable()
.frame(width: 20, height: 20)
},
trailing:
//NavigationLink(destination: FormUI(frm11: $tbl11)) {
Button(action: {
showSheet.toggle()
}, label: {
Text("Edit")
.actionSheet(isPresented: $showActionSheet, content: getActionSheet)
.sheet(isPresented: $showSheet, content: {
FormUI()
})
.foregroundColor(self.color == 0 ? Color.yellow : Color.purple)
}
}
struct DataUI: Identifiable {
var id = UUID().uuidString
var name: String
var label : String
}
struct SwiftUIView_Previews: PreviewProvider {
static var previews: some View {
Group {
LeadDetailUI(viewModel: getCustomerData())
.preferredColorScheme(.dark)
}
}
}
public struct FormUI: View {
#Environment(\.presentationMode) var presentationMode
#EnvironmentObject var viewModel: getCustomerData
private var db = Firestore.firestore()
#State var frm11 = ""
#State var frm12 = ""
#State var frm13 = ""
#State var frm14 = ""
#State var frm15 = ""
#State var frm16 = ""
#State var frm17 = ""
#State var frm18 = ""
#State var frm19 = ""
public var body: some View {
NavigationView {
VStack {
ScrollView(self.height > 800 ? .init() : .vertical, showsIndicators: false) {
VStack {
//ForEach(self.viewModel.data) { i in
Form {
Section {
HStack{
VStack{
Image("taylor_swift_profile")
.resizable()
.frame(width: 75, height: 75)
.clipShape(Circle())
.overlay(Circle().stroke(Color.white, lineWidth: 2))
.padding()
Button(action: {}, label: {
Text("Edit")
.font(.caption)
.padding(.top, -15)
.foregroundColor(self.color == 0 ? Color.purple : Color.red)
})
}
.padding(.leading, -30)
Divider()
Spacer()
VStack(spacing: 12) {
TextField("First", text: $frm11)
TextField("Last", text: $frm12)
Picker(selection: $selection, label:
TextField("Company", text: $callback)) {
ForEach(0 ..< pickContractor.count) {
Text(self.pickContractor[$0])
}
}
}
.font(.system(size: 20.0))
.multilineTextAlignment(.leading)
}
}
.font(.headline)
.padding(.leading, 18)
Section(header: Text("Customer Info")) {
HStack {
Text("Address:")
.formTextStyle()
Spacer()
TextField("address", text: $address)
.formStyle()
}
HStack {
Text("City:")
.formTextStyle()
Spacer()
TextField("city", text: $city)
.formStyle()
}
HStack {
Text("State:")
.formTextStyle()
.multilineTextAlignment(.leading)
Spacer()
TextField("state", text: $state)
.formStyle()
.frame(minWidth: 50, maxWidth: 60)
.autocapitalization(.allCharacters)
.multilineTextAlignment(.leading)
//.padding(.leading, )
Spacer()
Text("Zip:")
.formTextStyle()
TextField("zip", text: $zip)
.formStyle()
.frame(minWidth: 100, maxWidth: 145)
.keyboardType(.numberPad)
}
HStack {
Text("Phone:")
.formTextStyle()
Spacer()
TextField("phone", text: $phone)
.formStyle()
.keyboardType(.numberPad)
}
HStack {
Text("Amount:")
.formTextStyle()
Spacer()
Stepper(
onIncrement: {
stepperValue += 1000
},
onDecrement: {
stepperValue -= 1000
},
label: {
TextField("amount", text: $amount)
.formStyle()
})
}
HStack {
Text("Email:")
.formTextStyle()
Spacer()
TextField("email", text: $email)
.formStyle()
.keyboardType(.emailAddress)
}
}
Section {
HStack {
Text("Salesman:")
.formTextStyle()
Spacer()
TextField("salesman", text: $salesman)
}
HStack {
Text("Job:")
.formTextStyle()
Spacer()
TextField("job", text: $jobName)
.formStyle()
}
HStack {
Text("Product:")
.formTextStyle()
Spacer()
TextField("product", text: $adName)
.formStyle()
}
HStack {
Text("Quantity:")
.formTextStyle()
Spacer()
TextField("quantity", text: $frm25)
.formStyle()
.keyboardType(.numberPad)
}
HStack {
Text("Apt Date:")
.formTextStyle()
Spacer()
DatePicker(selection: $selDate, displayedComponents: .date) {
TextField("", text: $aptdate)
.formStyle()
}
}
HStack {
Text("Comments:")
.formTextStyle()
Spacer()
TextEditor(text: $comment)
}
}
Section(header: Text("Misc")) {
HStack {
Toggle(isOn: $isOn) {
Text("\(self.isOn == true ? "Active":"Not Active")")
.formTextStyle()
}
.toggleStyle(SwitchToggleStyle(tint: .purple))
}
HStack {
Text("Date")
.formTextStyle()
Spacer()
DatePicker(selection: $selDate, displayedComponents: .date, label: {
TextField("", text: $date)
})
}
HStack {
Text("Spouse")
.formTextStyle()
Spacer()
TextField("spouse", text: $spouse)
}
HStack {
Text("Called Back")
.formTextStyle()
Spacer()
Picker(selection: $selection, label:
TextField("", text: $callback)) {
ForEach(0 ..< callbackPicker.count) {
Text(self.callbackPicker[$0])
}
}
}
HStack {
Text("Rate")
.formTextStyle()
Spacer()
Picker(selection: $selection, label:
TextField("", text: $rate)) {
ForEach(0 ..< pickRate.count) {
Text(verbatim: self.pickRate[$0])
}
}
}
HStack {
Text("Photo")
.formTextStyle()
Spacer()
TextField("photo", text: $photo)
}
}
}
.font(.system(size: 20.0))
.padding(.top, -40)
}
}
}
.navigationTitle("Data Entry")
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(action: {
presentationMode.wrappedValue.dismiss()
}) {
Image(systemName: "xmark.circle").font(.largeTitle)
}
}
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {
//if !frm11.isEmpty && !frm12.isEmpty {
saveData()
resetTextFields()
self.alert.toggle()
}, label: {
Text("Save")
}
}
.alert(isPresented: $alert) {
Alert(title: Text("Upload Complete"), message: Text("Successfully updated the data"), dismissButton: .default(Text("Ok")))
}
}
.accentColor(self.color == 0 ? Color.purple : Color.red)
}
private func saveData() {
let uid = Auth.auth().currentUser!.uid
var ref: DocumentReference? = nil
ref = db.collection("Customers").addDocument(data: [
"active": frm30,
"custId": frm12,
"custNo": custNo,
"leadNo": leadNo,
"first": frm11,
"lastname": frm12,
"contractor": frm13,
"city": city,
"state": state,
"zip": zip,
"phone": phone,
"amount": Int(amount) as Any,
"email": email,
"rate": rate,
"salesNo": saleNo,
"jobNo": jobNo,
"adNo": adNo,
"quan": Int(frm25) as Any,
"start": NSNull(),
"completion": NSNull(),
"lastUpdate": Timestamp(date: Date()),
"creationDate": Timestamp(date: Date()),
"aptdate": aptdate,
"comments": comment,
"spouse": spouse,
"photo": photo,
"uid": uid,
]) { error in
if let error = error {
print("Error adding document: \(error)")
} else {
print("Document added with ID: \(ref!.documentID)")
}
}
}
func updateData() {
db.collection("Customer")
.document()
.setData(["active":self.frm30,"custId":self.frm12,"custNo":self.custNo,"leadNo":self.leadNo,"first":self.frm11,"lastname":self.frm12,"contractor":self.frm13,"city":self.city,"state":self.state,"zip":self.zip,"phone":self.phone,"amount":self.amount,"email":self.email,"rate":self.rate,"salesNo":self.saleNo,"jobNo":self.jobNo,"adNo":self.adNo,"start":self.start,"lastUpdate":Timestamp(date:Date()),"aptdate":self.aptdate,"comments":self.comment,"spouse":self.spouse,"photo":self.photo]) { (error) in
if error != nil{
print((error?.localizedDescription)!)
return
}
//self.presentation.wrappedValue.dismiss()
}
}
}
struct FormUI_Previews: PreviewProvider {
static var previews: some View {
FormUI()
.preferredColorScheme(.dark)
}
}

How align columns for multiple items on a VStack on SwiftUI?

In the sample below, if I have a VStack followed for a HStack, how can I make the width of the HStack follow the same as a grid ?
struct VStackAlignmentView: View {
let data = ["a", "b", "cdefghl alalala", "i", "j"]
var body: some View {
VStack(spacing: 0) {
ForEach (data, id:\.self) { item in
HStack(alignment: .top) {
Text("Column 1")
VStack(alignment: .trailing) {
Text("Column \(item)")
Text("Value 2")
}
.frame(minWidth: 120)
Text("Column 3")
Spacer()
}
}
}
}
}
This is the result I got:
The text on the 3rd row is aligned to the right, but the other rows it adds a space to that
I have tried a hack to for the VStack(alignment: .trailing) by adding an empty Text with the frame width and it works, but I don't think that is an elegant way.
I also tried to use alignmentGuide but it push the views to other way.
Anyone with the same problem?
Using you're code, I believe this is what you're looking for:
struct VStackAlignmentView: View {
let data = ["a", "b", "cdefghl alalala", "i", "j"]
var body: some View {
VStack(alignment: .center, spacing: 20) {
ForEach (data, id:\.self) { item in
HStack(alignment: .top, spacing: 20) {
Text("Column 1")
VStack(alignment: .center) {
Text("Column \(item)")
Text("Value 2")
}
.frame(minWidth: 120)
Text("Column 3")
}
.frame(maxWidth: .infinity)
}
}
.multilineTextAlignment(.center)
.frame(maxWidth: .infinity)
}
}
But if you're just creating a grid layout, it will be much easer to use a LazyGrid:
struct VStackAlignmentView2: View {
let data = ["a", "b", "cdefghl alalala", "i", "j"]
var body: some View {
LazyVGrid(
columns: [
GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())
],
alignment: .center,
spacing: 10,
pinnedViews: [],
content: {
ForEach (data, id:\.self) { item in
Text(item)
}
})
}
}

how to have a navigationLink contain a Text and a Image

I am building a recipe app in SwiftUI. I have created the home screen with a few lists of a view which I created in a separate file. (see picture, I don't have all the images yet, so I have the same image for all views)
I want to embed the view inside a navigationLink so that when a user tapped on A dish, that it will go to a detail screen. this is the code I have:
struct MenuTopicView: View {
var titleText: String
var foodImageName: String
var body: some View {
NavigationLink(destination: RecipeView(recipeName: titleText)) {
ZStack {
Image(foodImageName)
.resizable()
VStack {
Text(titleText)
.foregroundColor(Color.init(hex: "AAAAAA"))
.font(.system(size: 30, weight: .semibold))
Spacer()
}
}
.frame(width: 189, height: 194)
.cornerRadius(15)
.shadow(color: Color.init(hex:"000000"), radius: 7,x: 7, y: 7)
}
}
}
but when I run that, I get this:
this is the code of the main view, where I create that layout:
struct ContentView: View {
private var spacing: CGFloat = 20
var body: some View {
VStack {
Text("First Course")
.frame(height: 36)
.font(.system(size: 25, weight: .semibold))
ScrollView (Axis.Set.horizontal, showsIndicators: false){
HStack{
MenuTopicView(titleText: "Soup", foodImageName: "Soup")
MenuTopicView(titleText: "Fish", foodImageName: "Soup")
}
}.frame(height: 200)
Text("Main Course")
.frame(height: 36)
.font(.system(size: 25, weight: .semibold))
ScrollView(Axis.Set.horizontal) {
HStack {
MenuTopicView(titleText: "Steak", foodImageName: "Soup")
MenuTopicView(titleText: "Chicken", foodImageName: "Soup")
}
}
Text("Dessert")
.frame(height: 36)
.font(.system(size: 25, weight: .semibold))
ScrollView(Axis.Set.horizontal) {
HStack {
MenuTopicView(titleText: "Ice cream", foodImageName: "Soup")
MenuTopicView(titleText: "Pancakes", foodImageName: "Soup")
}
}
}
}
}
I googled this for a while, and I didn't succeed getting a answer to this question.
does anybody have any suggestions?
Thanks!
BSM
Try adding this modifier to your Image:
.renderingMode(.original)