admin管理员组

文章数量:1391766

New to xcode and ios programming

I am trying to create an image grid view of a bunch of images - i need to download the list of filenames/urls and into an array, then loop through the data in the array to display them.

right now i have asyncimage pulling a random image for testing - this works as intended. i need to replace the URL being fetched with data from the array - you will see ProjectInfo defined at the bottom

I can't work out how to replace the ForEach loop with data from the array. right now it is just looping from 1 to 100 and loading a random image. i need to loop through the ProjectInfo struct and download the filename for each record

below is my code:

import SwiftUI

struct ProjectViewPhotos: View
{
    @State private var data: [ProjectInfo] = []

    let jobid: String

    var body: some View
    {
        ScrollView {
            LazyVGrid(columns: [.init(.adaptive(minimum: 100, maximum: .infinity), spacing: 3)], spacing: 3) {
                ForEach(1..<100)
                {
                    ix in
                    VStack(alignment: .leading){
                        NavigationLink(
                            destination: ViewImage(project_job_id: "126", image_filename: "pic05.jpg"))
                        {

                                AsyncImage(url: URL(string: "/200/300")!)
                                    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
                                    .clipped()
                                    .aspectRatio(1, contentMode: .fit)
                            }
                    }.navigationTitle("Project Photos - " + jobid)
                }
            }
        }
    }

    func fetchData()
    {
        guard let url = URL(string: ".php?projectid=" + jobid) else { return }

        URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data else { return }
            do {
                let projectinfo = try JSONDecoder().decode([ProjectInfo].self, from: data)
                DispatchQueue.main.async {
                    self.data = projectinfo
                }
            } catch {
                print(error)
            }
        }.resume()
    }
}

struct ProjectInfo: Codable {
    let id: String
    let image_filename: String
    let project_id: String
}

#Preview {
    ProjectViewPhotos(jobid: "47")
}

tried the above which works. when i attempt to use the array i get all sorts of errors depending on what i've tried.

New to xcode and ios programming

I am trying to create an image grid view of a bunch of images - i need to download the list of filenames/urls and into an array, then loop through the data in the array to display them.

right now i have asyncimage pulling a random image for testing - this works as intended. i need to replace the URL being fetched with data from the array - you will see ProjectInfo defined at the bottom

I can't work out how to replace the ForEach loop with data from the array. right now it is just looping from 1 to 100 and loading a random image. i need to loop through the ProjectInfo struct and download the filename for each record

below is my code:

import SwiftUI

struct ProjectViewPhotos: View
{
    @State private var data: [ProjectInfo] = []

    let jobid: String

    var body: some View
    {
        ScrollView {
            LazyVGrid(columns: [.init(.adaptive(minimum: 100, maximum: .infinity), spacing: 3)], spacing: 3) {
                ForEach(1..<100)
                {
                    ix in
                    VStack(alignment: .leading){
                        NavigationLink(
                            destination: ViewImage(project_job_id: "126", image_filename: "pic05.jpg"))
                        {

                                AsyncImage(url: URL(string: "https://picsum.photos/200/300")!)
                                    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
                                    .clipped()
                                    .aspectRatio(1, contentMode: .fit)
                            }
                    }.navigationTitle("Project Photos - " + jobid)
                }
            }
        }
    }

    func fetchData()
    {
        guard let url = URL(string: "https://mywebsite/index.php?projectid=" + jobid) else { return }

        URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data else { return }
            do {
                let projectinfo = try JSONDecoder().decode([ProjectInfo].self, from: data)
                DispatchQueue.main.async {
                    self.data = projectinfo
                }
            } catch {
                print(error)
            }
        }.resume()
    }
}

struct ProjectInfo: Codable {
    let id: String
    let image_filename: String
    let project_id: String
}

#Preview {
    ProjectViewPhotos(jobid: "47")
}

tried the above which works. when i attempt to use the array i get all sorts of errors depending on what i've tried.

Share Improve this question edited Mar 12 at 8:50 Joakim Danielson 52.3k5 gold badges33 silver badges71 bronze badges asked Mar 12 at 1:57 user29966277user29966277 1 1
  • Don't use ForEach with indexes. Use ForEach(data) { data in ... } – Paulw11 Commented Mar 12 at 2:16
Add a comment  | 

1 Answer 1

Reset to default 0

You're close! You just need to modify your ForEach loop to iterate over the data array instead of a fixed range. Additionally, ensure that fetchData() is called to load data when the view appears.

struct ProjectViewPhotos: View {
    @State private var data: [ProjectInfo] = []
    let jobid: String

    var body: some View {
        ScrollView {
            LazyVGrid(columns: [GridItem(.adaptive(minimum: 100, maximum: .infinity), spacing: 3)], spacing: 3) {
                ForEach(data, id: \.id) { item in
                    VStack(alignment: .leading) {
                        NavigationLink(
                            destination: ViewImage(project_job_id: jobid, image_filename: item.image_filename)) {
                                AsyncImage(url: URL(string: "https://mywebsite/images/\(item.image_filename)"))
                                    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
                                    .clipped()
                                    .aspectRatio(1, contentMode: .fit)
                        }
                    }
                }
            }
        }
        .navigationTitle("Project Photos - \(jobid)")
        .onAppear {
            fetchData()
        }
    }

    func fetchData() {
        guard let url = URL(string: "https://mywebsite/index.php?projectid=\(jobid)") else { return }

        URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data else { return }
            do {
                let projectinfo = try JSONDecoder().decode([ProjectInfo].self, from: data)
                DispatchQueue.main.async {
                    self.data = projectinfo
                }
            } catch {
                print(error)
            }
        }.resume()
    }
}

本文标签: swiftuiiOS Apptrying to load images from list in arrayStack Overflow