Swiftui 向每个操作表按钮添加不同的修改器

Swiftui 向每个操作表按钮添加不同的修改器,swiftui,imagepicker,swiftui-actionsheet,Swiftui,Imagepicker,Swiftui Actionsheet,这可能是一个很简单的问题,但我找不到答案 我正在尝试构建一个包含两个按钮(以及一个取消按钮)的操作表: 按钮“从库中选择”打开一个图像选择器,其中源类型设置为.photoLibrary 按钮“拍摄新照片”打开一个图像采集器,其中源类型设置为.camera 我已经成功制作了ActionSheet和imagePicker,但无法确定在何处添加修改器来告诉每个按钮应该使用哪个sourceType。我设法将它添加到动作表之外的一个sheet()修改器中的一个普通按钮中,如下所示,一切正常: Button

这可能是一个很简单的问题,但我找不到答案

我正在尝试构建一个包含两个按钮(以及一个取消按钮)的操作表:

  • 按钮“从库中选择”打开一个
    图像选择器
    ,其中
    源类型
    设置为
    .photoLibrary
  • 按钮“拍摄新照片”打开一个
    图像采集器
    ,其中
    源类型
    设置为
    .camera
  • 我已经成功制作了ActionSheet和imagePicker,但无法确定在何处添加修改器来告诉每个按钮应该使用哪个sourceType。我设法将它添加到动作表之外的一个
    sheet()
    修改器中的一个普通按钮中,如下所示,一切正常:

    Button(action: {
                                self.show.toggle()
                            })
                            {Text("Take a new picture")}
                            .sheet(isPresented: self.$show, content: {
                                ImagePicker(sourceType: .camera, show: self.$show, image: self.$imageTemp)
                            })
    
    但是,我看不出在行动表中的什么地方包含这些信息。非常感谢任何能提供帮助的人,我希望这一点是明确的:-)

    这是我的密码:

    struct ContentView: View {
    
    @State private var showingActionSheet = false
    @State var imageTemp : Data = (UIImage(systemName: "photo.on.rectangle.angled")?.jpegData(compressionQuality: 1))!
    
    var body: some View {
            NavigationView {
    Image(uiImage: UIImage(data: imageTemp)!)
                            .onTapGesture {
                                            self.showingActionSheet = true
                                        }
                            .actionSheet(isPresented: $showingActionSheet) {
                                ActionSheet(title: Text("Image selector"), message: Text("Select an image"), buttons: [
                                    .default(Text("Select from Gallery"))
                                        {
                                            self.show.toggle()
                                        },
                                    .default(Text("Take new picture")) {
                                        self.show.toggle()
                                    },
                                    .cancel()
                                ]
                                )
                            }
                     }
             }
    }
    
    为了以防万一,这里是我的imagePicker的代码,尽管我认为这可能不是必需的

    struct ImagePicker: UIViewControllerRepresentable {
        var sourceType: UIImagePickerController.SourceType = .photoLibrary
        
        @Binding var show: Bool
        @Binding var image: Data
        
        func makeCoordinator() -> ImagePicker.Coordinator {
            let imagePicker = UIImagePickerController()
            return ImagePicker.Coordinator(child1: self)
        }
        
        func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
            let picker = UIImagePickerController()
            picker.delegate = context.coordinator
            picker.sourceType = sourceType
            return picker
        }
    
        func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
    
        }
        
        class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
            var child : ImagePicker
            init(child1: ImagePicker) {
                child = child1
            }
        
        
        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            self.child.show.toggle()
        }
        
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
            let image = info[.originalImage]as! UIImage
            let data = image.jpegData(compressionQuality: 0.45)
            self.child.image = data!
            self.child.show.toggle()
        }
    }
    }
    
    struct ImagePicker:UIViewControllerRepresentable{
    变量sourceType:UIImagePickerController.sourceType=.photoLibrary
    @绑定变量显示:Bool
    @绑定var映像:数据
    func makeCoordinator()->ImagePicker.Coordinator{
    让imagePicker=UIImagePickerController()
    返回图像选择器协调器(child1:self)
    }
    func makeUIViewController(上下文:UIViewControllerRepresentableContext)->UIImagePickerController{
    让picker=UIImagePickerController()
    picker.delegate=context.coordinator
    picker.sourceType=sourceType
    回程选择器
    }
    func updateUIViewController(uViewController:UIImagePickerController,上下文:UIViewControllerRepresentableContext){
    }
    类协调器:NSObject、UIImagePickerControllerDelegate、UINavigationControllerDelegate{
    var子对象:图像选择器
    初始化(child1:ImagePicker){
    child=child1
    }
    func ImagePickerController IDCancel(picker:UIImagePickerController){
    self.child.show.toggle()
    }
    func imagePickerController(picker:UIImagePickerController,didFinishPickingMediaWithInfo:[UIImagePickerController.InfoKey:Any]){
    将image=info[.originalImage]设为!UIImage
    让数据=image.jpegData(压缩质量:0.45)
    self.child.image=数据!
    self.child.show.toggle()
    }
    }
    }
    
    您的问题可以归结为“我如何才能呈现多张工作表?”,因此可能会有所帮助

  • 定义新的
    enum
    以包含可能的图纸类型(图库/拍照)
  • 声明一个
    @State
    属性以保存当前图纸类型。它是可选的,因为当它为零时,将不会显示任何工作表
  • 将属性设置为所需的类型
  • 使用而不是<代码>isPresented最适合静态图纸<代码>项目适用于您需要的多种图纸类型
  • 您还需要修改
    图像选择器
    ,以便
    绑定
    接收
    照片类型
    ,而不是
    Bool
    。要关闭工作表,只需将
    showingType
    设置为nil

    struct ImagePicker: UIViewControllerRepresentable {
        var sourceType: UIImagePickerController.SourceType = .photoLibrary
        
        @Binding var showingType: PhotoSheetType?
        @Binding var image: Data
        
        func makeCoordinator() -> ImagePicker.Coordinator {
            let imagePicker = UIImagePickerController()
            return ImagePicker.Coordinator(child1: self)
        }
        
        func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
            let picker = UIImagePickerController()
            picker.delegate = context.coordinator
            picker.sourceType = sourceType
            return picker
        }
        
        func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
            
        }
        
        class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
            var child : ImagePicker
            init(child1: ImagePicker) {
                child = child1
            }
            
            
            func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
                self.child.showingType = nil /// set to nil here
            }
            
            func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
                let image = info[.originalImage] as! UIImage
                let data = image.jpegData(compressionQuality: 0.45)
                self.child.image = data!
                self.child.showingType = nil /// set to nil here
            }
        }
    }
    
    struct ImagePicker:UIViewControllerRepresentable{
    变量sourceType:UIImagePickerController.sourceType=.photoLibrary
    @绑定变量showingType:photosheetype?
    @绑定var映像:数据
    func makeCoordinator()->ImagePicker.Coordinator{
    让imagePicker=UIImagePickerController()
    返回图像选择器协调器(child1:self)
    }
    func makeUIViewController(上下文:UIViewControllerRepresentableContext)->UIImagePickerController{
    让picker=UIImagePickerController()
    picker.delegate=context.coordinator
    picker.sourceType=sourceType
    回程选择器
    }
    func updateUIViewController(uViewController:UIImagePickerController,上下文:UIViewControllerRepresentableContext){
    }
    类协调器:NSObject、UIImagePickerControllerDelegate、UINavigationControllerDelegate{
    var子对象:图像选择器
    初始化(child1:ImagePicker){
    child=child1
    }
    func ImagePickerController IDCancel(picker:UIImagePickerController){
    self.child.showingType=nil///此处设置为nil
    }
    func imagePickerController(picker:UIImagePickerController,didFinishPickingMediaWithInfo:[UIImagePickerController.InfoKey:Any]){
    将image=info[.originalImage]设为!UIImage
    让数据=image.jpegData(压缩质量:0.45)
    self.child.image=数据!
    self.child.showingType=nil///此处设置为nil
    }
    }
    }
    
    这是一个很棒的答案!非常清楚,解释得很好。你也是对的,它与另一个问题类似,我认为将代码放在操作表中让我感到有点困惑。唯一的问题是,当我尝试它时,我在控制台上得到一条消息,“应用程序试图以模态方式呈现一个已经由呈现的视图控制器”。看起来某个地方的“showingActionSheet”太多了,但我太新手了,看不清确切的位置。@FPL上面的代码是否会出现此消息?当我测试它时,问题可能在代码的其他地方。你是对的,我在其他地方发现了错误。非常感谢!
    struct ImagePicker: UIViewControllerRepresentable {
        var sourceType: UIImagePickerController.SourceType = .photoLibrary
        
        @Binding var showingType: PhotoSheetType?
        @Binding var image: Data
        
        func makeCoordinator() -> ImagePicker.Coordinator {
            let imagePicker = UIImagePickerController()
            return ImagePicker.Coordinator(child1: self)
        }
        
        func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
            let picker = UIImagePickerController()
            picker.delegate = context.coordinator
            picker.sourceType = sourceType
            return picker
        }
        
        func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
            
        }
        
        class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
            var child : ImagePicker
            init(child1: ImagePicker) {
                child = child1
            }
            
            
            func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
                self.child.showingType = nil /// set to nil here
            }
            
            func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
                let image = info[.originalImage] as! UIImage
                let data = image.jpegData(compressionQuality: 0.45)
                self.child.image = data!
                self.child.showingType = nil /// set to nil here
            }
        }
    }