Создание Grid / UICollectionView с SwiftUI - PullRequest
0 голосов
/ 01 мая 2020

Я работаю над приложением iOS с SwiftUI. Переходя к SwiftUI, я быстро заметил отсутствие UICollectionView, благодаря которому представления в виде сетки легко достижимы. У меня есть код ниже для моего элемента ячейки:

struct ListingView : View{
   var body: some View{
        VStack (alignment: .leading) {
            VStack{
                HStack(spacing: 5){
                    KFImage(URL(string: Global.imageStoreListings + image1)!).resizable().scaledToFill()
                        .frame(height:140).frame(minWidth: 0, maxWidth: .infinity)
                    .cornerRadius(4)

                    KFImage(URL(string: Global.imageStoreListings + image2)!).resizable()
                        .scaledToFill()
                         .frame(height:140).frame(minWidth: 0, maxWidth: .infinity)
                         .cornerRadius(4)
                }.frame(minWidth: 0, maxWidth: .infinity)
                 HStack(spacing: 5){
                    KFImage(URL(string: Global.imageStoreListings + image3)!).resizable()
                     .scaledToFill()
                         .frame(height:140).frame(minWidth: 0, maxWidth: .infinity)
                        .cornerRadius(4)

                     KFImage(URL(string: Global.imageStoreListings + image4)!).resizable()
                        .scaledToFill()
                         .frame(height:140).frame(minWidth: 0, maxWidth: .infinity)
                        .cornerRadius(4)
                }.frame(minWidth: 0, maxWidth: .infinity)
            }.frame(minWidth: 0, maxWidth: .infinity)
            Text(listing.tags! + " • " + listing.location!).font(.custom("Nolasco Sans", size: 14))
            Text(listing.title).font(.custom("Google Sans", size: 16))

        }
       }
    }

Я вызываю это в ContentView:

  var body: some View{       
      List {
        ForEach(self.list, id: \.bid_id){ item in
                ListingView()
           }
       }
  }

Результат выглядит так (это одна строка):

enter image description here

Вместо этого я хочу, чтобы это выглядело так (это одна строка)

enter image description here

Я пытался использовать вложенные циклы, как я видел из других примеров, но я просто настолько запутался в этом, что решил просто получить помощь для своего конкретного сценария. Любая помощь приветствуется

1 Ответ

1 голос
/ 02 мая 2020

Решением этой проблемы является структура данных. Вам нужен 2D массив списков.

Редактировать: Я добавляю полный код с преобразователем массива. Я не настроил стили, чтобы сделать изображение идеальным. Но я думаю, что все работает.

import SwiftUI

struct ContentView: View {
    @ObservedObject var model = DataLoader()
    var body: some View {
        VStack {
            List {
                ForEach(self.model.data, id: \.self){ item in
                    HStack(spacing: 25) {
                        ForEach(item, id: \.self) { listing in
                            ListingView(listing: listing)
                        }
                    }
                }
            }
        }.padding()
    }
}

struct ListingView: View {
    @State var listing: Listing
    var body: some View {
        VStack (alignment: .leading) {
            VStack{
                HStack(spacing: 5){
                    Image(listing.images[0]).resizable().scaledToFill()
                        .frame(height:70).frame(minWidth: 0, maxWidth: .infinity)
                        .cornerRadius(4)

                    Image(listing.images[1]).resizable()
                        .scaledToFill()
                        .frame(height:70).frame(minWidth: 0, maxWidth: .infinity)
                        .cornerRadius(4)
                }.frame(minWidth: 0, maxWidth: .infinity)
                HStack(spacing: 5){
                    Image(listing.images[2]).resizable()
                        .scaledToFill()
                        .frame(height:70).frame(minWidth: 0, maxWidth: .infinity)
                        .cornerRadius(4)

                    Image(listing.images[3]).resizable()
                        .scaledToFill()
                        .frame(height:70).frame(minWidth: 0, maxWidth: .infinity)
                        .cornerRadius(4)
                }.frame(minWidth: 0, maxWidth: .infinity)
            }.frame(minWidth: 0, maxWidth: .infinity)
            Text(listing.tags + " • " + listing.location).font(.custom("Nolasco Sans", size: 14))
            Text(listing.title).font(.custom("Google Sans", size: 16))

        }
    }
}

struct Listing: Hashable, Decodable {
    var id: Int
    var title: String
    var location: String
    var tags: String
    var images: [String]
}

class DataLoader: ObservableObject {
    @Published var data: [[Listing]] = [[Listing]]()
    func loader() {
        if let url = URL(string: "https://nikz.in/data.json") {
            let req = URLRequest(url: url)
            URLSession.shared.dataTask(with: req) { data, res, err in
                if let data = data {
                    do {
                        let response = try JSONDecoder().decode([Listing].self, from: data)
                        DispatchQueue.main.async {
                            self.data = self.to2DArray(input: response, rows: 2)
                        }
                        return
                    } catch {
                        print("Unable to decode")
                    }
                } else {
                    print("Data not loading")
                }
            }.resume()
        }
    }

    func to2DArray<T>(input: [T], rows: Int) -> [[T]] {
        let columns = Int(ceil(Double(input.count)/Double(rows)))
        print(Double(input.count)/Double(rows))
        var output = [[T]]()
        for column in 0..<columns {
            var temp: [T] = [T]()
            for row in 0..<rows {
                let id = (column*rows)+row
                if id>input.count-1 { break }
                temp.append(input[id])
            }
            output.append(temp)
        }
        return output
    }

    init() {
        loader()
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...