首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SwiftUI中居中的"CollectionView“

SwiftUI中居中的"CollectionView“
EN

Stack Overflow用户
提问于 2020-06-30 15:49:03
回答 1查看 573关注 0票数 2

苹果介绍了在SwiftUI中制作CollectionViews的方法,通过使用新的LazyVGrid和嵌入ScrollView中的LazyHGrid。

但是,如果最后一行的元素少于列数,则这些项显示为与leading对齐。可以将最后一行项目与.center对齐

Swift 5.3 - SwiftUI 2.0 - Xcode 12.0b - macOS 11大压力

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-30 17:17:02

我不知道这在LazyGrid中是否可行,但这里有一个可能的解决方法:

只要数据数组中的项数量不均匀,就可以简单地将最后一项放在VStack中并将其居中对齐。

我已经为您实现了一个演示:

简单:

代码语言:javascript
复制
import SwiftUI

//MARK: - Content

struct ContentView: View {
    //Your data
    let data = Array(0...4)
    
    let columns = [
        GridItem(.fixed(160)),
        GridItem(.fixed(160))
    ]
    
    //Same spacing both for items inside grid and between grid and stack
    let rowSpacing: CGFloat = 32
        
    //If number of items is odd, remove the last one from grid and add to stack
    var gridData: [Int] { data.count%2 == 1 ? data.dropLast() : data }
    var stackData: Int? { data.count%2 == 1 ? data.last : nil }
    
    var body: some View {
        ScrollView {
            VStack(spacing: rowSpacing) {
                LazyVGrid(columns: columns, spacing: rowSpacing) {
                    ForEach(gridData, id: \.self) { i in
                        ItemView(i: i)
                    }
                }
                if let data = stackData {
                    VStack {
                        ItemView(i: data)
                    }
                }
            }
        }
    }
}

//MARK: - Item

struct ItemView: View {
    let i: Int
    
    var body: some View {
        Rectangle()
            .frame(width: 160, height: 240)
            .foregroundColor(Color.green)
            .overlay(Text(String(i)).foregroundColor(.white))
    }
}

可选的,可重用的:

代码语言:javascript
复制
//MARK: - Data

struct SampleData: Identifiable {
    let id: Int
    var text: String
}


//MARK: - View

struct ContentView: View {
    //Your data
    let data = [SampleData(id: 0, text: "A"), SampleData(id: 1, text: "B"), SampleData(id: 2, text: "C")]
    
    let columns = [
        GridItem(.fixed(160)),
        GridItem(.fixed(160))
    ]
    
    var body: some View {
        ScrollView {
            CenteredLazyVGrid(data, columns: columns, spacing: 32) { i in
                ItemView(i: i.id)
            }
        }
    }
}

//MARK: - Item

struct ItemView: View {
    let i: Int
    
    var body: some View {
        Rectangle()
            .frame(width: 160, height: 240)
            .foregroundColor(Color.green)
            .overlay(Text(String(i)).foregroundColor(.white))
    }
}

//MARK: - Centered Grid View

struct CenteredLazyVGrid<Data, Content>: View where Data: RandomAccessCollection, Content: View, /*Data: Hashable, */Data.Element: Identifiable {
    private var data: Data
    //private var id: KeyPath<Data.Element, ID>
    private var columns: [GridItem]
    private var alignment: HorizontalAlignment = .center
    private var spacing: CGFloat? = nil
    private var pinnedViews: PinnedScrollableViews = []
    private var content: (Data.Element) -> Content
    
    init(_ data: Data, /*id: KeyPath<Data.Element, ID>, */columns: [GridItem], alignment: HorizontalAlignment = .center, spacing: CGFloat?
            = nil, pinnedViews: PinnedScrollableViews = .init(), content: @escaping (Data.Element) -> Content) {
        self.data = data
        //self.id = id
        self.columns = columns
        self.alignment = alignment
        self.spacing = spacing
        self.pinnedViews = pinnedViews
        self.content = content
    }
    
    private var gridData: [Data.Element] { data.count%2 == 1 ? data.dropLast() : data as! [Data.Element] }
    private var stackData: Data.Element? { data.count%2 == 1 ? data.last : nil }
    
    var body: some View {
        VStack(spacing: spacing) {
            LazyVGrid(columns: columns, alignment: alignment, spacing: spacing, pinnedViews: pinnedViews) {
                ForEach(gridData/*, id: id*/) { i in
                    content(i)
                }
            }
            if let data = stackData {
                VStack {
                    content(data)
                }
            }
        }
    }
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62652655

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档