当前位置: 首页 > news >正文

wordpress 网站小模块计算机应用技术移动互联网开发

wordpress 网站小模块,计算机应用技术移动互联网开发,建设部网站中淼工程有限公司,哈尔滨seo一、引言在日常开发中,我们经常会遇到需要构建多个内容模块纵向排列的首页,尤其是图书类、视频类、资讯类 App,这种页面结构尤为常见。相比于简洁的登录页或设置页,这类长页面涉及滚动嵌套、模块拆分、布局一致性、性能优化等多个…

一、引言

在日常开发中,我们经常会遇到需要构建多个内容模块纵向排列的首页,尤其是图书类、视频类、资讯类 App,这种页面结构尤为常见。相比于简洁的登录页或设置页,这类长页面涉及滚动嵌套、模块拆分、布局一致性、性能优化等多个方面,对开发者提出了更高的要求。

本篇文章将以 iPhone 自带的「图书」App 为参考,带你一步步用 SwiftUI 实现一个结构清晰、组件化良好、交互自然的首页布局

我们的页面结构包括:

  • 顶部导航栏 + 右上角的「我的」按钮
  • 「继续阅读」模块(横向滑动)
  • 「之前读过」模块(网格或列表)
  • 「阅读目标」模块(包含进度统计)

虽然功能不复杂,但它很好地代表了一个典型的长页面结构。通过这个实战例子,我们将一起探讨 SwiftUI 在应对复杂页面时的布局技巧、组件划分策略以及实际编码方式。

二、页面整体结构:PHHomeView

在图书类 App 中,首页往往需要承载多个信息区域,并支持垂直滚动浏览。在 SwiftUI 中,这种长页面非常适合用 ScrollView 加上 VStack 的组合来搭建结构化内容。

我们将内容稍微进行一下简化,只保留 “继续阅读” 和 “之前读过” 还有 “阅读目标”。

下面是我们首页的主视图 PHHomeView 的代码结构节选:

struct PHHomeView: View {@ObservedObject var presenter = PHHomePresenter.sharedvar body: some View {ScrollView {VStack(alignment: .leading, spacing: 20) {Spacer(minLength: 20)// 继续阅读区域if let readingEpisode = presenter.readingEpisode {PHHomeContinueReadView(episode: readingEpisode)}// 之前读过区域if let recentlyViewedEpisodes = presenter.recentlyViewedEpisodes,!recentlyViewedEpisodes.isEmpty {PHHomeHistoryView(recentlyViewedEpisodes: recentlyViewedEpisodes)}// 阅读目标区域PHHomeGoalView().padding(.top, 24)Spacer(minLength: 40)}}.background(Color.gray.opacity(0.2)).toolbar {ToolbarItem(placement: .topBarTrailing) {Button {// 点击“我的”} label: {Image(systemName: "person.circle").foregroundColor(.black)}}}.navigationTitle("首页").onAppear {presenter.fetchReadingEpisode()presenter.fetchRecentlyViewedEpisodes()}}
}

📌 核心结构说明:

  1. 整体使用 ScrollView + VStack 实现长页面滚动:所有区域按顺序依次排列,形成一个流畅的滚动体验。
  2. 数据驱动视图内容是否显示:「继续阅读」与「之前读过」模块都基于 presenter 的数据条件渲染。
  3. 模块隔离良好,每个区域都是独立 View:比如 PHHomeContinueReadView、PHHomeHistoryView、PHHomeGoalView,便于复用与维护。
  4. 导航栏按钮与标题通过 .toolbar 和 .navigationTitle 设置:“我的”按钮使用系统图标,放在右上角。
  5. 页面数据在 .onAppear 时加载:保证首页每次展示时都能拿到最新内容。

三、继续阅读区域:PHHomeContinueReadView

这个模块是一个非常典型的 SwiftUI 区块式布局,由一个标题文本和一个自定义卡片组件组成。整体采用 VStack实现垂直排列,间距、边距控制都比较标准,适合初中级页面构建参考。

📄 代码如下:

struct PHHomeContinueReadView: View {var episode: PHEpisodeEntityvar body: some View {VStack(alignment: .leading, spacing: 10) {Text("继续阅读").font(.title2).fontWeight(.semibold).padding(.horizontal)PHHistoryCardView(episode: episode).padding(.horizontal, 24)}}
}

四、之前读过区域:PHHomeHistoryView

「之前读过」模块的结构与「继续阅读」类似,也是由标题加上一个滑动区域组成,区别在于这里使用了 ScrollView(.horizontal) 搭配 HStack,用于展示多个横向排列的卡片组件。

📄 对应代码如下:

struct PHHomeHistoryView: View {var recentlyViewedEpisodes: [PHEpisodeEntity]var body: some View {VStack(alignment: .leading, spacing: 10) {Text("之前读过").font(.title2).fontWeight(.semibold).padding(.horizontal)ScrollView(.horizontal, showsIndicators: false) {HStack(spacing: 12) {ForEach(recentlyViewedEpisodes, id: \.id) { episode inPHHistoryCardView(episode: episode)}}.padding(.horizontal, 24)}}}
}

🧱 布局解析:

  • 最外层依然是 VStack,结构一致,方便模块化管理;
  • 标题使用 .title2 + semibold 样式,与上一模块保持统一;
  • ScrollView(.horizontal) 实现横向滑动区域,并关闭默认滚动指示器;
  • 内容区域使用 HStack 横向排列所有卡片,每张卡片由 PHHistoryCardView 渲染;
  • 外部 .padding(.horizontal, 24) 保证整体边距一致,与上一模块的卡片对齐。

五、复用组件:PHHistoryCardView 卡片结构解析

在前面两个模块「继续阅读」和「之前读过」中,我们都使用了同一个组件 PHHistoryCardView 来展示单个剧集的信息。这种组件复用的方式可以大大提升开发效率,并保持 UI 风格一致。

下面是 PHHistoryCardView 的完整实现:

struct PHHistoryCardView: View {var episode: PHEpisodeEntityvar body: some View {HStack(spacing: 12) {// 封面图if let packageId = episode.packageId,let fileName = episode.episodeCoverFileName {Image(uiImage: PHFileManger.loadImage(packageId: packageId, imageName: fileName) ?? UIImage()).resizable().aspectRatio(599.0 / 337.0, contentMode: .fill).frame(width: 100, height: 56).clipped().cornerRadius(6)}// 剧集信息文本VStack(alignment: .leading, spacing: 4) {Text(episode.drama?.title ?? "未知剧名").font(.subheadline).foregroundColor(.white).lineLimit(1)Text(episode.title ?? "第 X 集").font(.caption).foregroundColor(.white.opacity(0.8)).lineLimit(1)Text("共 \(episode.cardList?.count ?? 0) 张卡片").font(.caption2).foregroundColor(.white.opacity(0.6))}Spacer()}.padding(.horizontal, 12).frame(height: 80).background(randomColor).cornerRadius(8)}var randomColor: Color {let colors: [Color] = [.red, .green, .blue]return colors.randomElement()!.opacity(0.3)}
}

🧱 布局结构说明:

  • 整体为 HStack:左侧封面图 + 中间文字信息 + 右侧空白占位 Spacer();
  • 封面图尺寸为 100 × 56,保持 16:9 比例,使用 .resizable() 和 .aspectRatio() 控制缩放行为;
  • 文字信息区使用 VStack 垂直排列三行文本,每行文字样式略有区分,强调主次;
  • 背景颜色为红/绿/蓝三选一,带透明度 0.3,当前主要用于调试或展示状态区别,后续可替换为统一主题色;
  • 外部加圆角 + 水平内边距,让卡片在页面中更加紧凑且不贴边。

这个组件设计追求简单、紧凑、信息清晰,适合在横向滑动视图中频繁出现。通过 PHHistoryCardView(episode:)这样的结构,我们可以在多个模块中共享样式逻辑,只需要传入数据即可灵活复用。

六、阅读目标区域:PHHomeGoalView

首页的尾部我们加入了一个带有进度环和统计信息的视图组件 —— PHHomeGoalView。这个模块相较前两个更为视觉化,包含一个弧形进度圈、文字信息和按钮,布局略复杂一些,但仍然可以通过 SwiftUI 的组合方式轻松实现。

📄 对应代码如下:

struct PHHomeGoalView: View {var body: some View {VStack(alignment: .center, spacing: 10) {Text("阅读目标").font(.title2).fontWeight(.semibold).padding(.horizontal)Text("坚持每天阅读,积累知识和灵感").font(.subheadline).foregroundColor(.gray).padding(.horizontal).padding(.bottom, 10)ZStack {let circleSize: CGFloat = 200// 背景圆Circle().stroke(Color.gray.opacity(0.2), lineWidth: 10).frame(width: circleSize, height: circleSize)// 弧形进度(目前写死 50%)Path { path inlet center = CGPoint(x: circleSize / 2, y: circleSize / 2)let radius = circleSize / 2let startAngle = Angle(degrees: 90)let endAngle = Angle(degrees: 90 + 360 * 0.5)path.addArc(center: center,radius: radius,startAngle: startAngle,endAngle: endAngle,clockwise: false)}.stroke(Color.blue, lineWidth: 10).frame(width: circleSize, height: circleSize)// 中间文字VStack {Text("今日阅读").font(.headline).foregroundColor(.blue)Text("0:00").font(.largeTitle).fontWeight(.bold).foregroundColor(.blue)Text("(阅读目标10分钟)").font(.subheadline).foregroundColor(.gray)}}.padding(.bottom, 20)// 开始阅读按钮Button(action: {print("开始阅读")}) {Text("开始阅读").font(.headline).padding().frame(maxWidth: .infinity).background(Color.blue).foregroundColor(.white).cornerRadius(8)}}.padding().background(Color.white)}
}

🧱 布局结构说明:

  • 外层使用 VStack 垂直排列标题、副标题、图形区域和按钮;
  • 视觉核心是 ZStack,用于绘制背景圆形 + 蓝色进度弧线 + 居中文字;
  • 弧线绘制使用 Path 手动构造半圆(起始角度 90° 向后延展 180°),当前进度写死为 50%,可后续接入动态进度;
  • 文字排布在弧形中央,大小层次清晰,强调阅读时长;
  • 最下方的“开始阅读”按钮占满整行,使用 .frame(maxWidth: .infinity) 与 .cornerRadius 实现标准按钮样式;
  • 整个组件嵌套在白色背景 + 内边距中,保持与其他模块视觉一致。

这个模块展示了 SwiftUI 中 Path 与 ZStack 的组合能力,也验证了即使不借助 Core Graphics 或第三方库,也能轻松绘制出可定制的图形视图。

七、结语

本文通过 SwiftUI 分模块构建了一个图书类 App 的首页页面,页面内容参考了 iPhone 自带的图书应用,包含以下几个区域:

  • 顶部导航栏(带“我的”按钮)
  • 继续阅读模块(单卡片展示)
  • 之前读过模块(横向滑动卡片列表)
  • 阅读目标模块(弧形进度 + 阅读时间)

整个首页采用了 ScrollView + VStack 作为主结构,配合多个独立组件完成页面构建。每个模块都遵循了清晰的层级布局与样式一致性,体现了 SwiftUI 在构建长页面时的简洁性与灵活性。

在这个过程中我们重点实践了:

  • 如何将多个逻辑区域封装为可维护的独立视图
  • 如何控制模块之间的间距与对齐
  • 如何使用 ZStack 和 Path 绘制简单图形组件

SwiftUI 的组件组合理念,使得即使面对复杂的长页面,也能通过良好的结构拆分和样式统一,实现一套清晰、高可维护的实现方式。

http://www.dtcms.com/a/501640.html

相关文章:

  • 湖北微网站建设报价伪静态 多个网站
  • 网站空间数据企业名称登记管理规定
  • 建设安全备案登入那个网站syntax highlighter for wordpress
  • 网站建设 电话营销网站建设需求指引
  • 关键词搜索工具爱站网制冷设备东莞网站建设
  • 东莞网站关键词优化效果网站备案主体信息变更
  • 建网站的客户城市建设管理网站
  • 网站的投票系统怎么做海南省住房公积金管理局官网
  • 成都科技网站建设热佛山网站建设乐云seo在线制作
  • 郴州公司做网站平台公司债务风险
  • 一个小型网站开发成本新增备案网站
  • 辽宁省建设银行招聘网站WordPress产品录入
  • 产品做网站推广九江做网站的公司
  • 广东省建设厅官方网站网址网站php环境搭建
  • 公司网站搭建教程百合怎么doi怎么做网站
  • 襄阳网络公司 网站建设深圳品牌型网站建设
  • 域名备案期间网站热狗seo外包
  • 沈阳建站程序做产品类网站有哪些内容
  • 网站建设与维护要用到代码吗公司网站管理属于什么职位
  • 外汇网站开发在线crm什么软件好
  • 深圳网站建设首选全通网络口碑好的网页设计服务
  • 兼容手机的网站网站app的意义
  • vs网站毕业设计怎么做一般电商都是在哪些网站上做
  • php公司网站汕头网站制作后缀
  • 07 标识符命名规则
  • python网站开发的优势合肥制作网站价格
  • 兴安盟老区建设促进会网站湘潭天元建设集团有限公司董事长
  • 公司做网络推广哪个网站好wordpress 装修主题
  • 手机网站模板源码外贸公司网站模板
  • 海南网络公司网站建设桂林 网站建站