SwiftUI小功能模块系列
0001、SwiftUI自定义Tabbar动画效果
0002、SwiftUI自定义3D动画导航抽屉效果
0003、SwiftUI搭建瀑布流-交错网格-效果
技术:SwiftUI3.0、瀑布流、交错网格
运行环境:
SwiftUI3.0 + Xcode13.4.1 + MacOS12.5 + iPhone Simulator iPhone 13 Pro Max
使用SwiftUI搭建一个做一个瀑布流-交错网格


思路:
1.创建主窗口
2.再搭建瀑布流-交错网格页面
3.添加模型数据
4.添加一个测试瀑布流-交错网格的加减按钮


随机找十张图片即可
New Group 命名为 View

New File 选择SwiftUI View类型 命名为Home


New File 选择SwiftUI View类型 命名为StaggeredGrid


New Group 命名为 Model

New File 选择SwiftUI View类型 命名为Post ,并且删除预览视图 改造成一个模型


主要是展示主窗口
Home
//
// ContentView.swift
// Shared
//
// Created by 李宇鸿 on 2022/8/13.
//
import SwiftUI
struct ContentView: View {
var body: some View {
Home()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
思路
- 创建导航
- 创建瀑布流布局-交错网格
- 创建数据
- 创建瀑布流展示的View
//
// Home.swift
// StaggeredGrid (iOS)
//
// Created by 李宇鸿 on 2022/8/13.
//
import SwiftUI
struct Home: View {
@State var posts : [Post] = []
// To show dynamic
@State var columns : Int = 2
// Smooth Hero Effect
@Namespace var animation
var body: some View {
// 创建导航
NavigationView{
// 设置中心内容
StaggeredGrid(columns:columns, list:posts, content: { post in
// 在这里创建帖子卡片
PostCard(post: post)
.matchedGeometryEffect(id: post.id, in: animation)
.onAppear{
print(post.imageURL)
}
})
.padding(.horizontal)
.navigationTitle("Staggered Grid")
.toolbar{
ToolbarItem(placement: .navigationBarTrailing) {
Button{
columns += 1
}label: {
Image(systemName: "plus")
}
}
ToolbarItem(placement: .navigationBarTrailing) {
Button{
columns = max(columns - 1,1)
}label: {
Image(systemName: "minus")
}
}
}
// 动画……
.animation(.easeInOut, value: columns)
}
// 出现的时候
.onAppear{
for index in 1...10 {
posts.append(Post(imageURL: "post\(index)"))
}
}
}
}
struct Home_Previews: PreviewProvider {
static var previews: some View {
Home()
}
}
// 因为我们声明T为可识别的…
// 所以我们需要传递可识别集合/数组…
struct PostCard : View {
var post : Post
var body: some View{
Image(post.imageURL)
.resizable()
.aspectRatio(contentMode: .fit)
.cornerRadius(10)
}
}
主要是做 瀑布流-交错网格
思路
- 提供外界初始化操作 - 尽量提供额外多个属性 让外界调用 - 比如 : 网格的列数、间距、是否显示滚动条、数据的数量、网格的展示View
- 添加演示±的瀑布流-交错网格效果演示
- 展示瀑布流-交错网格内容 - 优化瀑布流-交错网格加载
//
// StaggeredGrid.swift
// StaggeredGrid (iOS)
//
// Created by 李宇鸿 on 2022/8/13.
//
import SwiftUI
// 自定义视图构建器…… Content 外界传递的视图
// T -> 是用来保存可识别的数据集合… 外界传递的列表模型数据
struct StaggeredGrid<Content: View, T : Identifiable>: View where T: Hashable {
// 它将从集合中返回每个对象来构建视图…
var content: (T) -> Content
var list : [T]
// 列……
var columns : Int
// 属性
var showsIndicators : Bool
var spacing : CGFloat
// 提供构造函数的闭包
init(columns: Int, showsIndicators: Bool = false,spacing : CGFloat = 10, list:[T], @ViewBuilder content: @escaping(T)->Content){
self.content = content
self.list = list
self.spacing = spacing
self.showsIndicators = showsIndicators
self.columns = columns
}
// 交错网格功能…
func setUpList()->[[T]]{
// 创建列的空子数组计数…
var gridArray : [[T]] = Array(repeating: [], count: columns)
// 用于Vstack导向视图的拆分数组…
var currentIndex : Int = 0
for object in list{
gridArray[currentIndex].append(object)
// increasing index count
// and resetting fi overbounds the columns count...
//增加索引计数
//和重置fi越界列计数…
if currentIndex == (columns - 1){
currentIndex = 0
}
else{
currentIndex += 1
}
}
return gridArray
}
var body: some View {
ScrollView(.vertical,showsIndicators: showsIndicators)
{
HStack(alignment:.top){
ForEach(setUpList(),id:\.self){ columnsData in
// 优化使用LazyStack…
LazyVStack(spacing:spacing){
ForEach(columnsData){ object in
content(object)
}
}
}
}
//只有垂直填充…
//水平填充将是用户可选的…
.padding(.vertical)
}
}
}
struct StaggeredGrid_Previews: PreviewProvider {
static var previews: some View {
// StaggeredGrid()
// 预览的是主窗口页面
ContentView()
}
}
import SwiftUI
struct Post: Identifiable,Hashable {
var id = UUID().uuidString
var imageURL: String
}