swiftui使用ScrollView实现左右滑动和上下滑动的效果,仿小红书页面

news2024/9/20 5:30:09

实现的效果如果所示,顶部的关注用户列表可以左右滑动,中间的内容区域是可以上下滚动的效果,点击顶部的toolbar也可以切换关注/发现/附近不同页面,实现翻页效果。

首页布局

这里使用了NavigationStack组件和tabViewStyle样式配置,tabViewStyle主要是为了实现左右滑动翻页的效果,就是关注,发现和附近的三个页面切换。还有TabView就是控制这三个页面切换的。toolbar+ToolbarItem是为了实现顶部的三个切换菜单还有顶部右侧的搜索按钮。BottomTab是我封装的一个底部四个tab菜单。FollowView是我封装的关注页面的视图。

布局代码:

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

import SwiftUI

struct Hongshu: View {
    @State var current = 0
    var body: some View {
        VStack {
            NavigationStack {
                ScrollView(content: {
                    TabView(selection: $current) {
                        // 关注
                        FollowView()
                        .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()
                            })
                        })
                        .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()
                            })
                        })
                        .tag(2)
                    }
                    .tabViewStyle(.page(indexDisplayMode: .never))
                    .frame(width: .infinity,
                           height: UIScreen.main.bounds.height - 100)
                })
                .background(.gray.opacity(0.3))
                .navigationBarTitleDisplayMode(.inline)
                .toolbar {
                    ToolbarItem(placement: .principal, content: {
                        HStack(spacing: 30) {
                            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")
                        }
                    })
                }
            }
            BottomTab()
        }
    }
}

#Preview {
    Hongshu()
}

BottomTab菜单

因为这里要自定义一个中间的红色按钮,所以没有使用系统自带的tabview视图,而是自己定义并实现的一个样式代码。

底部tab菜单实现代码:

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

import SwiftUI

struct BottomTab: View {
    @State var sel = "home"
    var body: some View {
        HStack {
            Spacer()
            Text("首页").onTapGesture {
                sel = "home"
            }.foregroundColor(sel == "home" ? .blue : .gray)
            Spacer()
            Text("购物").onTapGesture {
                sel = "shoping"
            }.foregroundColor(sel == "shoping" ? .blue : .gray)
            Spacer()
            Button(action: {
                sel = "publish"
            }, label: {
                Image(systemName: "plus")
                    .padding(.horizontal, 20)
                    .padding(.vertical, 10)
                    .foregroundColor(.white)
                    .background(.red)
                    .cornerRadius(5)
            })
            Spacer()
            Text("消息").onTapGesture {
                sel = "message"
            }.foregroundColor(sel == "message" ? .blue : .gray)
            Spacer()
            Text("我的").onTapGesture {
                sel = "my"
            }.foregroundColor(sel == "my" ? .blue : .gray)
            Spacer()
        }
    }
}

#Preview {
    BottomTab()
}

关注页面

这里的关注页面实现了顶部的左右滑动布局和内容区域的上下滑动布局。这里需要注意的是,因为我们使用了自定义的tabview视图实现了页面底部的菜单,所以这个页面的内容区域底部会被自定义的菜单视图盖住一部分,要给ScrollView添加padding(.bottom, 70)用于抵消这部分遮挡

关注页面代码:

//
//  FollowView.swift
//  SwiftBook
//
//  Created by Song on 2024/7/7.
//

import SwiftUI

struct FollowView: View {
    @State var users = ["xigua", "damangguo", "juzi", "hongyou", "liulian", "lizhi", "putao", "shanchu", "taozi"]

    var body: some View {
        // 关注的用户列表,可以左右滑动
        ScrollView(.vertical, showsIndicators: false) {
            ScrollView(.horizontal, showsIndicators: false) {
                HStack {
                    ForEach(users, id: \.self) { u in
                        Image(u).avator(w: 60, h: 60)
                    }
                }.padding(5)
            }
            ForEach(0 ..< 5) { _ in
                FollowUserCard()
            }
            Spacer()
        }.padding(.bottom, 70)
    }
}

#Preview {
    FollowView()
}

FollowUserCard

这是一个内容区域的card视图内容,为了方便复用,所以封装了一个组件实现。其中Rectangle是为了实现分割线效果,因为设置边框的话,只能给一个视图设置全部的边框,所以就没有使用边框

//
//  FollowUserCard.swift
//  SwiftBook
//
//  Created by Song on 2024/7/7.
//

import SwiftUI

struct FollowUserCard: View {
    @State var commit = ""
    var body: some View {
        VStack {
            // 分割线
            Rectangle()
                .fill(.black)
                .frame(height: 1)
            // 头像和更多
            HStack {
                Image("xigua").avator(w: 30, h: 30)
                Text("你好")
                Text("6天前").foregroundColor(.secondary)
                Spacer()
                Image(systemName: "ellipsis")
            }.padding(.horizontal)
            // 图片
            Image("xigua2")
                .resizable()
                .frame(width: .infinity, height: 300)
                .aspectRatio(contentMode: .fill)
            // 点赞分享
            HStack {
                Image(systemName: "square.and.arrow.up")
                Spacer()
                Image(systemName: "heart")
                Image(systemName: "star")
                Image(systemName: "ellipsis.message")
            }.padding(5)
            // 文字内容
            Text("无籽西瓜已进入香港市场。周至种西瓜有史已久,特别是近十多年来,新品种较多,有“周至红”、“兴城红”、“及醇酥”和“台黑”等一类脆瓤型西瓜").lineLimit(/*@START_MENU_TOKEN@*/2/*@END_MENU_TOKEN@*/)
                .padding(5)
            // 评论
            HStack {
                Image("xigua").avator(w: 30, h: 30).padding(5)
                TextField("请输入评论", text: $commit)
            }
            .background(.gray.opacity(0.1), in: RoundedRectangle(cornerRadius: 20))
            .padding(5)
        }
    }
}

#Preview {
    FollowUserCard()
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1939517.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在项目服务器部署git 并实现自动提交

以下场景适合在服务器当中使用git 方便提交代码&#xff0c;同时不需要外部的git仓库&#xff08;码云gitee或者github作为管理平台&#xff09;。依靠服务器本身ssh 连接协议做为git提交的地址&#xff0c;同时利用钩子自动同步项目代码 首先下载git sudo apt update sudo a…

Linux最直观的性能分析(热点分析)-编译perf并生成火焰图

本文先介绍了linux下perf工具的使用场景&#xff0c;然后对命令行安装和源码编译安装两种方式做了说明&#xff0c;接下来通过最简单的perf top命令给出perf的直观印象&#xff0c;最后通过perf record生成火焰图的方式说明如何发现进程中的函数热点。 一、perf工具介绍 per…

00 JavaWeb

学习资料&#xff1a;B站视频-黑马程序员JavaWeb基础教程 文章目录 JavaWeb1、JavaWeb简介2、 JavaWeb主要内容3、JavaWeb技术栈4、JavaWeb课程安排5、Web核心课程安排 JavaWeb 1、JavaWeb简介 Web&#xff1a;全球广域网&#xff0c;也称为万维网(www)&#xff0c;能够通过浏…

C++: 链表回文结构/分割链表题解

目录 1.链表的回文结构 分析 代码 2.链表分割 ​编辑分析 代码 1.链表的回文结构 分析 这道题的难点是空间复杂度为O&#xff08;1&#xff09; 结合逆置链表找到链表的中间节点就可以解决了。 先找到链表的中间节点&#xff0c;再对中间节点的下一个节点进行逆置&…

macbook pro大模型推理

安装与配置 参考github ollama 链接安装ollama。安装完成后,安装常用的模型,下载速度超快。 性能测试 在进行实际测试之前,我首先对模型进行了预处理,以确保其在 M3 Max 上能够高效运行。测试过程中,我主要关注了以下几个方面: 模型加载时间 加载大型模型通常需要较…

Python WebUIAPI:打造交互式Web界面的利器

Python WebUIAPI&#xff1a;打造交互式Web界面的利器 引言&#xff1a;交互式Web界面的革新 在当今快速发展的互联网时代&#xff0c;Web界面的交互性已成为衡量用户体验的重要标准。Python作为一门流行的编程语言&#xff0c;其生态中涌现出许多强大的库来帮助开发者构建交互…

组队学习——贝叶斯分类器

前言 本次数据继续沿用上一次主题的【组队学习——支持向量机-CSDN博客】 数据处理部分延续【组队学习——支持向量机】主题的处理办法对应划分训练集和验证集 模型选择 本次贝叶斯分类器模型的较多&#xff0c;常用的为高斯朴素贝叶斯分类器、多项式朴素贝叶斯分类器、伯努…

2024年超好用的4款PDF阅读器推荐

PDF文件已经是我们平时常常会接触到的文件&#xff0c;但是无论是阅读和编辑都需要依赖一些工具&#xff0c;所以今天给大家介绍的是4个很多人都在使用的PDF阅读器。 &#xff11;、福昕PDF阅读软件 这款PDF编辑器是一个大厂其他的产品&#xff0c;功能非常的强大&#xff0c;…

Build a Large Language Model (From Scratch)GPT-4o翻译和代码每行中文注释Ch4

目录 4 Implementing a GPT model from Scratch To Generate TextThis chapter covers4.1 Coding an LLM architectureListing 4.1 A placeholder GPT model architecture class4.2 Normalizing activations with layer normalization4.3 Implementing a feed forward network …

STM32CUBEMX_SPI_驱动WS2811灯带

STM32CUBEMX_SPI_驱动WS2811灯带 前言&#xff1a; 关于这种带芯片的之前我都是使用GPIO模拟时序&#xff0c;但是带来一个很大的弊端&#xff0c;那就是严重占用CPU资源&#xff0c;使得其他代码逻辑没办法正常执行了&#xff0c;想办法搞一个单片机的外设使用DMA功能&#xf…

LeetCode-day21-1186. 删除一次得到子数组最大和

LeetCode-day21-1186. 删除一次得到子数组最大和 题目描述示例示例1&#xff1a;示例2&#xff1a;示例3&#xff1a; 思路代码 题目描述 给你一个整数数组&#xff0c;返回它的某个 非空 子数组&#xff08;连续元素&#xff09;在执行一次可选的删除操作后&#xff0c;所能得…

【学术研究、研究热点、最新前沿】如何跟踪最新的论文

1.跟踪arxiv 使用https://www.arxivdaily.com/接收每天的推送。 2.跟踪热点文章的引用 使用semantic scholar。 3.跟踪某个学术大佬或者主题 3.1 使用web of science。 3.2 使用文献鸟 4.跟踪某个期刊

pico+unity3d 射线交互教程

前期配置&#xff1a;环境配置参考教程一&#xff0c;手部模型参考教程二&#xff0c;场景基于上一篇搭建。 最终效果&#xff1a;手部射线&#xff08;初始不可见&#xff09;对准 UI 显示&#xff0c;按下手柄 Trigger 键与可交互 UI&#xff08;如 Button、Toggle、Slider …

Android APP 基于RecyclerView框架工程(知识体系积累)

说明&#xff1a;这个简单的基于RecyclerView的框架作用在于自己可以将平时积累的一些有效demo整合起来&#xff08;比如音视频编解码的、opengles的以及其他也去方向的、随着项目增多&#xff0c;工程量的增加&#xff0c;后期想高效的分析和查找并不容易&#xff09;&#xf…

vscode 环境

这张截图显示的是在VS Code&#xff08;Visual Studio Code&#xff09;中选择Python解释器的界面。不同的Python解释器及其虚拟环境列出了可选项&#xff0c;用户可以根据需要选择合适的解释器来运行Python代码。以下是对截图中信息的详细解释&#xff1a; 解释器选择界面 当…

Java小技能:多级组织机构排序并返回树结构(包含每个层级的子节点和业务数据集合)

文章目录 引言I 实体定义1.1 部门1.2 用户组织机构中间表1.3 树状DTOII 抽取组织机构排序方法2.1 树状排序方法2.2 案例III 查询条件构建3.1 根据部门进行权限控制3.2 注入风险引言 需求: 根据组织机构进行数据授权控制,例如控制船舶、船舶设备、摄像头、港区查看权限。 一…

05_解封装和解码

1. 基本概念 容器就是一种文件格式&#xff0c;比如flv、mkv、mp4等。包含下面5种流以及文件头信息。 流是一种视频数据信息的传输方式&#xff0c;5种流&#xff1a;音频&#xff0c;视频&#xff0c;字幕&#xff0c;附件&#xff0c;数据。 包在ffmpeg中代表已经编码好的一…

【LINUX】pr_info函数开发摸索

1、打印开关可随时控制&#xff0c;开机如果要修改是否打印日志的话&#xff0c;需要修改代码重新编译内核才行&#xff0c;其实如果真要搞&#xff0c;应该有其他方法&#xff1b; 2、打印次数&#xff0c;当前代码里边写的是1000次&#xff0c;其实可以根据传参动态修改打印…

CUDA编程00 - 配置CUDA开发环境

第一步&#xff1a; 在一台装有Nvidia显卡和驱动的机器上&#xff0c;用nvidia-smi命令查看显卡所支持cuda版本 第二步&#xff1a; 到Nvidia官网下载CUDA Toolkit并安装&#xff0c;CUDA Toolkit Archive | NVIDIA Developer 安装时按提示下一步即可&#xff0c;安装完成用 …

Django cursor()增删改查和shell环境执行脚本

在Django中&#xff0c;cursor()方法是DatabaseWrapper对象&#xff08;由django.db.connectio提供&#xff09;的一个方法&#xff0c;用于创建一个游标对象。这个游标对象可以用来执行SQL命令&#xff0c;从而实现对数据库的增删改查操作。 查询&#xff08;Select&#xff0…