我有一个提取请求,该请求会在其视图被导航离开时触发。即使没有条目,它也会在列表视图中产生一堆空白单元格。我不确定是什么原因引起的,我需要它消失。我认为这可能与导航链接有关,但是当我尝试使用工作表时,图像选择器无法启动,因为从工作表进行导航实际上并不起作用。这是我的观点
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()
}
}
答案 0 :(得分:0)
我发现他们有问题。 let receiver = Recipient(context: self.lovedOne)
应该在保存信息的按钮代码中。这样就无需返回VStack。我认为我以前的方法出于某种奇怪的原因引起了List的震撼。