UIImageView Array ForEach 迭代循环问题

Posted

技术标签:

【中文标题】UIImageView Array ForEach 迭代循环问题【英文标题】:UIImageView Array ForEach Iteration Loop problem 【发布时间】:2021-09-04 18:36:42 【问题描述】:

在开发我的 ios 应用程序时,我遇到了在 UIImageViews 数组中获取图像以对该特定图像执行操作的问题。无论我对 LazyVGrid 照片集中的哪张图片执行 LongPressGesture 操作,它始终适用于显示的第一张图片。我认为这可能是我的数组中的 id 的问题,即 ForEach 循环无法正确识别每个元素,但是我不知道如何解决它。

我将数组保存在 ProfileViewModel 类中:

@Published var userPicturesView: [UIImageView] = [UIImageView]()

我正在我的 ProfileView 中循环浏览它:

ScrollView() 
                            LazyVGrid(columns: Array(repeating: GridItem(), count: 3)) 
                                ForEach(0..<profileViewModel.userPicturesView.count, id: \.self)  imageIndex in
                                    if profileViewModel.userPicturesView[imageIndex].image != nil 
                                        Image(uiImage: profileViewModel.userPicturesView[imageIndex].image!)
                                            .resizable()
                                            .border(Color.black, width: 0.25)
                                            .frame(width: screenWidth * 0.34, height: screenHeight * 0.17)
                                            .onLongPressGesture 
                                                withAnimation 
                                                    self.shouldPresentEditActionSheet = true
                                                
                                            
                                            .actionSheet(isPresented: $shouldPresentEditActionSheet) 
                                                ActionSheet(title: Text("Edit selected"), message: nil, buttons: [
                                                    .default(Text("Set as profile picture"), action: 
                                                        withAnimation 
                                                            self.profilePictureImage = Image(uiImage: self.profileViewModel.userPicturesView[imageIndex].image!)
                                                        
                                                    ),
                                                    .destructive(Text("Delete this photo"), action: 
                                                        withAnimation 
                                                            self.profileViewModel.deleteUserImage(imageIndex: imageIndex)
                                                        
                                                    ),
                                                    .cancel()
                                                ])
                                            
                                    
                                
                            
                        

我可以补充一点,我尝试通过添加包含我的图片的自定义结构来解决它:

struct PictureView: Identifiable 
    var id = UUID()
    var uiImageView: UIImageView
    
    init(uiImageView: UIImageView) 
        self.uiImageView = uiImageView
    

然后在 ProfileViewModel 中创建一个这样的结构数组:

@Published var userPicturesView: [PictureView] = [PictureView]()

然后以这种方式更改 ProfileView:

ScrollView() 
                            LazyVGrid(columns: Array(repeating: GridItem(), count: 3)) 
                                ForEach(self.profileViewModel.userPicturesView)  userPictureView in
                                    if userPictureView.uiImageView.image != nil 
                                        Image(uiImage: userPictureView.uiImageView.image!)
                                            .resizable()
                                            .border(Color.black, width: 0.25)
                                            .frame(width: screenWidth * 0.34, height: screenHeight * 0.17)
                                            .onLongPressGesture 
                                                withAnimation 
                                                    self.shouldPresentEditActionSheet = true
                                                
                                            
                                            .actionSheet(isPresented: $shouldPresentEditActionSheet) 
                                                ActionSheet(title: Text("Edit selected"), message: nil, buttons: [
                                                    .default(Text("Set as profile picture"), action: 
                                                        withAnimation 
                                                            self.profilePictureImage = Image(uiImage: userPictureView.uiImageView.image!)
                                                        
                                                    ),
                                                    .destructive(Text("Delete this photo"), action: 
                                                        withAnimation 
//                                                            self.profileViewModel.deleteUserImage(imageIndex: imageIndex)
                                                        
                                                    ),
                                                    .cancel()
                                                ])
                                            
                                    
                                
                            
                        

但这带来了同样的结果。 我们将不胜感激。

【问题讨论】:

不要使用actionSheet(isPresented:) -- 使用actionSheet(item:)并将正确的PictureView传递给它 @jnpdx 感谢您的回复!我正在尝试更改我的代码以按照您的方式实现它但是我不太确定在没有 isPresented 触发器时长按图像时如何在 ForEach 循环中调用操作表 查看我的答案——触发器将是item: 而不是isPresented——只要确保在闭包中引用item。不相关,但我不清楚你为什么使用UIImageView 然后访问其中的image 而不仅仅是使用UIImage 当我像现在使用 UIImageView 一样使用 UIImage 时,我的图像无法显示,可能是做错了什么 【参考方案1】:

使用actionSheet(item:) 代替actionSheet(isPresented:) 将使您能够访问所选项目。在 iOS 14+ 中,isPresented 先渲染前一个值存在问题。这是您的代码的简化版本:

struct ContentView: View 
    let pictureViews : [PictureView] = []
    @State private var selectedItem : PictureView? = nil
    
    var body: some View 
        ForEach(pictureViews)  pictureView in
            Image(uiImage: pictureView.uiImageView.image!)
                .onLongPressGesture 
                    selectedItem = pictureView
                
        .actionSheet(item: $selectedItem)  item in
            ActionSheet(title: Text("Edit selected"), message: nil, buttons: [
                .default(Text("Set as profile picture"), action: 
                    withAnimation 
                        //use `item` here
                    
                ),
                .destructive(Text("Delete this photo"), action: 
                    withAnimation 
                        //use `item` here
                    
                ),
                .cancel()
            ])
        
    

【讨论】:

非常感谢!我在我的代码中实现了这一点,调整了 ID 创建,以便我也可以使用按索引删除,现在一切正常。如果不是你,我不会想到问题可能与 ActionSheet 相关 :)

以上是关于UIImageView Array ForEach 迭代循环问题的主要内容,如果未能解决你的问题,请参考以下文章

forEach()Array.map()和Array.filter()用法

Array.forEach Array.map Array.filter的用法

Array.forEach原理,仿造一个类似功能

jQuery.each 实现不同于原生 Array.forEach

UIImageView下如何显示subtext

php foreach数组问题