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()
}

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

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

相关文章

zerotier安装后设备在线,两个设备无法ping通

来源 组 NAS&#xff0c; 软路由&#xff0c;内网穿透&#xff0c;远程访问&#xff0c;安装了 zerotier&#xff0c;无法ping通 方法 修改windows防火墙&#xff0c;Configure the Windows firewall to allow pings。 Search for and open Windows Firewall.Select Advance…

Node.js快速入门

Node.js 1、Node.js介绍与安装 官网&#xff1a;https://nodejs.cn/ 介绍&#xff1a;简单的说 Node.js 就是运行在服务端的 JavaScript。 Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台。 Node.js 是一个事件驱动 I/O 服务端 JavaScript 环境&#xff0c;基…

Python | Leetcode Python题解之第274题H指数

题目&#xff1a; 题解&#xff1a; class Solution:def hIndex(self, citations: List[int]) -> int:left,right 0,len(citations)while left<right:# 1 防止死循环mid (leftright1)>>1cnt 0for v in citations:if v>mid:cnt1if cnt>mid:# 要找的答案在…

php并发提高20倍

opcache扩展 负责 opcode 缓存&#xff0c;专注于提高 PHP 代码的执行效率 apcu扩展 用于应用级数据缓存&#xff0c;专注于减少 I/O 操作和计算密集型任务的重复执行 大杀器swoole扩展 在实际应用中&#xff0c;Swoole 能够将 PHP 服务器的并发处理能力提升数十倍到数百倍…

哈希 -- 简单实现

在STL库中&#xff0c;有map和set两个关联式容器&#xff0c;这两个容器的底层都是以红黑树为底层。但是在后续的发展过程中&#xff0c;我们发现有些场景的数据不适合用红黑树进行存储&#xff0c;所以有人就发明了底层为哈希表的map和set,称为unordered_map 和 unordered_set…

C语言中的控制语句(一):if语句

文章目录 &#x1f34a;自我介绍&#x1f34a;if 的单分支语句&#x1f34a;a.if 单分支判断&#x1f34a;b.if单分支选择判断 &#x1f34a;if多分支语句&#x1f34a;if多分支选择判断 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以&#xff1a;点赞关注评论收藏&a…

web前端 React 框架面试200题(七)

面试题 185. 如果想要在组件第一次加载后获取该组件的dom元素&#xff0c;应当在以下哪个生命周期中进行 &#xff1f; A&#xff1a;componentDidUpdate() B&#xff1a;componentDidMount() C&#xff1a;componentWillUnmount() D&#xff1a;shouldComponentUpdate()答案&…

HarmonyOS应用开发者高级认证,Next版本发布后最新题库 - 多选题序号2

基础认证题库请移步&#xff1a;HarmonyOS应用开发者基础认证题库 注&#xff1a;有读者反馈&#xff0c;题库的代码块比较多&#xff0c;打开文章时会卡死。所以笔者将题库拆分&#xff0c;单选题20个为一组&#xff0c;多选题10个为一组&#xff0c;题库目录如下&#xff0c;…

MMCV 核心组件分析(一):整体概述

概述 MMCV 是计算机视觉研究的基础库&#xff0c;并提供以下功能。

(11)Python引领金融前沿:投资组合优化实战案例

1. 前言 本篇文章为 Python 对金融的投资组合优化的示例。投资组合优化是从一组可用的投资组合中选择最佳投资组合的过程&#xff0c;目的是最大限度地提高回报和降低风险。 投资组合优化是从一组可用的投资组合中选择最佳投资组合的过程&#xff0c;目的是最大限度地提高回报…

订单管理系统需求规范

1. 引言 1.1 目的 本文档旨在明确描述订单管理系统的功能、非功能性需求以及约束条件&#xff0c;以指导系统的分析、设计、开发、测试和部署。 1.2 范围 本系统将支持在线订单处理&#xff0c;从客户下单到完成配送的全过程管理&#xff0c;包括库存管理、支付处理、订单跟…

TypeScript与面向对象编程

引言 TypeScript简介 TypeScript是JavaScript的一个超集&#xff0c;由微软开发&#xff0c;它在JavaScript的基础上添加了类型系统和对ES6的新特性的支持。TypeScript最终会被编译成纯JavaScript代码&#xff0c;以便在任何支持JavaScript的环境中运行。 面向对象编程&…

单例模式_Golang

目录 一、单例模式 1.1 基本概念 1.2 使用场景 二、Golang实现 2.1 懒汉模式&#xff08;Lazy Loading&#xff09; 一、单例模式 1.1 基本概念 一个类只能生成一个实例&#xff0c;且该类能自行创建这个实例的一种模式,这个定义个人感觉可以拆的通俗一些,在项目的生命周…

电子电器架构 - SOA架构软件平台

电子电器架构 - SOA架构软件平台 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无…

Spring通过工厂方法进行配置

在Spring的世界中&#xff0c; 我们通常会利用 xml配置文件 或者 annotation注解方式来配置bean实例&#xff01; 在第一种利用 xml配置文件 方式中&#xff0c; 还包括如下三小类 反射模式&#xff08;我们前面的所有配置都是这种模式&#xff09;工厂方法模式Factory Bean模…

Composition API实现逻辑复用

抽离逻辑代码到一个函数函数命名约定为useXxxx格式&#xff08;react Hooks也是&#xff09;在setup中去引用这个函数 如下经典鼠标位置例子&#xff1a; // useMousePosition.ts import { onMounted, onUnmounted, ref } from "vue";const useMousePosition () &…

【Spark官方文档部分翻译】RDD编程指南(RDD Programming Guide)

写在前面 内容如何选择 本翻译只翻译本人认为精华的部分&#xff0c;本人认为的Spark的一些核心理念&#xff0c;编程思想。一些特别基础的操作包括但不限于搭建环境就不在此赘述了。 配套版本 本系列基于Spark 3.3.1&#xff0c;Scala 2.12.10&#xff0c;进行翻译总结 原…

Linux+InternStudio 关卡(test)

任务地址&#xff1a; https://github.com/InternLM/Tutorial/blob/camp3/docs/L0/Linux/task.md 文档 https://github.com/InternLM/Tutorial/blob/camp3/docs/L0/Linux/readme.md 任务 ssh连接 端口映射 gradio页面 笔记&#xff1a; 1.端口映射阶段&#xff1a;输入密…

编译linux kernel时,如何增加一个include路径?

编译linux kernel时增加一个include路径的方法&#xff0c;使用 EXTRA_CFLAGS : make O/path/to/build/dir ARCHyour_arch CROSS_COMPILEyour_cross_compiler EXTRA_CFLAGS"-I/your/new/path" 其中 EXTRA_CFLAGS"-I/your/new/path" 就是要增加的include路径…

线段树分治+可撤销并查集 学习笔记

题目一般是给你边或者点的出现时间区间[Li,Ri]&#xff0c;问你在某些时间里1能访问到的点或者点的数量。 先考虑暴力的思路&#xff0c;就是对于一个具体的时间节点&#xff0c;我们去暴力地得知当前边/点是否出现&#xff0c;并且跑图查看是否联通。 由于一个具体的时间节点…