如何在 SwiftUI 中对 Imagepicker 进行两次单独的调用?

2024-04-22

我希望用户能够将两个单独的图像上传到同一视图的两个不同部分。

我能够让第一张图像在顶部正确显示。但每当用户添加第二个图像时,顶部的图像会再次更新,而不是底部的图像。

截屏 https://i.stack.imgur.com/IOi90.png

下面是我的代码。任何帮助,将不胜感激!

图像选择器

import SwiftUI

struct ImagePicker: UIViewControllerRepresentable {
    @Environment(\.presentationMode) var presentationMode
    @Binding var image: UIImage?

    func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.delegate = context.coordinator
        return picker
    }

    func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {

    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
}

class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
    let parent: ImagePicker

    init(_ parent: ImagePicker) {
        self.parent = parent
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
        if let uiImage = info[.originalImage] as? UIImage {
            parent.image = uiImage
        }

        parent.presentationMode.wrappedValue.dismiss()
    }
}

内容视图

import SwiftUI

struct ContentView: View {
    @State private var firstImage: Image? = Image("PlaceholderImage")
    @State private var secondImage: Image? = Image("PlaceholderImage")
    @State private var inputImage1: UIImage?
    @State private var inputImage2: UIImage?
    @State private var showingImagePicker = false

    var body: some View {
            VStack{
                    Form {
                        Section(header: Text("First Image")){
                            firstImage!
                                .resizable()
                                .aspectRatio(contentMode: .fit)
                                .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 200, alignment: .center)
                                .clipShape(Rectangle())
                                .onTapGesture { self.showingImagePicker = true }
                                .sheet(isPresented: $showingImagePicker, onDismiss: loadImage1) {
                                    ImagePicker(image: self.$inputImage1)
                                }
                        }
                        Section(header: Text("Second Image")){
                            secondImage!
                                .resizable()
                                .aspectRatio(contentMode: .fit)
                                .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 200, alignment: .center)
                                .clipShape(Rectangle())
                                .onTapGesture { self.showingImagePicker = true }
                                .sheet(isPresented: $showingImagePicker, onDismiss: loadImage2) {
                                    ImagePicker(image: self.$inputImage2)
                                }
                        }
                    }
            }
        }
    
    func loadImage1() {
        guard let inputImage = inputImage1 else { return }
        firstImage = Image(uiImage: inputImage)
    }
    
    func loadImage2() {
        guard let inputImage = inputImage2 else { return }
        secondImage = Image(uiImage: inputImage)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

问题的根本原因是使用sheet(isPresented:)这在 iOS 14 上可能会出现问题,因为它会加载第一个渲染的工作表内容(在您的情况下,ImagePicker对于第一张图片),然后没有像人们预期的那样更新(请参阅SwiftUI @State 和 .sheet() ios13 与 ios14 https://stackoverflow.com/questions/63946914/swiftui-state-and-sheet-ios13-vs-ios14例如)。

解决方案是使用sheet(item:)。就您而言,这还涉及一些其他重构以使事情按预期工作。这是我想出的:

struct ContentView: View {
    @State private var inputImage1: UIImage?
    @State private var inputImage2: UIImage?
    @State private var activeImagePicker : ImagePickerIdentifier? = nil
    
    enum ImagePickerIdentifier : String, Identifiable {
        case picker1, picker2
        
        var id : String {
            return self.rawValue
        }
    }
    
    var image1 : Image {
        if let inputImage1 = inputImage1 {
            return Image(uiImage: inputImage1)
        } else {
            return Image("Placeholder")
        }
    }
    
    var image2 : Image {
        if let inputImage2 = inputImage2 {
            return Image(uiImage: inputImage2)
        } else {
            return Image("Placeholder")
        }
    }
    
    var body: some View {
        VStack{
            Form {
                Section(header: Text("First Image")){
                    image1
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 200, alignment: .center)
                        .clipShape(Rectangle())
                        .onTapGesture { self.activeImagePicker = .picker1 }
                }
                Section(header: Text("Second Image")) {
                    image2
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 200, alignment: .center)
                        .clipShape(Rectangle())
                        .onTapGesture { self.activeImagePicker = .picker2 }
                }
                
            }
            .sheet(item: $activeImagePicker) { picker in
                switch picker {
                case .picker1:
                    ImagePicker(image: $inputImage1)
                case .picker2:
                    ImagePicker(image: $inputImage2)
                }
            }
        }
    }
}

请注意,我摆脱了你的onDismiss函数,因为这里没有必要,但是如果你did您的实际实施需要它,我建议使用onDisappear就个人而言ImagePickers,这将让您区分哪一个被解雇。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 SwiftUI 中对 Imagepicker 进行两次单独的调用? 的相关文章

  • 如何从 SwiftUI 中的列表获取屏幕行?

    我想放一个Text对于列表中的每个可见 屏幕边界内 行 其当前索引在所有可见行中 我这里有一个例子 如果我有一个一次显示 3 行的列表 并且最初我希望它显示如下 A 0 B 1 C 2 如果我向下滚动列表 A 走出屏幕 那么就会像 B 0
  • 绑定到枚举的关联值

    是否有一个标准的方法来绑定 比如说 TextField到枚举的关联值 所以 鉴于此 enum Choice case one String case two String 我可以以某种方式将它用作视图中的绑定吗 State var choi
  • 如何在 SwiftUI 中为按下时的导航链接设置动画?

    我试图通过在按下 NavigationLink 时提供一些反馈来改进用户体验 我的意思是一个简单的动画 它会增长然后缩小链接以显示它被按下或以任何其他方式提供反馈 这是我正在尝试改进的代码 NavigationLink destinatio
  • SwiftUI Focus State API 环境变量不起作用

    当我们想要观察 SwiftUI 文本字段的焦点状态时 环境值 isFocused 似乎不起作用 除了将值传递给 TextFieldStyle 的 init 我们必须为每个 Textfield 执行此操作 之外 还有其他方法可以做到这一点吗
  • SwiftUI 根据设备设置 navigationViewStyle

    我试图让我的导航视图样式在 iPad 上堆叠 但在 iPhone 上默认 Code navigationViewStyle UIDevice current userInterfaceIdiom pad StackNavigationVie
  • 更改 TabBar SwiftUI 中的选项卡选择颜色

    我试图更改 TabBar 中选定选项卡的颜色 但没有任何效果 我可以更改 TabBarbackgroundColor通过写作 struct ContentView View init UITabBar appearance backgrou
  • SwiftUI:为什么 ForEach($strings) (文本:Binding)无法构建?

    我有一个ForEach它需要一个 Binding 并使用 Xcode11 beta5 编译 但使用 beta6 则显示Type of expression is ambiguous without more context on the T
  • SwiftUI - TabView 禁用背景透明度

    有没有办法禁用透明度TabView for iOS 15 If my List没有填满整个屏幕TabView背景是透明的 我希望始终显示TabView背景 感谢 Asperi 为我指明了正确的方向 我发现scrollEdgeAppearan
  • 在 SecureField 的 SwiftUI 中切换 isSecureTextEntry

    我想实现在 SecureField 中显示和隐藏密码的功能 以下是 SecureField 的代码 我添加了按钮 该按钮将被检测到显示和隐藏 SecureField 中的文本 但 swiftUI 没有类似的功能是安全文本条目除了切换之外还有
  • SwiftUI 列表内存问题,图像未从 RAM 中释放导致崩溃

    我正在将图像加载到 SwiftUI 列表中 当向下滚动太多图像时 RAM 会飙升并导致应用程序崩溃 为什么当用户向下滚动经过图像时图像不会被释放 我正在加载图像 如下所示 List allProducts id self product i
  • SwiftUI |选择器 - 更改选定行的颜色

    我想更改所选行的颜色 正如您所看到的 默认情况下它具有浅灰色 我不知道该怎么做 因为我根本找不到访问这一行的方法 有什么办法可以做到这一点吗 演示代码 struct ContentView View var data Array 0 20
  • SwiftUI 按钮在出现时更改文本大小

    从 GIF 中可以看出 一旦工作表完全打开 完成 按钮文本就会变大 这不仅发生在这个视图中 而且也发生在使用系统图像而不是文本的其他视图中 有谁知道问题的解决方案还是我做错了什么 我仍然对 Swift 记忆犹新 NavigationView
  • 在视图之间传递变量 SwiftUI

    再次基本问题 我想让变量 anytext 对于我要添加的所有未来视图都可见且可访问 在我的例子中 变量将是String 如果是的话 程序会改变吗 Float 我怎样才能将其另存为全局变量 如果我重新启动应用程序 变量会自行删除吗 如何保存即
  • SceneDelegate 和 AppDelegate 之间的区别

    在我的 SwiftUI 项目中我看到AppDelegate文件以及SceneDelegate file 它们之间有什么区别 例如在方法之间SceneDelegate scene willConnectTo options 并在AppDele
  • 有没有 SwiftUI 方法来制作文本上标或下标?

    我知道可以像这样应用偏移量Text TM offset x 0 y 7 但是有没有不同或更好的方法来在 SwiftUI 中创建一些上标或下标文本 这是使用的通用方法 baselineOffset Text Company font call
  • 滚动 swiftUI 列表时,未调用单元格的任务修改器。怎么修?

    我写了一个异步图像视图 with swiftui 并在列表单元格中使用 AsyncImgView 使用任务修饰符在 Img 出现时从缓存或网络下载 Img 在 iOS16 之前一切正常 但在iOS16我发现当我滚动列表新细胞的AsyncIm
  • SwiftUI:如何删除两个部分之间的间距? (iOS16)

    如何消除两个部分之间的间距 这是我的代码 NavigationStack List Section NavigationLink value Color mint HStack Image systemName person font sy
  • 按下后退按钮时 SwiftUI 工具栏项目被剪裁

    我在 SwiftUI 中遇到了一种奇怪的行为 我似乎无法解决它 鉴于以下简单的示例应用程序 我遇到了这种行为 工具栏项目在初始运行时正确呈现 但导航离开并返回它会被剪切 重新创建此示例代码 内容视图 swift import SwiftUI
  • 在一个 SwiftUI 视图中相同的 ForEach 循环两次

    当我在视图中对数组使用 ForEach 循环两次时 我在运行时收到以下警告 LazyVGridLayout the ID 84308994 9D16 48D2 975E DC40C5F9EFFF is used by multiple ch
  • 自定义“可搜索”搜索字段 SwiftUI iOS 15

    When using the new searchable modifier in SwiftUI on iOS 15 I have no way to customize the Search Bar appearance Specifi

随机推荐

  • JSF:使用 ajax 清除 inputTextArea 时出现奇怪的行为

    这是我所拥有的
  • 点击链接后如何导航回来?

    我对在 vba 中使用 IE 还很陌生 所以有时我很难纠正在编写从网络上抓取数据的代码时所犯的任何错误 我编写了一些代码来单击标题下 20 个链接中的每个视频链接Microsoft computer training videos可以在它的
  • 在硒自动化中,鼠标箭头移动是否可以用于测试用例

    我是硒的新手 我想知道如何向用户显示鼠标箭头移动 我的意思是说我们自动化某些事情 我想知道如何向用户显示鼠标箭头移动看到硒中正在进行的自动化 是否可以 我们能否清楚地显示正在单击的内容 我的意思是通过鼠标箭头移动单击了哪个按钮 我希望我很清
  • 更改为服务器端后如何获取标签文本?

    我试图在不回发时将标签的文本分配给隐藏字段 但失败了 这就是我所做的 If Not IsPostBack Then Dim structPayperiod As strcPayperiodDet structPayperiod objTim
  • 使用 ddply 进行汇总统计

    我喜欢使用编写一个函数ddply根据两列的名称输出汇总统计信息data frame mat mat是一个大data frame与列的名称 metric length species tree index index是具有 2 个水平的因子
  • 如何在 jQuery UI 中将多个可排序列表相互连接?

    我是 jQuery 新手 并且在使用 jQuery UI 时遇到了很大的困难sortable 我正在尝试整理一个页面以方便对项目进行分组和排序 我的页面有一个组列表 每个组都包含一个项目列表 我希望允许用户能够执行以下操作 重新排序组 对组
  • 在不知道键的情况下快速引用字典键和值

    我有一个字典数组定义为 var users String String 数组内的字典是一个简单的用户名 是 否标志 第一个用户 Y 第二个用户 N 第三个用户 N 在我的 TableView 单元格配置中 我定义了 let userReco
  • 浏览器和服务器在实践中是否使用 HTTP 内容协商?

    我正在学习关于HTTP内容协商 https developer mozilla org en US docs Web HTTP Content negotiation眼下 我已经了解客户端和服务器能够协商所请求内容的表示的基本方式 但我不知
  • 热点 JVM 字节码解释器是跟踪 JIT 吗?

    这个问题几乎说明了一切 我一直在寻找答案 甚至通过 VM 规范 但我没有明确说明 No 不过 还有一些其他 JVM 具有跟踪 JIT HotPath http HotPath GoogleCode Com and Maxine http L
  • 通过 jQuery tiny PubSub 传递数组

    jQuery 微型 PubSub https gist github com 661855在传递原始值或对象时非常有用 但在传递数组时会遇到一些问题 所以我必须将数组包装成一个对象 function var o subscribe func
  • JTable TableCellRenderer背景与Nimbus LookAndFeel颜色问题

    我正在使用 NimbusLookAndFeel 通过这种外观和感觉 JTable 的单元格背景可以是白色和浅灰色 这取决于行号 现在 我正在编写一些实现 TableCellRenderer 的自定义单元格渲染器 我需要根据 JTable 中
  • PHP 循环遍历表单值

    我有一个表单 提交了许多小字段 我需要循环遍历这些字段并对其执行操作 表格如下所示
  • 在 GoogleTest 中使用 ASSERT 和 EXPECT

    当 ASSERT 宏导致测试用例终止时 EXPECT 宏继续其评估 我想知道决定是否使用其中之一的标准是什么 Use ASSERT当条件must保持 如果没有 测试就在那里停止 当测试的其余部分在不满足此条件的情况下不具有语义意义时 请使用
  • 在使用 libstdc++ 进行调试期间强制使用 std::atomic 内部的锁

    我用谷歌搜索了一下 似乎找不到GCC选项或libstdc 库宏为此 是否可以强制在所有的内部使用锁定std atomic模板专业化 在某些平台上 某些专业化无论如何都会锁定 因此这似乎是一个可行的选择 过去我发现使用std atomic使用
  • 将 Java 日期向后更改一小时

    我有一个 Java 日期对象 Date currentDate new Date 这将给出当前日期和时间 例子 Thu Jan 12 10 17 47 GMT 2012 相反 我想获取日期 将其更改为一小时前 这样它应该给我 Thu Jan
  • GDB 函数参数上的条件中断

    我想在函数参数大于某个值时设置断点 下面的虚拟代码 int main void uint64 t num 123456 uint64 t x 847534 uint64 t other num x x num other stuff her
  • Python:如何在两个单独的数组之间找到两个相等/最接近的值?

    假设我们有两个长度相等的数组 arr1 21 2 3 5 13 arr2 10 4 5 9 12 20 哪个变量来自arr1 is 相等 最接近到一个变量arr2 看看这两个列表 我们可以很容易地说最接近的数字是4 5 and 5 我试图实
  • 如何使用适用于 iOS 的谷歌地图 sdk 来拟合坐标数组的边界?

    如何使用适用于 iOS 的谷歌地图 sdk 来拟合坐标数组的边界 我需要缩放地图以获得 4 个可见标记 这是我对这个问题的解决方案 建设一个GMSCoordinateBounds对象由多个坐标组成 void focusMapToShowAl
  • 零部署 CouchDB 嵌入 Windows 应用程序?

    我可能在这里做梦 但我想知道是否有可能将最小的 CouchDB 引擎完全嵌入到 Windows 应用程序中 以便该应用程序可以运行而无需在用户计算机上安装 CouchDB Erlang 我已经提供了这种精简 捆绑的功能 请在此处查看http
  • 如何在 SwiftUI 中对 Imagepicker 进行两次单独的调用?

    我希望用户能够将两个单独的图像上传到同一视图的两个不同部分 我能够让第一张图像在顶部正确显示 但每当用户添加第二个图像时 顶部的图像会再次更新 而不是底部的图像 截屏 https i stack imgur com IOi90 png 下面