导航时会触发FetchRequest

时间:2020-04-18 06:51:06

标签: swift core-data swiftui

我有一个提取请求,该请求会在其视图被导航离开时触发。即使没有条目,它也会在列表视图中产生一堆空白单元格。我不确定是什么原因引起的,我需要它消失。我认为这可能与导航链接有关,但是当我尝试使用工作表时,图像选择器无法启动,因为从工作表进行导航实际上并不起作用。这是我的观点

import SwiftUI

struct LovedOnesView: View {
 @Environment(\.managedObjectContext) var lovedOnes
@FetchRequest(entity: Recipient.entity(), sortDescriptors: []) var lovedOne:FetchedResults<Recipient>
@State var stockImage = UIImage(imageLiteralResourceName: "WrittenPic")
@State var shouldNav: Bool = false

var body: some View {
    VStack {
        Button(action: {
            self.shouldNav.toggle()
        }) {
            Text("Add")
        }
       List {
        ForEach(lovedOne) { lovedOne in
            HStack {


                Person(name: lovedOne.name ?? "")

            }

           }
       }
        NavigationLink(destination: CreateLovedOnes().environment(\.managedObjectContext, self.lovedOnes), isActive: $shouldNav) {
            Text("")
        }

        }.navigationBarTitle(Text("Love Ones"))
}
}

struct LovedOnesView_Previews: PreviewProvider {
static var previews: some View {
    LovedOnesView()
}
}

extension Recipient: Identifiable {
}

struct Person: View {
var name: String = ""
var body: some View {
    HStack{
        Text(name)
    }
}


}

第二个视图如下:

import FirebaseAuth
import FirebaseDatabase
import FirebaseStorage

struct CreateLovedOnes: View {
     @Environment(\.managedObjectContext) var lovedOne
    @Environment(\.presentationMode) var presentationMode
    @State private var showSheet: Bool = false
    @State private var showImagePicker: Bool = false
    @State private var sourceType: UIImagePickerController.SourceType = .camera
    @State private var image: UIImage?
    @State var name: String = ""
    @State var relation: String = ""
    @State var birthday: Date = Date()
    @State var phoneNumber: String = ""
    @State var email: String = ""
    @State var admin: String = ""
    @State  var adminEmail: String = ""
    @State var shouldNavigate: Bool = false
    @State private var didSave: Bool = false
    @State var hideMarriage: Bool = true
    @State var marriageDate: Date = Date()
    @State var pickedIndex = 0
    @State var showingAlert: Bool = false
    var relations = Relations().relationArray
    var disableForm: Bool {
        name.isEmpty || phoneNumber.isEmpty || email.isEmpty || admin.isEmpty || admin.isEmpty || image == nil
    }
    var body: some View {
        let receiver = Recipient(context: self.lovedOne)
        return VStack {
            Form {
                HStack {
                    Text("Loved One's Name").padding(.trailing)
                    TextField("John Smith", text: $name)
                }
                VStack{
                    Picker(selection: $pickedIndex, label: Text("Relation")) {
                        ForEach(0 ..< relations.count) {
                            Text(self.relations[$0]).tag($0)
                        }
                    }


            }


                DatePicker("Loved One's Birthday", selection: $birthday, displayedComponents: .date)




                    if relations[pickedIndex] == "Husband" || relations[pickedIndex] == "Wife" {
                        DatePicker("Marraige Date", selection: $marriageDate, displayedComponents: .date)

                }



                HStack {
                    Text("Loved One's Number").padding(.trailing)
                    TextField("1-916-123-4567", text: $phoneNumber)
                }
                HStack {
                    Text("Loved One's Email").padding(.trailing)
                    TextField("this@email.com", text: $email)
                }
                HStack {
                    Text("Name of Admin").padding(.trailing)
                    TextField("John Johnson", text: $admin)
                }
                HStack {
                    Text("Admid Email").padding(.trailing)
                    TextField("admin@email.com", text: $adminEmail)
                }
                HStack {
                    Text("Choose an image")
                    Spacer()
                    Image(uiImage: image ?? UIImage(named:"WrittenPic")!).resizable().scaledToFit().frame(width: 50, height: 50)
                }.onTapGesture {
                    self.showSheet.toggle()
                }.actionSheet(isPresented: $showSheet) {
                    ActionSheet(title: Text("Select Photo"), message: Text("Choose"), buttons: [.default(Text("Photo Library")){
                        self.showImagePicker = true
                        self.sourceType = .photoLibrary
                        },
                                                                                    .default(Text("Camera")){
                                                               self.showImagePicker = true
                                                                                        self.sourceType = .camera
                        }, .cancel()])
                }
            }.sheet(isPresented: $showImagePicker) {
                ImagePicker(image: self.$image, isShown: self.$showImagePicker, sourceType: self.sourceType)
            }

            VStack {

                        NavigationLink(destination: MainView().navigationBarBackButtonHidden(true),isActive: self.$shouldNavigate) {
                           Text("")

                        }

                        Button(action: {
                            receiver.id = UUID()
                            receiver.name = self.name
                            receiver.email = self.email
                            receiver.phoneNumber = self.phoneNumber
                            receiver.age = self.birthday
                            guard let image = self.image else {
                                return
                            }
                            guard let imageData = image.jpegData(compressionQuality: 0.01) else {
                                return
                            }
                            let relationTo = self.relations[self.pickedIndex]
                            receiver.avatar = imageData
                            receiver.relation = relationTo

                            if relationTo == "Husband" || relationTo == "Wife" {
                                receiver.married = true
                                receiver.mariageDate = self.marriageDate
                            }
                            else {
                                receiver.married = false
                            }

                            receiver.adminName = self.admin
                            receiver.adminEmail = self.adminEmail


                         do {
                             try self.lovedOne.save()
                             self.didSave.toggle()
                             if self.didSave {
                                 print("I saved")

                             }
                         } catch {
                             print("Could not save \(error)")
                         }

                            if self.didSave {
                                self.saveToFirebase(recipientName: self.name, avatar: image, birthday: self.birthday, email: self.email, relation: self.relation, isMarried: self.hideMarriage , marriageDate: self.marriageDate, adminName: self.admin, adminEmail: self.adminEmail, lovedOneNumber: self.phoneNumber)
                            }


                        }) {
                         Text("Save Loved One")
                        }.disabled(disableForm)
                         .frame(minWidth: 0, maxWidth: 300, minHeight: 0, maxHeight: 50)
                         .font(.largeTitle).foregroundColor(.white).background(LinearGradient(gradient: Gradient(colors: [Color.themeColor, Color.white]), startPoint: /*@START_MENU_TOKEN@*/.leading/*@END_MENU_TOKEN@*/, endPoint: /*@START_MENU_TOKEN@*/.trailing/*@END_MENU_TOKEN@*/)).opacity(disableForm ? 0 : 1)
            }.alert(isPresented: $showingAlert) {
                Alert(title: Text("Same Name Error"), message: Text("You've already added this person please change the name"), dismissButton: .default(Text("Got it!")))


            }

        }.navigationBarTitle("Loved One Creation")


    }

    func saveToFirebase(recipientName: String, avatar: UIImage, birthday: Date, email: String, relation: String, isMarried: Bool, marriageDate: Date, adminName: String, adminEmail: String, lovedOneNumber:String){
        guard let userID = Auth.auth().currentUser?.uid else {
            return
        }

        Database.database().reference().child("users").child(userID).child(recipientName).observeSingleEvent(of: .value) { (snapshot) in
            if snapshot.exists() {
                self.showingAlert = true

            } else {
                self.uploadMedia(avatar: avatar, name: recipientName, userID: userID, completion: { (url) in
                    guard let url = url else {return}
                    let dateFormat = DateFormatter()
                    dateFormat.dateFormat = "MM-dd-yyyy"
                    let dateString = dateFormat.string(from: birthday)
                    let marDateString = dateFormat.string(from: marriageDate)

                    Database.database().reference().child("users").child(userID).child("lovedOnes").child(recipientName).child("info").updateChildValues(["name" : recipientName,"avatar": url,"birthday": dateString,"email": email, "relation": relation,"married": isMarried, "admin": adminName, "adminEmail": adminEmail,"phoneNumber": lovedOneNumber, "marriageDate":marDateString])


                })
            }

         self.presentationMode.wrappedValue.dismiss()

    }

    }
    func uploadMedia(avatar: UIImage, name:String,userID: String,completion: @escaping (_ url: String?) -> Void) {
           let storageRef = Storage.storage().reference().child(userID).child(name).child("avatar")

           let jpegRep = avatar.jpegData(compressionQuality: 0.30)!
           let imagetoLoad = UIImage(data: jpegRep)

           if let uploadData = imagetoLoad?.pngData() {
               storageRef.putData(uploadData, metadata: nil) { (metadata, error) in
                   if error != nil {
                       print("error")
                       completion(nil)
                   } else {
                       storageRef.downloadURL(completion: { (url, error) in
                           if error == nil {
                               completion(url?.absoluteString)
                           }
                       })

                   }
               }
           }

       }
}

struct CreateLovedOnes_Previews: PreviewProvider {
    static var previews: some View {
        CreateLovedOnes()
    }
}

1 个答案:

答案 0 :(得分:0)

我发现他们有问题。 let receiver = Recipient(context: self.lovedOne)应该在保存信息的按钮代码中。这样就无需返回VStack。我认为我以前的方法出于某种奇怪的原因引起了List的震撼。