如何让一个简单的 SwiftUI 作为 UITableView 加载(逻辑上!) [英] How to get a simple SwiftUI to load as a UITableView would (logically!)

查看:19
本文介绍了如何让一个简单的 SwiftUI 作为 UITableView 加载(逻辑上!)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我怎样才能让 SwiftUI 水平加载 8 个图像,但如果第三个图像碰巧离开屏幕,它会将它放在第一个图像下方的 Vstack 中,具有相同的填充......如果三个图像可以放在屏幕上,它确实可以和第四个一样.

反正我找不到这样做!TableViews 很容易实现,但现在 SwiftUI 使事情变得更加困难

iPhone:[1] [2][3] [4][5] [6][7] [8]iPad Pro[1] [2][3] [4][5] [6] [7] [8]小型平板电脑[1] [2][3][4] [5] [6][7] [8]

解决方案

我通过下面的代码实现了同样的要求.请检查.

我们需要根据项目总数计算行数和列数

<块引用>

逻辑 -

  1. 通过假设屏幕中每个图像的宽度相等来计算列
    • 每个图像单元格的屏幕宽度/宽度
  2. 通过将总图像数组计数除以数量来计算行列.
  3. 例如;

  • 数组中的总图像 - 5

  • 总列数为 2

  • 总行数 = 5/2 = 2.5 这意味着我们需要第三行来显示最后一张图片

struct GalleryView:查看{//图像样本数组让图像:[String] = [preview1"、preview2"、preview3"、preview4"、preview5""]let columns = Int(UIScreen.main.bounds.width/120.0)//图片宽度为100,多取20进行填充var主体:一些视图{滚动视图{GalleryCellView(rows: getRows(), columns: columns) { index in如果索引整数{//根据图像计数和总列数计算行让行 = Double(images.count)/Double(columns)返回楼层(行)== 行?整数(行):整数(行+1.0)//如果行数是双精度值,则意味着还需要一行}}//加载图片按钮单元格结构 ImageGridView:查看 {让图像:字符串var主体:一些视图{图像(图像).renderingMode(.original).frame(宽:100,高:100).cornerRadius(10)}}//构建单元格视图struct GalleryCellView<内容:视图>:视图{让行:Int让列:Int让内容:(Int)->内容var主体:一些视图{VStack(对齐:.领先,间距:0){ForEach(0 ..< rows, id: \.self) { row inHStack(间距:10){ForEach(0 ..< self.columns, id: \.self) { 列在self.content((row * self.columns) + column)}}.padding([.top, .bottom], 5).padding([.lead,.trailing], 10)}}.padding(10)}init(rows: Int, columns: Int, @ViewBuilder content: @escaping (Int) -> Content) {self.rows = 行self.columns = 列self.content = 内容}}

<块引用>

在 Xcode 11.3 版、iPhone 11 Pro Max & 中测试iPad Pro (12.9 -英寸)模拟器

iPhone 中的结果

iPad 中的结果

How can I get SwiftUI to load 8 images horizontally but if the third image happens to go off screen it puts it in a Vstack underneath the 1st image with the same padding... and if three can fit on the screen it does the same to the 4th.

I can not find anyway to do this! TableViews were so easy to implement but now SwiftUI makes things much harder

iPhone:

[1] [2]
[3] [4]
[5] [6] 
[7] [8]

iPad Pro
[1] [2][3] [4]
[5] [6] [7] [8]

iPad Mini
[1] [2][3] 
[4] [5] [6] 
[7] [8]

解决方案

I have acheived this same requirement through below code. Please check.

We need to calculate number of rows and columns based on total items

Logic -

  1. Calculate columns by assuming equal width for each images in screen
    • Screen width/width of each image cell
  2. Calculate rows by dividing total image array count with number of columns.
  3. For example;

  • Total images in array - 5

  • Total columns say 2

  • Total rows = 5/2 = 2.5 that means we need 3rd row to display last image

struct GalleryView: View {
    //Sample array of images
    let images: [String] = ["preview1","preview2","preview3","preview4","preview5""]
    let columns = Int(UIScreen.main.bounds.width/120.0) //image width is 100 and taken extra 20 for padding
    
    var body: some View {
        ScrollView {
            GalleryCellView(rows: getRows(), columns: columns) { index in
                if index < self.images.count {
                    Button(action: { }) {
                        ImageGridView(image: self.images[index])
                    }
                }
            }.listRowInsets(EdgeInsets())
        }
    }
    
    func getRows() -> Int {
        //calculate rows based on image count and total columns
        let rows = Double(images.count)/Double(columns)
        return floor(rows) == rows ? Int(rows) : Int(rows+1.0)
        //if number of rows is a double values that means one more row is needed
    }
}

//Load image button cell
struct ImageGridView: View {
    let image: String
    var body: some View {
        Image(image)
            .renderingMode(.original)
            .frame(width:100, height:100)
            .cornerRadius(10)
    }
}

//Build cell view
struct GalleryCellView<Content: View>: View {
    let rows: Int
    let columns: Int
    let content: (Int) -> Content
    
    var body: some View {
        VStack(alignment: .leading, spacing : 0) {
            ForEach(0 ..< rows, id: \.self) { row in
                HStack(spacing : 10) {
                    ForEach(0 ..< self.columns, id: \.self) { column in
                        self.content((row * self.columns) + column)
                    }
                }.padding([.top, .bottom] , 5)
                .padding([.leading,.trailing], 10)
            }
        }.padding(10)
    }

    init(rows: Int, columns: Int, @ViewBuilder content: @escaping (Int) -> Content) {
        self.rows = rows
        self.columns = columns
        self.content = content
    }
}

Tested in Xcode Version 11.3 , iPhone 11 Pro Max & iPad Pro (12.9 - inch) simulators

Result in iPhone

Result in iPad

这篇关于如何让一个简单的 SwiftUI 作为 UITableView 加载(逻辑上!)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆