SwiftUI Charts 入门:从零到一,笑谈“柱”状人生(一)

概述

从 iOS 16 开始,Apple 为小伙伴们带来了全新的 SwiftUI Charts 框架,让我们可以用极少的代码便捷地绘制折线图、柱状图、饼图以及各种图,可谓"画龙点睛,一步登天"。

本系列文章将带宝子们从无到有,逐步拆解示例 TodayInYearsSetbacksComparisonChart 的源代码,并着重揭示几个开发中的"鬼斧神工"与"隐藏套路"。

在本篇博文中,您将学到如下内容:

  1. 缘起
  2. 基本柱状图骨架的搭建

想用 Charts 为自己精妙绝伦的 App 如虎添翼吗?看这篇就对啦! 无需等待,让我们马上开始 Charts 大冒险吧! Let's go!!!;)


前言:为何要用 Charts?

SwiftUI Charts 可以让小伙伴们"得心应手、游刃有余"地绘制精美图表:不再为折线的拐角、色彩渐变、大量 UIKit 代码而头疼。在数据驱动下,几行声明式代码就能呈现炫酷可交互的图表。


想知道在 Charts 诞生之前我们是怎么在 SwiftUI 中绘制图表的吗?小伙伴们猛戳下面观赏就对啦:


然而,Charts 既有强大能力,也自有对于初学者来说"闻鸡起舞"之难点:如 X 轴标签重叠、x/y 轴刻度自定义、动画、嵌入 Form 时多余的分隔线等等。

正所谓:"盘根错节、扑朔迷离"。

So,接下来我们就用示例来逐一破解它们吧。


在 iOS 17(SwiftUI 5.0)中,苹果为图表增加了新的呈现类型,感兴趣的宝子们请到如下链接观赏精彩的内容:


0. 缘起

本文将会实现一个 TodayInYearsSetbacksComparisonChart 图表视图,它用来以柱状图的形式比较历年中发生的挫折数量:

从上图可以清楚的看到,今年的挫折在往年中算得上是最少的,所以我们不得不由衷的为其竖一个大拇指儿👍🏻。

我们所有年份的挫折数据都放在下面的字典中,其中 Key 代表年份,Value 则表示对应年份的挫折数量:

swift 复制代码
let sbCountInYears: [Int: Int]

有了这些基础的构思和数据模型,我们下面可以大施拳脚啦。

1. 基本柱状图骨架的搭建

首先,创建 TodayInYearsSetbacksComparisonChart 视图,并为其填充如下代码:

swift 复制代码
struct TodayInYearsSetbacksComparisonChart: View {
        
    let sbCountInYears: [Int: Int]
    
    var body: some View {
        let sortedYears = sbCountInYears.keys.sorted(using: SortDescriptor(\.self, order: .reverse))
        
        
        Chart {
            ForEach(sortedYears.indices, id: \.self) { yearIndex in
                
                let year = sortedYears[yearIndex]
                let sbCount = sbCountInYears[year]!
                let isThisYear = TimeMachine.shared.now.isSameYear(year)
                
                BarMark(x: .value("年份序号", yearIndex), y: .value("次数", sbCount))
                    .foregroundStyle(isThisYear ? .blue : .red)
            }
        }
        .padding(.vertical)
        .frame(minHeight: 150)
    }
}
  • ForEach :遍历 [Int: Int],按年份排序(示例中是倒序)。
  • BarMark :最基础的柱状图元素,用 .value(label, value) 绑定数据。

上面代码有几个需要注意的地方:

  • 使用逆序排序让最近的年份排在最前面;
  • 使用局部值来简化 SwiftUI 的布局逻辑;

这样,我们就能在屏幕上绘制一组从最近年份到最早年份的柱状图,"一目了然":

不过,目前图表 x 轴的标签显示的不太正确,应该显示的是年份,你给我玩什么"偶数游戏"是要闹哪样呢?

在接下来的文章中,我们将继续走向完善上述图表的"康庄大道",不见不散哦!

总结

在本篇博文中,我们讨论了 SwiftUI 中图表框架 Charts 存在的真谛,并初步实现了一个简陋的 TodayInYearsSetbacksComparisonChart 示例图表视图。

感谢观赏,下一篇再会吧!8-)

相关推荐
非专业程序员Ping5 小时前
HarfBuzz概览
android·ios·swift·font
Daniel_Coder10 小时前
iOS Widget 开发-8:手动刷新 Widget:WidgetCenter 与刷新控制实践
ios·swift·widget·1024程序员节·widgetcenter
HarderCoder17 小时前
Swift 中基础概念:「函数」与「方法」
swift
西西弗Sisyphus1 天前
将用于 Swift 微调模型的 JSON Lines(JSONL)格式数据集,转换为适用于 Qwen VL 模型微调的 JSON 格式
swift·qwen3
songgeb2 天前
🧩 iOS DiffableDataSource 死锁问题记录
ios·swift
大熊猫侯佩2 天前
【大话码游之 Observation 传说】上集:月光宝盒里的计数玄机
swiftui·swift·weak·observable·self·引用循环·observations
HarderCoder2 天前
Swift 方法全解:实例方法、mutating 方法与类型方法一本通
swift
HarderCoder2 天前
Swift 类型转换实用指北:从 is / as 到 Any/AnyObject 的完整路线
swift
HarderCoder2 天前
Swift 嵌套类型:在复杂类型内部优雅地组织枚举、结构体与协议
swift
齐行超2 天前
SwiftUI NavigatorStack 导航容器
ios·swiftui·navigationstack·navigationpath·navigationlink