swiftui使用ScrollView实现左右滑动和上下滑动的效果,仿小红书页面
实现的效果如果所示,顶部的关注用户列表可以左右滑动,中间的内容区域是可以上下滚动的效果,点击顶部的toolbar也可以切换关注/发现/附近不同页面,实现翻页效果。
首页布局
这里使用了NavigationStack组件和tabViewStyle样式配置,tabViewStyle主要是为了实现左右滑动翻页的效果,就是关注,发现和附近的三个页面切换。还有TabView就是控制这三个页面切换的。toolbar+ToolbarItem是为了实现顶部的三个切换菜单还有顶部右侧的搜索按钮。BottomTab是我封装的一个底部四个tab菜单。FollowView是我封装的关注页面的视图。
布局代码:
//
// Hongshu.swift
// SwiftBook
//
// Created by Song on 2024/7/6.
//import SwiftUIstruct Hongshu: View {@State var current = 0var 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 SwiftUIstruct 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 SwiftUIstruct 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 inImage(u).avator(w: 60, h: 60)}}.padding(5)}ForEach(0 ..< 5) { _ inFollowUserCard()}Spacer()}.padding(.bottom, 70)}
}#Preview {FollowView()
}
FollowUserCard
这是一个内容区域的card视图内容,为了方便复用,所以封装了一个组件实现。其中Rectangle是为了实现分割线效果,因为设置边框的话,只能给一个视图设置全部的边框,所以就没有使用边框
//
// FollowUserCard.swift
// SwiftBook
//
// Created by Song on 2024/7/7.
//import SwiftUIstruct 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()
}
相关文章:
swiftui使用ScrollView实现左右滑动和上下滑动的效果,仿小红书页面
实现的效果如果所示,顶部的关注用户列表可以左右滑动,中间的内容区域是可以上下滚动的效果,点击顶部的toolbar也可以切换关注/发现/附近不同页面,实现翻页效果。 首页布局 这里使用了NavigationStack组件和tabViewStyle样式配置…...
深入理解并使用 MySQL 的 SUBSTRING_INDEX 函数
引言 在处理字符串数据时,经常需要根据特定的分隔符来分割字符串或提取字符串的特定部分。MySQL 提供了一个非常有用的函数 SUBSTRING_INDEX 来简化这类操作。本文将详细介绍 SUBSTRING_INDEX 的使用方法、语法,以及通过实际案例来展示其在数据库查询中…...
elementUI在手机端使用遇到的问题总结
之前的博客有写过用vue2elementUI封装手机端选择器picker组件,支持单选、多选、远程搜索多选,最终真机调试的时候发现有很多细节样式需要调整。此篇博客记录下我调试过程中遇到的问题和解决方法。 一、手机真机怎么连电脑本地代码调试? 1.确…...
【初阶数据结构】5.栈和队列
文章目录 1.栈1.1 概念与结构1.2 栈的实现2.队列2.1 概念与结构2.2 队列的实现3.栈和队列算法题3.1 有效的括号3.2 用队列实现栈3.3 用栈实现队列3.4 设计循环队列 1.栈 1.1 概念与结构 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操…...
高通Android 12 设置Global属性为null问题
1、最近在做app调用framework.jar需求,尝试在frameworks/base/packages/SettingsProvider/res/values/defaults.xml增加属性 <integer name"def_xxxxx">1</integer> 2、在frameworks\base\packages\SettingsProvider\src\com\android\provide…...
Xcode代码静态分析:构建无缺陷代码的秘诀
Xcode代码静态分析:构建无缺陷代码的秘诀 在软件开发过程中,代码质量是至关重要的。Xcode作为Apple的官方集成开发环境(IDE),提供了强大的代码静态分析工具,帮助开发者在编写代码时发现潜在的错误和问题。…...
Qt各个版本安装的保姆级教程
文章目录 前言Qt简介下载Qt安装包安装Qt找到Qt的快捷方式总结 前言 Qt是一款跨平台的C图形用户界面应用程序开发框架,广泛应用于桌面软件、嵌入式软件、移动应用等领域。Qt的强大之处在于其高度的模块化和丰富的工具集,可以帮助开发者快速、高效地构建出…...
数学建模--优劣解距离法TOPSIS
目录 简介 TOPSIS法的基本步骤 延伸 优劣解距离法(TOPSIS)的历史发展和应用领域有哪些? 历史发展 应用领域 如何准确计算TOPSIS中的理想解(PIS)和负理想解(NIS)? TOPSIS方法在…...
Springboot开发之 Excel 处理工具(三) -- EasyPoi 简介
引言 Springboot开发之 Excel 处理工具(一) – Apache POISpringboot开发之 Excel 处理工具(二)-- Easyexcel EasyPoi是一款基于 Apache POI 的高效 Java 工具库,专为简化 Excel 和 Word 文档的操作而设计。以下是对…...
【BUG】已解决:python setup.py bdist_wheel did not run successfully.
已解决:python setup.py bdist_wheel did not run successfully. 目录 已解决:python setup.py bdist_wheel did not run successfully. 【常见模块错误】 解决办法: 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主…...
Java 中如何支持任意格式的压缩和解压缩
👆🏻👆🏻👆🏻关注博主,让你的代码变得更加优雅。 前言 Hutool 是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率…...
从零开始实现大语言模型(八):Layer Normalization
1. 前言 Layer Normalization是深度学习实践中已经被证明非常有效的一种解决梯度消失或梯度爆炸问题,以提升神经网络训练效率及稳定性的方法。OpenAI的GPT系列大语言模型使用Layer Normalization对多头注意力模块,前馈神经网络模块以及最后的输出层的输入张量做变换,使shap…...
<数据集>混凝土缺陷检测数据集<目标检测>
数据集格式:VOCYOLO格式 图片数量:7353张 标注数量(xml文件个数):7353 标注数量(txt文件个数):7353 标注类别数:6 标注类别名称:[exposed reinforcement, rust stain, Crack, Spalling, Efflorescence…...
【LabVIEW作业篇 - 3】:数组相加、for循环创建二位数组、数组练习(求最大最小值、平均值、中位数、提取范围内的数据、排序)
文章目录 数组相加for循环实现直接使用加函数 for循环创建二位数组数组练习 数组相加 要求:用两种方法实现两个数组相加 for循环实现 在前面板中分别创建两个数值类型的一维数组,并设置相应的值,然后在程序框图中创建一个for循环ÿ…...
Unity动画系统(4)
6.3 动画系统高级1-1_哔哩哔哩_bilibili p333- 声音组件添加 using System.Collections; using System.Collections.Generic; using UnityEngine; public class RobotAnimationController : MonoBehaviour { [Header("平滑过渡时间")] [Range(0,3)] publ…...
React基础学习-Day08
React基础学习-Day08 React生命周期(旧)(新)(函数组件) (旧) 在 React 16 版本之前,React 使用了一套不同的生命周期方法。这些生命周期方法在 React 16 中仍然可以使用…...
Flowable的学习一
今日项目用到了Flowable。简单记录下。 学习中 参考了网上资料: 工作流-Activiti7-基础讲解_activity工作流-CSDN博客 https://juejin.cn/post/7158342433615380517 flowable实战(九)flowable数据库表中流程实例、活动实例、任务实例三者…...
django-vue-admin项目运行
文本主要对django-vue-admin项目进行了简要介绍,并且对前后端进行了源码安装和运行。在此基础上可作为管理系统二次开发的基础框架。 一.django-vue-admin简介和安装 1.简介 django-vue-admin项目是基于RBAC模型权限控制的中小型应用的基础开发平台,采…...
4. docker镜像、Dockerfile
docker镜像、Dockerfile 一、docker镜像1、镜像介绍2、镜像核心技术 二、Dockerfile定制镜像1、Dockerfile使用流程1.1 编写Dockerfile1.2、构建镜像1.3 创建容器测试镜像定制操作 2、Dockerfile常用指令 三、部署springcloud微服务架构的商品秒杀项目1、部署项目需要的基础服务…...
智能水果保鲜度检测:基于YOLO和深度学习的完整实现
引言 水果新鲜程度直接影响其口感和营养价值。为了提高水果品质管理的效率和准确性,本文介绍了一种基于深度学习的水果新鲜程度检测系统。该系统包括用户界面,利用YOLO(You Only Look Once)v8/v7/v6/v5模型进行水果新鲜程度检测&…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
