swiftui中封装一个carditem视图,结合toolbar实现滚动的瀑布流,仿小红书首页

实现的效果如上图所示,支持左右滑动切换页面,也支持点击顶部的toolbar菜单切换页面,每个页面里面的每一项都是一个carditem.swift,这是我封装的一个card组件,用于展示每一个card内容,carditem.swift内容如下:

//
//  CardItem.swift
//  SwiftBook
//
//  Created by Song on 2024/7/6.
//

import SwiftUI

struct CardItem: View {
    // 传递过来的图片和昵称
    var preImg = ""
    var avatar = ""
    var nickname = ""
    var distance = ""

    var body: some View {
        VStack {
            Image(preImg)
                .resizable()
                .aspectRatio(contentMode: .fit)
            HStack {
                HStack {
                    Image(avatar)
                        .resizable()
                        .frame(width: 20, height: 20)
                        .aspectRatio(contentMode: .fit)
                        .mask(Circle())
                    Text(nickname)
                }
                Spacer()
                Text("\(distance)km")
            }
        }
        .padding()
        .background(.white)
        .cornerRadius(10)
    }
}

#Preview {
    CardItem()
}

这个组件封装出来的效果如图所示:里面使用到的就是水平布局和垂直布局,还有一个Image组件


 

首页实现

然后就是首页里面的toolbar使用,以及NavigationStack和TabView,还有tabViewStyle,还有navigationBarTitleDisplayMode,还有ToolbarItem。简单讲一下使用他们的必要性以及作用。

NavigationStack是导航栈,要配合TabView一起使用,才能达到TabView的效果。

TabView:是实现点击每一项toolbar实现页面切换的必备视图

tabViewStyle:是为了使用tabview的page样式,以此实现页面切换的效果,并设置indexDisplayMode为never,让切换页面之间不显示小白点,就是轮播图。还有一种是点击底部tab的效果。

navigationBarTitleDisplayMode:为了让顶部toolbar和内容之间没有空白间隙,设置inline模式。

toolbar+ToolbarItem:为了实现顶部的toolbar菜单效果。还有顶部右侧的搜索图标显示。

首页代码内容:

//
//  Hongshu.swift
//  SwiftBook
//
//  Created by Song on 2024/7/6.
//

import SwiftUI

struct Hongshu: View {
    @State var current = 0
    var body: some View {
        NavigationStack {
            ScrollView(content: {
                TabView(selection: $current) {
                    HStack(content: {
                        VStack(content: {
                            CardItem(preImg: "juzi", avatar: "juzi", nickname: "11111", distance: "555")
                            CardItem(preImg: "putao", avatar: "putao", nickname: "putao", distance: "11")
                            CardItem(preImg: "shanchu", avatar: "xigua", nickname: "山竹", distance: "53")
                            Spacer()
                        })
                        VStack(content: {
                            CardItem(preImg: "hongyou", avatar: "liulian", nickname: "liula", distance: "11")
                            CardItem(preImg: "taozi", avatar: "xigua2", nickname: "山竹", distance: "53")
                            CardItem(preImg: "lizhi", avatar: "xigua2", nickname: "山竹", distance: "53")
                            Spacer()
                        })
                    })
                    .padding(.horizontal)
                    .tag(0)
                    HStack(content: {
                        VStack(content: {
                            CardItem(preImg: "taozi", avatar: "taozi", nickname: "11111", distance: "555")
                            CardItem(preImg: "xigua", avatar: "xigua", nickname: "putao", distance: "11")
                            CardItem(preImg: "hongyou", avatar: "xigua", nickname: "山竹", distance: "53")
                            Spacer()
                        })
                        VStack(content: {
                            CardItem(preImg: "liulian", avatar: "liulian", nickname: "liula", distance: "11")
                            CardItem(preImg: "xigua2", avatar: "xigua2", nickname: "山竹", distance: "53")
                            Spacer()
                        })
                    })
                    .padding(.horizontal)
                    .tag(1)
                    HStack(content: {
                        VStack(content: {
                            CardItem(preImg: "xigua", avatar: "taozi", nickname: "11111", distance: "555")
                            CardItem(preImg: "default", avatar: "xigua", nickname: "putao", distance: "11")
                            CardItem(preImg: "xigua2", avatar: "xigua", nickname: "山竹", distance: "53")
                            Spacer()
                        })
                        VStack(content: {
                            CardItem(preImg: "liulian", avatar: "liulian", nickname: "liula", distance: "11")
                            CardItem(preImg: "taozi", avatar: "xigua2", nickname: "山竹", distance: "53")
                            Spacer()
                        })
                    })
                    .padding(.horizontal)
                    .tag(2)
                }
                .tabViewStyle(.page(indexDisplayMode: .never))
                .frame(width: UIScreen.main.bounds.width,
                       height: UIScreen.main.bounds.height)
            })
            .background(.gray.opacity(0.3))
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .principal, content: {
                    HStack {
                        Text("首页")
                            .foregroundColor(
                                current == 0 ? .blue : .black)
                            .onTapGesture {
                                current = 0
                            }
                        Text("附近")
                            .foregroundColor(
                                current == 1 ? .blue : .black)
                            .onTapGesture {
                                current = 1
                            }
                        Text("推荐")
                            .foregroundColor(
                                current == 2 ? .blue : .black)
                            .onTapGesture {
                                current = 2
                            }
                    }
                })
                ToolbarItem(placement: .topBarTrailing, content: {
                    HStack {
                        Image(systemName: "magnifyingglass")
                    }
                })
            }
            .tag("home")
        }
    }
}

#Preview {
    Hongshu()
}

  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1024小神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值