SwiftUI URLImage 水平滚动视图

Posted

技术标签:

【中文标题】SwiftUI URLImage 水平滚动视图【英文标题】:SwiftUI URLImage Horizontal ScrollView 【发布时间】:2020-09-09 08:20:46 【问题描述】:

所以我一直在阅读 SwiftUI instagram 教程,并学习了如何在标准 3x3 instagram 视图中将用户上传的图像加载到 firebase,但现在我想扩展我的知识并练习在水平滚动视图中进行操作。

这是我必须创建的网格视图:

    import SwiftUI
    import URLImage
    import FirebaseAuth
    
    struct Photo: Identifiable 
        let id = UUID()
        var photo = ""
    
    
    struct PhotoView: View 
        @Environment(\.presentationMode) var mode: Binding<PresentationMode>
        @EnvironmentObject var session: SessionStore
        @ObservedObject var profileViewModel = ProfileViewModel()

var body: some View 
        
        return
                ScrollView 
                    if !profileViewModel.isLoading 
                        VStack(alignment: .leading, spacing: 1) 
                            // rows
                            ForEach(0..<self.profileViewModel.splitted.count)  index in
                                HStack(spacing: 1) 
                                    // Columns
                                    ForEach(self.profileViewModel.splitted[index], id: \.postId)  post in
                                        
                                        URLImage(URL(string: post.mediaUrl)!,
                                        content: 
                                            $0.image
                                                .resizable()
                                                .aspectRatio(contentMode: .fill)
                                            ).frame(width: UIScreen.main.bounds.width / 3, height: UIScreen.main.bounds.width / 3).clipped().cornerRadius(5)
                                        
                                    
                                
                            
                        .frame(width: UIScreen.main.bounds.width, alignment: .leading).padding(.top, 2)
                    
 
                .navigationBarTitle(Text("Photos"), displayMode: .inline).navigationBarBackButtonHidden(true).navigationBarItems(leading: Button(action : 
                    self.mode.wrappedValue.dismiss()
                ) 
                    Image(systemName: "arrow.left")
                ).onAppear 
                    self.profileViewModel.loadUserPosts(userId: Auth.auth().currentUser!.uid)
        
    


extension Array 
    
    func splitted(into size:Int) -> [[Element]] 
        var splittedArray = [[Element]]()
        if self.count >= size 
            for index in 0...self.count 
                if index % size == 0 && index != 0 
                    splittedArray.append(Array(self[(index - size)..<index]))
                 else if (index == self.count) 
                    splittedArray.append(Array(self[index - 1..<index]))
                
            
            
         else 
            splittedArray.append(Array(self[0..<self.count]))
        
        return splittedArray
    


class ProfileViewModel: ObservableObject 
    @Published var posts: [Post] = []
    @Published var isLoading = false
    var splitted: [[Post]] = []
    
    func loadUserPosts(userId: String) 
        isLoading = true
        Api.User.loadPosts(userId: userId)  (posts) in
            self.isLoading = false
            self.posts = posts
            self.splitted = self.posts.splitted(into: 3)
        
    

这就是它的样子:

这是我想要实现的示例代码:

import SwiftUI
import URLImage
import FirebaseAuth

struct TestView: View 
    @Environment(\.presentationMode) var mode: Binding<PresentationMode>
    var body: some View 
        VStack 
            
            ScrollView(.horizontal, showsIndicators: false) 
                HStack(spacing: 2) 
                    ForEach(1..<5)  _ in
                        Image("photo3").resizable()
                            .clipShape(Rectangle())
                            .aspectRatio(contentMode: ContentMode.fill)
                            .frame(width: 100, height: 100).cornerRadius(10).opacity(1).shadow(radius: 4)
                    
                    
                
            .navigationBarTitle(Text("Photos"), displayMode: .inline).navigationBarBackButtonHidden(true).navigationBarItems(leading: Button(action : 
                self.mode.wrappedValue.dismiss()
            ) 
                Image(systemName: "arrow.left")
            )
            Spacer()
        .padding()
    

这是我希望它看起来像的示例图像:

我真的很难理解 ForLoop 部分以及如何将图像检索到只是在一个简单的滚动视图中。

任何帮助将不胜感激!

谢谢!

【问题讨论】:

【参考方案1】:

您想遍历模型中的帖子。借用你之前的代码,你需要这样的东西:

ScrollView(.horizontal, showsIndicators: false) 
    HStack(spacing: 2) 

        ForEach(self.profileViewModel.posts, id: \.postId)  post in
                                        
            URLImage(URL(string: post.mediaUrl)!,
                content: 
                    $0.image
                    .resizable()
                    .aspectRatio(contentMode: .fill)
                
            )
            .frame(width: 100, height: 100)
            .clipped()
            .cornerRadius(10)
            .shadow(radius: 4)
        
    

【讨论】:

【参考方案2】:

vacawama 已经发布了完美的解决方案,使其看起来像您的示例。

只是为了添加你获得结果的原因,你得到了。

您的代码和示例代码之间的区别在于您使用了两个 ForEach,一个用于行,一个用于列。数组与您的扩展分开,因此您得到行和列。

//Rows
ForEach(0..<self.profileViewModel.splitted.count)  index in
    HStack(spacing: 1) 
        // Columns
        ForEach(self.profileViewModel.splitted[index], id: \.postId)  post in

您的 cmets 已经说明了它的工作原理。如果您想将所有图像放在水平滚动条中,您只需要一个 ForEach,它将所有图像输出到 ScrollView 中。

ScrollView(.horizontal, showsIndicators: false) 
    HStack(spacing: 2) 
        ForEach(self.profileViewModel.posts, id: \.postId)  post in

【讨论】:

以上是关于SwiftUI URLImage 水平滚动视图的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI/UIKit:水平滚动视图缩放视图

SwiftUI:水平滚动视图我能够上下拉图像

SwiftUi 水平滚动视图,带有来自 Api 的数据

SwiftUI当总内容宽度小于屏幕宽度时,如何在动态水平滚动视图中居中内容

SwiftUI Drag 事件如何限制仅检测水平/垂直滚动

在 SwiftUI ScrollView 中停止垂直滚动