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

概述

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

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

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

    1. 动态刻度:按最大值自定义 Y 轴刻度
    • 3.1 为什么要自定义轴刻度?
    • 3.2 实现思路
    1. 最小值高光:Annotation + "大拇指"吸睛
    • 4.1 为什么要最小值?
    • 4.2 实现代码

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


3. 动态刻度:按最大值自定义 Y 轴刻度

3.1 为什么要自定义轴刻度?

默认坐标轴刻度依赖系统自动分配,有时会显得"参差不齐、无所适从",比如,若最大值是 7,系统可能给 10、5、0,显得不够精准。

3.2 实现思路

我们可以首先计算所有年份中挫折的最大值,然后根据它来更好的向用户呈现 y 轴刻度值的范围。

  1. 计算最大值let maxSbCount = sbCountInYears.values.max()!
  2. Stride 动态 :将刻度间隔设为 Double(maxSbCount / 2),并在 AxisMarks 中使用。

代码如下所示:

swift 复制代码
let sortedYears = sbCountInYears.keys.sorted(using: SortDescriptor(\.self, order: .reverse))
let maxSbCount = sbCountInYears.values.max { $0 < $1 }!

Chart {...}
.chartXAxis(.hidden)
.chartYAxis {
    //AxisMarks { value in
    // 使用挫折数量最大值来"精细化" y 轴的标签刻度
    AxisMarks(values: .stride(by: Double(maxSbCount / 2))) { value in
        if let y = value.as(Int.self), y >= 0 {
            AxisValueLabel("\(y)")
            AxisGridLine()
        }
    }
}
  • .stride(by:):每隔 maxSbCount / 2 绘制一条刻度;
  • value.as(Int.self):将坐标值转换为 Int 型的年份索引,避免自己转换带来的问题。

这样一来,我们就可以"量体裁衣、因时制宜" ------ 无论数据如何千变万化,刻度总能完美契合最大值,图表一看便知上下限,就问宝子们赞不赞呢?

4. 最小值高光:Annotation + "大拇指"吸睛

4.1 为什么要最小值?

除了最大值以外,对于挫折的最小值往往也值得小伙伴们"千锤百炼、别具匠心"的标注出来。

我们希望在挫折最小值对应的那个方柱上应用特殊效果(比如一个点赞的大拇指),来让用户投以钦佩的目光。

4.2 实现代码

swift 复制代码
let sortedYears = sbCountInYears.keys.sorted(using: SortDescriptor(\.self, order: .reverse))
let maxSbCount = sbCountInYears.values.max { $0 < $1 }!
let minSbCount = sbCountInYears.values.min { $0 < $1 }!

Chart {
    ForEach(sortedYears.indices, id: \.self) { yearIndex in
        
        let year = sortedYears[yearIndex]
        let sbCount = sbCountInYears[year]!
        let isThisYear = TimeMachine.shared.now.isSameYear(year)
        let isMinCount = minSbCount == sbCount
        
        BarMark(x: .value("年份序号", yearIndex), y: .value("次数", sbCount))
            .foregroundStyle(isThisYear ? .blue : .red)
            .annotation(position: .bottom, alignment: .center, spacing: 10) {
                Text(verbatim: "\(year)")
                    .foregroundStyle(.gray)
                    .font(.footnote)
                    .rotationEffect(.degrees(45))
                    .offset(x: 15)
            }
            .annotation(position: .top, spacing: 10) {
                Text(verbatim: "\(sbCount)")
                    .foregroundStyle(.red)
                    .font(.footnote.bold())
            }
            .annotation(position: .top, spacing: 30) {
                if isMinCount {
                    Image(systemName: "hand.thumbsup.fill")
                        .bold()
                        .foregroundStyle(.green.gradient)
                }
            }
    }
}
.chartXAxis(.hidden)
.chartYAxis {
    AxisMarks(values: .stride(by: Double(maxSbCount / 2))) { value in
        if let y = value.as(Int.self), y >= 0 {
            AxisValueLabel("\(y)")
            AxisGridLine()
        }
    }
}
  • 判断最小值if sbCount == minSbCount
  • 用 SFSymbol:Thumbs-up "点赞"图标,配合渐变色,让最小值脱颖而出。

在上面的代码中,我们主要做了以下几件事:

  • 计算所有挫折最小值对应的年份;
  • 在该年份柱子顶部用大拇指点赞;
  • 在每个柱子顶部标识出当前年份的挫折数

准备就绪,我们可以在 Xcode 预览中看一下运行效果:

正所谓:"画龙点睛、一鸣惊人" ------ 让挑剔的用户们一眼就认出最精彩的年份,棒棒哒!💯

在下一篇博文中,我们会用动画等精彩内容来为整个图表系列文章画上一枚完美的句号,期待吧!

总结

在本篇博文中,我们讨论了如何在柱状图上应用元素的最大最小值,小伙伴们值得拥有。

感谢观赏,我们下一篇再见啦!8-)

相关推荐
神奇的程序员5 天前
开发了一个进阶版Apple健康
swiftui·apple·apple watch
东坡肘子7 天前
Swift 还让你 Excited 吗?-- 肘子的 Swift 周报 #141
人工智能·swiftui·swift
sweet丶9 天前
Swift 元编程-Macro
swift
武子康9 天前
调查研究-183 Apple container:Mac 上用轻量 VM 跑 Linux 容器,Swift 会改写本地容器体验吗?
docker·容器·apple
影寂ldy12 天前
WinForm PictureBox控件 + ImageList组件 完整笔记
开发语言·笔记·swift
Deepzz13 天前
macOS 上调教第三方鼠标的一些经验:从滚动顺滑到输入法自动切换
macos·swift·鼠标
大熊猫侯佩13 天前
WWDC26:SwiftUI 8 的 @State 全新“懒加载”机制与最佳实践
性能优化·swiftui·observable·懒加载·state·swift宏·实例初始化
东坡肘子14 天前
WWDC 26:AI 帮你看完了,然后呢?-- 肘子的 Swift 周报 #140
人工智能·swiftui·swift
大熊猫侯佩14 天前
SwiftData 迁移深度指南:从入门到“填坑”(下集)
数据库·swift·编程语言
大熊猫侯佩14 天前
SwiftData 迁移深度指南:从入门到“填坑”(上集)
数据库·swift·编程语言