Map become gray when keyboard appear swiftui - swiftui

I'm experience a strange behavior on my app view, as you can see from the attached gif when the keyboard appear the map will become gray.
What can be the issue and possible solution.
here my view code.
struct CreateYourFarm: View {
#ObservedObject var am : AppManager
#State var farmName = ""
#State var adress = "Via guglielmo 3"
#State var nameOwn = ""
#State var cognomeOwn = ""
#State var farmType : FarmType = .Mixed
#Binding var isFirstStart : Bool
#Environment(\.colorScheme) var colorScheme
#State var openMap = false
var body: some View {
GeometryReader { geo in
VStack{
ZStack{
Rectangle()
.foregroundColor(Color("TopBar"))
.frame(width: nil, height: geo.size.height/9, alignment: .center)
HStack{
Image("farm")
.resizable()
.frame(width: 40, height: 40, alignment: .center)
Text("New Farm")
.font(.title)
.foregroundColor(.white)
}
}.edgesIgnoringSafeArea(.top)
TextField("Name of Your Farm", text: $farmName)
.modifier(customViewModifier(roundedCornes: 6, startColor: .green, endColor: .purple, textColor: colorScheme == .dark ? .white : .black))
.disableAutocorrection(true)
.padding()
TextField("Farm Address", text: $adress)
.modifier(customViewModifier(roundedCornes: 6, startColor: .purple, endColor: .green, textColor: colorScheme == .dark ? .white : .black))
.disableAutocorrection(true)
.padding()
TextField("Name of the owner", text: $nameOwn)
.modifier(customViewModifier(roundedCornes: 6, startColor: .green, endColor: .purple, textColor: colorScheme == .dark ? .white : .black))
.disableAutocorrection(true)
.padding()
TextField("Surname of the owner", text: $cognomeOwn)
.modifier(customViewModifier(roundedCornes: 6, startColor: .purple, endColor: .green, textColor: colorScheme == .dark ? .white : .black))
.disableAutocorrection(true)
.padding()
Button {
am.reqLocOneTime()
openMap.toggle()
} label: {
HStack{
Text("Your Farm Location")
Image(systemName: "location.fill")
.foregroundColor(.blue)
}
}
Button {
am.createFarm(farmName: farmName, address: adress, nomeOwn: nameOwn, cognomeOwn: cognomeOwn, field: nil, farmType: farmType) {
// to be fix completition
isFirstStart.toggle()
}
} label: {
Text("SAVE")
.modifier(customViewModifier(roundedCornes: 6, startColor: .purple, endColor: .green, textColor: colorScheme == .dark ? .white : .black))
}
if openMap {
MapView(am: am)
.padding(.horizontal)
}
Spacer()
}
}
}
}
the MapView is a simple UIViewRepresentable
import Foundation
import MapKit
import SwiftUI
struct MapView: UIViewRepresentable {
var am : AppManager
func makeUIView(context: Context) -> some UIView {
return am.map
}
func updateUIView(_ uiView: UIViewType, context: Context) {
}
}

If your app's minimum deployment target is iOS 14 then use below code :
Use Map() intend of UIViewRepresentable view
struct CreateYourFarm: View {
#ObservedObject var am : AppManager
#State var farmName = ""
#State var adress = "Via guglielmo 3"
#State var nameOwn = ""
#State var cognomeOwn = ""
#State var farmType : FarmType = .Mixed
#Binding var isFirstStart : Bool
#Environment(\.colorScheme) var colorScheme
#State var openMap = false
#State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5))
var body: some View {
GeometryReader { geo in
VStack{
ZStack{
Rectangle()
.foregroundColor(Color("TopBar"))
.frame(width: nil, height: geo.size.height/9, alignment: .center)
HStack{
Image("farm")
.resizable()
.frame(width: 40, height: 40, alignment: .center)
Text("New Farm")
.font(.title)
.foregroundColor(.white)
}
}.edgesIgnoringSafeArea(.top)
TextField("Name of Your Farm", text: $farmName)
.modifier(customViewModifier(roundedCornes: 6, startColor: .green, endColor: .purple, textColor: colorScheme == .dark ? .white : .black))
.disableAutocorrection(true)
.padding()
TextField("Farm Address", text: $adress)
.modifier(customViewModifier(roundedCornes: 6, startColor: .purple, endColor: .green, textColor: colorScheme == .dark ? .white : .black))
.disableAutocorrection(true)
.padding()
TextField("Name of the owner", text: $nameOwn)
.modifier(customViewModifier(roundedCornes: 6, startColor: .green, endColor: .purple, textColor: colorScheme == .dark ? .white : .black))
.disableAutocorrection(true)
.padding()
TextField("Surname of the owner", text: $cognomeOwn)
.modifier(customViewModifier(roundedCornes: 6, startColor: .purple, endColor: .green, textColor: colorScheme == .dark ? .white : .black))
.disableAutocorrection(true)
.padding()
Button {
am.reqLocOneTime()
openMap.toggle()
} label: {
HStack{
Text("Your Farm Location")
Image(systemName: "location.fill")
.foregroundColor(.blue)
}
}
Button {
am.createFarm(farmName: farmName, address: adress, nomeOwn: nameOwn, cognomeOwn: cognomeOwn, field: nil, farmType: farmType) {
// to be fix completition
isFirstStart.toggle()
}
} label: {
Text("SAVE")
.modifier(customViewModifier(roundedCornes: 6, startColor: .purple, endColor: .green, textColor: colorScheme == .dark ? .white : .black))
}
if openMap {
// MapView(am: am)
// .padding(.horizontal)
Map(coordinateRegion: $region) //Add this and you can customise according your functionally.
}
Spacer()
}
}
}
}
And if your app's minimum deployment target is lower than iOS 14 then replace your code in UIViewRepresentable view:
struct MapView: UIViewRepresentable {
func makeUIView(context: Context) -> MKMapView {
MKMapView()
}
func updateUIView(_ uiView: MKMapView, context: Context) {
}
}
For more information please refer below link for MKMapView()
https://www.morningswiftui.com/2019-07-31-build-mapview-app-with-swiftui/

Related

SwiftUI Custom textfield with onEditingChanged closure

News to SwiftUI so please bare with me :) I have a custom textfield setup as a struct in a separate file.
I would like to use onEditingChanged in my content view (the closure would be perfect), is this possible? I have tried with a binding but it isn't a great solution.
import Foundation
import SwiftUI
struct EntryField: View {
var sfSymbolName: String
var placeHolder: String
var prompt: String
#Binding var field: String
var uptodate:Bool = false
var showActivityIndicator:Bool = false
#State var checkMarkOpacity = 0.9
#Binding var editingChanged: Bool
var body: some View {
VStack(alignment: .leading) {
HStack {
Image(systemName: sfSymbolName)
.foregroundColor(.gray)
.font(.custom("SF Pro Light", size: 60))
TextField(placeHolder, text: $field, onEditingChanged: { editing in
editingChanged = editing
}).autocapitalization(.none)
.keyboardType(.decimalPad)
.font(.custom("SF Pro Light", size: 60))
.placeholder(when: field.isEmpty) {
Text("0,00")
.foregroundColor(.white)
.font(.custom("SF Pro Light", size: 60))
}
Image(systemName: "checkmark").opacity(uptodate ? 1 : 0)
.opacity(checkMarkOpacity)
.foregroundColor(.white)
.font(.custom("SF Pro Light", size: 40))
.onAppear(perform: {
withAnimation(.easeIn(duration: 3.0).delay(2.0) ) {
checkMarkOpacity = 0
}
})
.overlay(
ProgressView()
.opacity(showActivityIndicator ? 1 : 0)
//.progressViewStyle(ShadowProgressViewStyle())
.progressViewStyle(RingProgressViewStyle(
configuration: .init(
trackColor: .blue,
fillColor: .white,
lineWidth: 6)))
)
}
.padding(8)
.background(Color(UIColor.secondarySystemBackground))
.clipShape(RoundedRectangle(cornerRadius:10))
Text(prompt)
.fixedSize(horizontal: false, vertical: true)
.font(.caption)
}
}
}
and in my content view I have:
#State private var editingChanged: Bool = false
EntryField(sfSymbolName: "eurosign.square", placeHolder: "", prompt: "Litre Price", field: $closestLitrePrice, uptodate: uptodate, showActivityIndicator: showActivityIndicator, editingChanged: $editingChanged)
thank you
If you don't need it internally then you can pass closure directly from construction to TextField, like
let editingChanged: (Bool) -> Void // << here !!
var body: some View {
VStack(alignment: .leading) {
HStack {
Image(systemName: sfSymbolName)
.foregroundColor(.gray)
.font(.custom("SF Pro Light", size: 60))
TextField(placeHolder, text: $field,
onEditingChanged: editingChanged) // << here !!
.autocapitalization(.none)

How to convert value of type 'ImagePickerView' to expected argument type 'String' on Swiftui?

I am trying to build an app where a user can insert the name of the movie and can add an image directly into the app from the photo library (using UIKit. Thankfully the part where the user can insert the text and image from the photo library works. My issue is transferring that data from the .sheet to a list. The info in the TextFields that the user inserts works fine and is shown in the list, but the image doesn't show. I keep getting the error "Cannot convert value of type 'ImagePickerView' to expected argument type 'String'". I don't know how to fix this issue. This issue comes in the ContentView.swift file, in the MovieRow struct when I try to insert the Image(). Any help would be appreciated. Thanks in advance.
Below is my ContentView file. d
// ContentView.swift
// MovieListEditttt
//
import SwiftUI
struct ContentView: View {
#State var movieAdd: [MovieAdd] = []
#State private var newMovieName: String = ""
#State private var showNewMovie = false
#State private var newMovieImage = UIImage()
var body: some View {
ZStack {
VStack {
HStack {
Text("Movies Watched Ratings")
.font(.system(size: 40, weight: .black, design: .rounded
))
Spacer()
Button(action: {
self.showNewMovie = true
}) {
Image(systemName: "plus.circle.fill")
.font(.largeTitle)
.foregroundColor(.yellow)
}
}
List{
ForEach(movieAdd) {movie in
movieRow(movieAdd: movie)
}
}
}
if showNewMovie {
BlankView(bGColor: .black)
.opacity(0.5)
.onTapGesture {
self.showNewMovie = false
}
NewMovieView(isShow: $showNewMovie, addMovie: $movieAdd, newMovieName: newMovieName)
.transition(.move(edge: .bottom))
.animation(.interpolatingSpring(stiffness: 200.0, damping: 25.0, initialVelocity: 10.0))
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct movieRow: View {
#ObservedObject var movieAdd : MovieAdd
var body: some View {
VStack {
Image(movieAdd.movieImage)
.resizable()
.frame(width: 100, height: 100)
Text(movieAdd.movieName)
}
}
}
struct BlankView: View {
var bGColor: Color
var body: some View {
VStack {
Spacer()
}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
.background(bGColor)
.edgesIgnoringSafeArea(.all)
}
}
Here is my MovieAdd.swift file where I initialize all variables that will be put inside the list.
import Foundation
class MovieAdd: ObservableObject, Identifiable {
var id = UUID()
#Published var movieName = ""
#Published var isComplete : Bool = false
#Published var movieImage : ImagePickerView
init(movieName: String, isComplete: Bool = false, movieImage: ImagePickerView) {
self.movieName = movieName
self.isComplete = isComplete
self.movieImage = movieImage
}
}
And here is my NewMovieView.swift file where the user will be able to insert their Movie information into a TextField, and insert an image from their Photos library. Here is also where I used UIKit.
import SwiftUI
struct NewMovieView: View {
#Binding var isShow: Bool
#Binding var addMovie: [MovieAdd]
#State var newMovieName: String = ""
#State var isShowingImagePicker = false
#State var imageInBlackBox = UIImage()
var body: some View {
ScrollView {
VStack {
VStack (alignment: .leading) {
HStack {
Text("Add a New Movie")
.font(.system(.title, design: .rounded))
.bold()
}
ZStack {
VStack {
HStack (alignment: .center){
Spacer()
Image(uiImage: imageInBlackBox)
.resizable()
.scaledToFill()
.frame(width: 200, height: 200)
.border(Color.black, width: 3)
.clipped()
Spacer()
}
VStack {
Spacer()
Button(action: {
self.isShowingImagePicker.toggle()
}, label: {
Text("Select Image")
.font(.system(size: 15))
})
.sheet(isPresented: $isShowingImagePicker, content: { ImagePickerView(isPresented: $isShowingImagePicker, selectedImage: $imageInBlackBox)})
}
}
}
Group {
TextField("Enter the movie name", text: $newMovieName)
.padding()
.background(Color(.systemGray6))
}
Button(action: {
if self.newMovieName.trimmingCharacters(in: .whitespaces) == "" {
return
}
if self.isShowingImagePicker {
return
}
self.isShow = false
self.addMovieTask(movieName: self.newMovieName, movieImage: ImagePickerView(isPresented: $isShowingImagePicker, selectedImage: $imageInBlackBox))
}) {
Text("Save")
.font(.system(.headline, design: .rounded))
.foregroundColor(.red)
}
}
}
.background(Color.white)
}
}
private func addMovieTask(movieName: String, isComplete: Bool = false, movieImage: ImagePickerView) {
let task = MovieAdd(movieName: movieName, movieImage: movieImage)
addMovie.append(task)
}
}
struct NewMovieView_Previews: PreviewProvider {
static var previews: some View {
NewMovieView(isShow: .constant(true), addMovie: .constant([]), newMovieName: "", isShowingImagePicker: true)
}
}
struct ImagePickerView: UIViewControllerRepresentable {
#Binding var isPresented: Bool
#Binding var selectedImage: UIImage
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePickerView>) -> some UIViewController {
let controller = UIImagePickerController()
controller.delegate = context.coordinator
return controller
}
func makeCoordinator() -> ImagePickerView.Coordinator {
return Coordinator(parent: self)
}
class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
let parent: ImagePickerView
init(parent: ImagePickerView){
self.parent = parent
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let selectedImage = info[.originalImage] as? UIImage {
print(selectedImage)
self.parent.selectedImage = selectedImage
}
self.parent.isPresented = false
}
}
func updateUIViewController(_ uiViewController: ImagePickerView.UIViewControllerType, context: UIViewControllerRepresentableContext<ImagePickerView>) {
//
}
}
Change #1:
Your model should usually be a struct unless there's a really compelling reason to make it an ObservableObject. In this case, struct works very well:
struct MovieAdd: Identifiable {
var id = UUID()
var movieName = ""
var isComplete : Bool = false
var movieImage : UIImage
}
Note that I've made movieImage a UIImage.
Change #2:
Use Image(uiImage:) in MovieRow. The MovieAdd property no longer needs #ObservableObject since it's just a struct.
Also notice that types in Swift should be capitalized to follow convention).
struct MovieRow: View {
var movieAdd : MovieAdd
var body: some View {
VStack {
Image(uiImage: movieAdd.movieImage)
.resizable()
.frame(width: 100, height: 100)
Text(movieAdd.movieName)
}
}
}
Complete code in case I forgot to mention any other changes:
struct ContentView: View {
#State var movieAdd: [MovieAdd] = []
#State private var newMovieName: String = ""
#State private var showNewMovie = false
#State private var newMovieImage = UIImage()
var body: some View {
ZStack {
VStack {
HStack {
Text("Movies Watched Ratings")
.font(.system(size: 40, weight: .black, design: .rounded
))
Spacer()
Button(action: {
self.showNewMovie = true
}) {
Image(systemName: "plus.circle.fill")
.font(.largeTitle)
.foregroundColor(.yellow)
}
}
List{
ForEach(movieAdd) {movie in
MovieRow(movieAdd: movie)
}
}
}
if showNewMovie {
BlankView(bGColor: .black)
.opacity(0.5)
.onTapGesture {
self.showNewMovie = false
}
NewMovieView(isShow: $showNewMovie, addMovie: $movieAdd, newMovieName: newMovieName)
.transition(.move(edge: .bottom))
.animation(.interpolatingSpring(stiffness: 200.0, damping: 25.0, initialVelocity: 10.0))
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct MovieRow: View {
var movieAdd : MovieAdd
var body: some View {
VStack {
Image(uiImage: movieAdd.movieImage)
.resizable()
.frame(width: 100, height: 100)
Text(movieAdd.movieName)
}
}
}
struct BlankView: View {
var bGColor: Color
var body: some View {
VStack {
Spacer()
}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
.background(bGColor)
.edgesIgnoringSafeArea(.all)
}
}
struct MovieAdd: Identifiable {
var id = UUID()
var movieName = ""
var isComplete : Bool = false
var movieImage : UIImage
}
struct NewMovieView: View {
#Binding var isShow: Bool
#Binding var addMovie: [MovieAdd]
#State var newMovieName: String = ""
#State var isShowingImagePicker = false
#State var imageInBlackBox = UIImage()
var body: some View {
ScrollView {
VStack {
VStack (alignment: .leading) {
HStack {
Text("Add a New Movie")
.font(.system(.title, design: .rounded))
.bold()
}
ZStack {
VStack {
HStack (alignment: .center){
Spacer()
Image(uiImage: imageInBlackBox)
.resizable()
.scaledToFill()
.frame(width: 200, height: 200)
.border(Color.black, width: 3)
.clipped()
Spacer()
}
VStack {
Spacer()
Button(action: {
self.isShowingImagePicker.toggle()
}, label: {
Text("Select Image")
.font(.system(size: 15))
})
.sheet(isPresented: $isShowingImagePicker, content: { ImagePickerView(isPresented: $isShowingImagePicker, selectedImage: $imageInBlackBox)})
}
}
}
Group {
TextField("Enter the movie name", text: $newMovieName)
.padding()
.background(Color(.systemGray6))
}
Button(action: {
if self.newMovieName.trimmingCharacters(in: .whitespaces) == "" {
return
}
if self.isShowingImagePicker {
return
}
self.isShow = false
self.addMovieTask(movieName: self.newMovieName, movieImage: ImagePickerView(isPresented: $isShowingImagePicker, selectedImage: $imageInBlackBox))
}) {
Text("Save")
.font(.system(.headline, design: .rounded))
.foregroundColor(.red)
}
}
}
.background(Color.white)
}
}
private func addMovieTask(movieName: String, isComplete: Bool = false, movieImage: ImagePickerView) {
let task = MovieAdd(movieName: movieName, movieImage: movieImage.selectedImage)
addMovie.append(task)
}
}
struct NewMovieView_Previews: PreviewProvider {
static var previews: some View {
NewMovieView(isShow: .constant(true), addMovie: .constant([]), newMovieName: "", isShowingImagePicker: true)
}
}
struct ImagePickerView: UIViewControllerRepresentable {
#Binding var isPresented: Bool
#Binding var selectedImage: UIImage
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePickerView>) -> some UIViewController {
let controller = UIImagePickerController()
controller.delegate = context.coordinator
return controller
}
func makeCoordinator() -> ImagePickerView.Coordinator {
return Coordinator(parent: self)
}
class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
let parent: ImagePickerView
init(parent: ImagePickerView){
self.parent = parent
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let selectedImage = info[.originalImage] as? UIImage {
print(selectedImage)
self.parent.selectedImage = selectedImage
}
self.parent.isPresented = false
}
}
func updateUIViewController(_ uiViewController: ImagePickerView.UIViewControllerType, context: UIViewControllerRepresentableContext<ImagePickerView>) {
//
}
}

List ForEach Problem SwiftUI - ListCells are not visible with List

I realized that when I use nested List - ForEach, I can not see anything inside these codes. But when I remove List I can see all elements inside the view. Unfortunately, without using List I can not use .onDelete and that is a problem.
struct ListsInfoView: View {
#Environment(\.managedObjectContext) private var viewContext
#FetchRequest(entity:CDListModel.entity(),
sortDescriptors: [
NSSortDescriptor(
keyPath:\CDListModel.title,
ascending: true )
]
)var lists: FetchedResults<CDListModel>
#State var isListSelected = false
#State var selectedList : CDListModel!
var body: some View {
List{
ForEach(lists) { list in
Button(action: {
self.selectedList = list
self.isListSelected.toggle()
}) {
ListCell(list: list)
}
}
.onDelete(perform: deleteList)
}
.listStyle(PlainListStyle())
.fullScreenCover(isPresented: $isListSelected) {
ListDetailView(selectedList: $selectedList)
.environment(\.managedObjectContext, viewContext)
}
}
func deleteList(at offsets: IndexSet) {
viewContext.delete(lists[offsets.first!])
PersistenceController.shared.saveContext()
}
}
Like above, I do not see any ListCell but when I remove List { } it is all perfect. Why is that?
My ListCell
struct ListCell: View {
#ObservedObject var list : CDListModel
var body: some View {
HStack{
Image(systemName: "folder")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 30, height: 30, alignment: .center)
.foregroundColor(.yellow)
Text(list.title ?? "")
.foregroundColor(.black)
.font(.system(size: 20, weight: .regular, design: .rounded))
.padding(.leading,10)
Spacer()
Text(String(list.notes?.count ?? 0))
.foregroundColor(.gray)
Image(systemName: "chevron.right")
.foregroundColor(.gray)
}
.padding(.horizontal)
}
}
This is my MainView that I call ListsView. Inside of the ListView I am calling ListInfoView if isShowTapped
struct MainView: View {
#Environment(\.managedObjectContext) private var viewContext
#State var searchText = ""
#State var newFolderName = ""
#State var isAddList : Bool = false
#State var isAddNote: Bool = false
var body: some View {
ZStack{
Color(.white)
.edgesIgnoringSafeArea(.all)
NavigationView{
VStack(alignment: .leading){
ScrollView{
SearchBar(text: $searchText)
.environment(\.managedObjectContext, viewContext)
ListsView()
.environment(\.managedObjectContext, viewContext)
ListView
struct ListsView: View {
#Environment(\.managedObjectContext) private var viewContext
#State var isShowTapped: Bool = false
#State var selectedIndex : Int = 0
var body: some View {
VStack {
Spacer()
HStack{
Text("On My iPhone")
.font(.system(size: 20, weight: .semibold, design: .rounded))
Spacer()
Button(action: {
withAnimation{
self.isShowTapped.toggle()
print("slider button tapped")
}
}, label: {
Image(systemName:isShowTapped ? "chevron.down" : "chevron.right")
.foregroundColor(.black)
})
}
.padding(.horizontal)
if isShowTapped {
ListsInfoView()
.environment(\.managedObjectContext, viewContext)
.transition(.scale)
} else {}
Spacer()
}
}
}

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 to show another view when user selects image from the photo library

My problem is that I can't show selected image in another view because I can't set my variable selected to true.
My variables:
#State private var selectedImage: UIImage?
#State private var isImagePickerDisplay = false
#State private var selected: Bool = false
Step 1 - I present ImagePicker for the user (works fine):
.sheet(isPresented: self.$isImagePickerDisplay) {
ImagePickerView(selectedImage: self.$selectedImage, sourceType: .photoLibrary)
}
Step 2 - I can't find the right way to know when the user actually selected the image. I tried to do like this:
if selectedImage != nil {
selected = true
}
But I get error:
Type '()' cannot conform to 'View'; only struct/enum/class types can conform to protocols
Step 3 - Then my plan was to show another view if user actually selected image from photo library:
.fullScreenCover(isPresented: $selected) {
EditView(selectedImage: $selectedImage)
}
Please, keep in mind that I'm new in SwiftUI. I just finished tutorials and now I'm trying to develop a project on my own.
EDIT (added my entire ContentView()):
struct ContentView: View {
#State private var selectedImage: UIImage?
#State private var isImagePickerDisplay = false
#State private var selected: Bool = false
var body: some View {
Button(action: {
self.isImagePickerDisplay.toggle()
}) {
Image(systemName: "plus")
.renderingMode(.original)
.font(.system(size: 16, weight: .medium))
.aspectRatio(contentMode: .fit)
.frame(width: 36, height: 36)
.background(Color(.white))
.clipShape(Circle())
.shadow(radius: 10)
}.sheet(isPresented: self.$isImagePickerDisplay) {
ImagePickerView(selectedImage: self.$selectedImage, sourceType: .photoLibrary)
}
if selectedImage != nil {
selected = true
}
.fullScreenCover(isPresented: $selected) {
EditView(selectedImage: $selectedImage)
}
}
}
Probably you wanted this
struct DFContentView: View {
#State private var selectedImage: UIImage?
#State private var isImagePickerDisplay = false
#State private var selected: Bool = false
var body: some View {
VStack {
Button(action: {
self.isImagePickerDisplay.toggle()
}) {
Image(systemName: "plus")
.renderingMode(.original)
.font(.system(size: 16, weight: .medium))
.aspectRatio(contentMode: .fit)
.frame(width: 36, height: 36)
.background(Color(.white))
.clipShape(Circle())
.shadow(radius: 10)
}
.sheet(isPresented: self.$isImagePickerDisplay, onDismiss: { // << here !!
self.selected = selectedImage != nil
}) {
ImagePickerView(selectedImage: self.$selectedImage, sourceType: .photoLibrary)
}
EmptyView()
.fullScreenCover(isPresented: $selected) {
EditView(selectedImage: $selectedImage)
}
}
}
}
Updated: Thanks to #RajaKishan, about iOS 14.2 - updated with separated .sheet and .fullScreenCover into different views. Tested and worked.
Possible solution
struct ContentView: View {
private enum SheetType {
case pickImage, showImage
}
#State private var selectedImage: UIImage?
#State private var selected: Bool = false
#State private var currentSheetType: SheetType = .pickImage
var body: some View {
Button(action: {
self.selected.toggle()
self.currentSheetType = .pickImage
}) {
Image(systemName: "plus")
.renderingMode(.original)
.font(.system(size: 16, weight: .medium))
.aspectRatio(contentMode: .fit)
.frame(width: 36, height: 36)
.background(Color(.white))
.clipShape(Circle())
.shadow(radius: 10)
}
.sheet(isPresented: self.$selected) {
if currentSheetType == .pickImage {
if selectedImage != nil {
self.selected.toggle()
self.currentSheetType = .showImage
}
}
} content: {
if currentSheetType == .pickImage {
ImagePickerView(selectedImage: self.$selectedImage, sourceType: .photoLibrary)
} else if currentSheetType == .showImage {
EditView(selectedImage: $selectedImage)
}
}
}
}