首页 > 解决方案 > @Environment(\.presentationMode) var 模式:绑定混淆其他观点

问题描述

我有一个 MailView()

import Foundation
import SwiftUI
import UIKit
import MessageUI

struct MailView: UIViewControllerRepresentable {

@Environment(\.presentationMode) var presentation
@Binding var result: Result<MFMailComposeResult, Error>?

let newSubject : String
let newMsgBody : String

class Coordinator: NSObject, MFMailComposeViewControllerDelegate {

    @Binding var presentation: PresentationMode
    @Binding var result: Result<MFMailComposeResult, Error>?

    init(presentation: Binding<PresentationMode>,
         result: Binding<Result<MFMailComposeResult, Error>?>) {
        _presentation = presentation
        _result = result
    }

    func mailComposeController(_ controller: MFMailComposeViewController,
        didFinishWith result: MFMailComposeResult,
        error: Error?) {
        defer {
            $presentation.wrappedValue.dismiss()
        }
        guard error == nil else {
            self.result = .failure(error!)
            return
        }
        self.result = .success(result)
    }
}

func makeCoordinator() -> Coordinator {
    return Coordinator(presentation: presentation,
    result: $result)
}

func makeUIViewController(context: UIViewControllerRepresentableContext<MailView>) -> MFMailComposeViewController {
    let vc = MFMailComposeViewController()
    vc.mailComposeDelegate = context.coordinator
    vc.setToRecipients(["hello@email.co.uk"])
    vc.setSubject(newSubject)
    vc.setMessageBody(newMsgBody, isHTML: false)
    return vc
}

func updateUIViewController(_ uiViewController: MFMailComposeViewController,
    context: UIViewControllerRepresentableContext<MailView>) {
}

}

在我的 SettingViews 中,它的名称如下:

import SwiftUI
import URLImage
import UIKit
import MessageUI

struct SettingsView: View {

@Environment(\.presentationMode) var mode: Binding<PresentationMode>

@State private var showMailSheet = false
@State var result: Result<MFMailComposeResult, Error>? = nil

@State private var subject: String = ""
@State private var emailBody: String = ""

@EnvironmentObject var session: SessionStore

var body: some View {
    
    NavigationView {
        VStack(alignment: .leading) {
            List {
                Section(header: Text("Account")) {
                    NavigationLink(destination: ProfileView()) {
                        HStack {
                            Image(systemName: "person")
                                .resizable()
                                .frame(width: 20, height: 20)
                            VStack(alignment: .leading) {
                                Text("Edit Profile").font(.callout).fontWeight(.medium)
                            }
                        }.padding([.top,.bottom],5).padding(.trailing,10)
                    }
                    NavigationLink(destination: AccountView()) {
                        HStack {
                            Image(systemName: "doc")
                                .resizable()
                                .frame(width: 20, height: 20)
                            VStack(alignment: .leading) {
                                Text("View Account").font(.callout).fontWeight(.medium)
                            }
                        }.padding([.top,.bottom],5).padding(.trailing,10)
                    }
                    NavigationLink(destination: PreferencesView()) {
                        HStack {
                            Image(systemName: "slider.horizontal.3")
                                .resizable()
                                .frame(width: 20, height: 20)
                            VStack(alignment: .leading) {
                                Text("Preferences").font(.callout).fontWeight(.medium)
                            }
                        }.padding([.top,.bottom],5).padding(.trailing,10)
                    }
                }
                Section(header: Text("Support")) {
                    HStack {
                        Image(systemName: "bubble.right")
                            .resizable()
                            .frame(width: 20, height: 20)
                        VStack(alignment: .leading) {
                            Text("Contact Us").font(.callout).fontWeight(.medium)
                        }
                        Spacer()
                        Button(action: {
                            self.subject = "Hello"
                            self.sendEmail()
                        }) {
                            Text("Send").font(.system(size:12))
                        }
                    }
                    HStack {
                        Image(systemName: "ant")
                            .resizable()
                            .frame(width: 20, height: 20)
                        VStack(alignment: .leading) {
                            Text("Report An Issue").font(.callout).fontWeight(.medium)
                        }
                        Spacer()
                        Button(action: {
                            self.sendEmail()
                            self.subject = "Report Issue"
                            self.emailBody = "Im having the following issues:"
                        }) {
                            Text("Report").font(.system(size:12))
                        }
                    }
                }
                Section (header: Text("Legal")) {
                    HStack {
                        Image(systemName: "hand.raised")
                            .resizable()
                            .frame(width: 20, height: 20)
                        VStack(alignment: .leading) {
                            Text("Privacy Policy").font(.callout).fontWeight(.medium)
                        }
                        Spacer()
                        Button(action: {
                            if let url = URL(string: "http://www.mysite.co.uk/privacy.html") {
                               UIApplication.shared.open(url)
                           }
                        }) {
                            Text("View").font(.system(size:12))
                        }
                    }
                    HStack {
                        Image(systemName: "folder")
                            .resizable()
                            .frame(width: 20, height: 20)
                        VStack(alignment: .leading) {
                            Text("Terms and Conditions (EULA)").font(.callout).fontWeight(.medium)
                        }
                        Spacer()
                        Button(action: {
                            if let url = URL(string: "http://www.mysite.co.uk/eula.html") {
                               UIApplication.shared.open(url)
                           }
                        }) {
                            Text("View").font(.system(size:12))
                        }
                    }
                }
            }.listStyle(GroupedListStyle())
        }.navigationBarTitle("Settings", displayMode: .inline)
        .background(NavigationBarConfigurator())
    }.sheet(isPresented: $showMailSheet) {
        MailView(result: self.$result, newSubject: self.subject, newMsgBody: self.emailBody)
    }
}

func sendEmail() {
    if MFMailComposeViewController.canSendMail() {
        self.showMailSheet = true
    } else {
        print("Error sending mail")
    }
}
}

struct SettingsView_Previews: PreviewProvider {
    static var previews: some View {
    SettingsView()
    }
}

我的工作表看起来很好,一旦发送电子邮件,工作表就会按预期关闭,但以下导致问题:

@Environment(\.presentationMode) var mode: Binding<PresentationMode>

当我点击:

                    NavigationLink(destination: ProfileView()) {
                        HStack {
                            Image(systemName: "person")
                                .resizable()
                                .frame(width: 20, height: 20)
                            VStack(alignment: .leading) {
                                Text("Edit Profile").font(.callout).fontWeight(.medium)
                            }
                        }.padding([.top,.bottom],5).padding(.trailing,10)
                    }

有一个行动表:

.actionSheet(isPresented: self.$profileViewModel.showActionSheet){
        ActionSheet(title: Text("Add a profile image"), message: nil, buttons: [
            .default(Text("Camera"), action: {
                self.profileViewModel.showImagePicker = true
                self.sourceType = .camera
            }),
            .default(Text("Photo Library"), action: {
                self.profileViewModel.showImagePicker = true
                self.sourceType = .photoLibrary
            }),
            .cancel()
            
        ])
    }.sheet(isPresented: self.$profileViewModel.showImagePicker){
        imagePicker(image: self.$profileViewModel.upload_image, showImagePicker: self.$profileViewModel.showImagePicker, sourceType: self.sourceType)
    }

当我单击此按钮时,它会一直关闭该按钮,并且我无法单击显示的选项。

知道我如何才能@Environment(\.presentationMode) var mode: Binding<PresentationMode>唯一影响电子邮件的关闭吗?并且不干涉其他任何事情?

标签: swiftswiftui

解决方案


@Environment(\.presentationMode)应该用于您希望具有此自定义行为的最后一个子视图。

您声明 , 的任何子视图@Environment(\.presentationMode)也将继承相同的行为。

如果您仅在 中声明它MailView,它应该修复它。


推荐阅读