返回顶部
首页 > 资讯 > 移动开发 >iOS 17(SwiftUI 5.0)带来的图表(Charts)新类型:“大饼”与“甜甜圈”
  • 398
分享到

iOS 17(SwiftUI 5.0)带来的图表(Charts)新类型:“大饼”与“甜甜圈”

Xcode15SwiftUI5.0iOS17WWDC23Charts饼图Pie原力计划 2023-09-09 10:09:13 398人浏览 八月长安
摘要

概览 WWDC 2023 为我们带来了 iOS 17,也为我们带来了 SwiftUI 5.0。 在 SwiftUI 新版中,Apple 增加了很多重磅功能,也对原有功能做了大幅度升级。 对于 Cha

在这里插入图片描述

概览

WWDC 2023 为我们带来了 iOS 17,也为我们带来了 SwiftUI 5.0。

在 SwiftUI 新版中,Apple 增加了很多重磅功能,也对原有功能做了大幅度升级。

对于 Charts 框架, 新增了饼图(Pie)类型并且加入了图表元素的原生选择功能。

在这里插入图片描述

在本篇博文中,就让我们一起来看看 SwiftUI 5.0 中这些激动人心的新功能吧!

Let’s Go!!!😃


“大饼"与"甜甜圈”

SwiftUI 5.0 在 4.0 众多图表类型基础之上,增加了全新的 饼图(Pie) 类型,我们可以通过它来更形象的展示图表数据。


注意:本文中的代码需要 Xcode 15 beta 版才能编译和运行。


下面是 SwiftUI 4.0 Charts 条状图的展示:

在这里插入图片描述

代码如下:

@Modelfinal class Item {    var name: String    var power: Int    var timestamp: Date        init(name: String, power: Int) {        self.name = name        self.power = power        timestamp = Date.now    }}Chart(items) { item in    BarMark(x: .value("power", item.power), stacking: .nORMalized)        .foregroundStyle(by: .value("name", item.name))}.chartLegend(.hidden)

想改为使用新饼图类型非常简单,只需将上面的 BarMark 换为 SectorMark 即可:

SectorMark(angle: .value("power", item.power))

在这里插入图片描述

我们可以调整每块“大饼”的空隙大小(angularInset)和圆角的弧度(cornerRadius):

SectorMark(angle: .value("power", item.power),angularInset: 3.0)    .cornerRadius(10)

在这里插入图片描述

值得注意的是:Charts 中饼图数据改变的动画效果做的也非常生动,SwiftUI 会自动根据状态的变化来合成自然的动画,无需多写半行代码。

不过,“大饼”虽好,“甜甜圈”更佳!

小孩子才做选择,光有“大饼”怎么行,我们连“甜甜圈”也统统都要了🍩!

实现“甜甜圈”(饼图空心)效果也很容易,我们只需调整 SectorMark 构造器中 innerRadius 属性的值即可:

SectorMark(angle: .value("power", item.power),           innerRadius: .ratio(innerRadius),           angularInset: 3.0)

在这里插入图片描述

好诱人的“甜甜圈”哦,有没有想吃的欲望呢?😉

图表元素的选中

除了加入新图表类型以外,SwiftUI 5.0 中 Charts 终于可以支持原生选择啦!

现在,我们无需再手动计算是图表中哪个元素被选中了,一切回归简洁:

struct LocationDetailsChart: View {  @Binding var rawSelectedDate: Date?  var body: some View {    Chart {      ForEach(data) { series in        ForEach(series.sales, id: \.day) { element in          LineMark(            x: .value("Day", element.day, unit: .day),            y: .value("Sales", element.sales)          )        }        .foregroundStyle(by: .value("City", series.city))        .symbol(by: .value("City", series.city))        .interpolationMethod(.catmullRom)      }    }    .chartXSelection(value: $rawSelectedDate)  }}

如上代码所示,我们使用 chartXSelection(value:) 修改器方法将当前选中的数据放入指定的绑定($rawSelectedDate)中。

在这里插入图片描述

除了选择单个图表元素,我们还可以选择一段范围内的元素集合

Chart(data) { series in  ForEach(series.sales, id: \.day) { element in    LineMark(      x: .value("Day", element.day, unit: .day),      y: .value("Sales", element.sales)    )  }  ...}.chartXSelection(value: $rawSelectedDate).chartXSelection(range: $rawSelectedRange)

在这里插入图片描述

那么问题来了,能不能选中 SwiftUI 5.0 图表新饼图类型的“大饼”元素呢?答案是肯定的!

下面是官方视频中对应的代码:

Chart(data, id: \.name) { element in  SectorMark(    angle: .value("Sales", element.sales),    innerRadius: .ratio(0.618),    angularInset: 1.5  )  .cornerRadius(5)  .foregroundStyle(by: .value("Name", element.name))  .opacity(element.name == selectedName ? 1.0 : 0.3)}.chartAngleSelection(value: $selectedAngle)

类似的, 通过 chartAngleSelection(value:) 修改器方法实现了饼图元素的选中:

在这里插入图片描述

不过,单从这段代码我们还是无法了解饼图元素选中的实现细节,比如:selectedAngle 是什么?它是如何转换成 selectedName 的呢?

为什么  在此要“犹抱琵琶半遮面”隐藏相关的细节呢?这不禁让我预感到它会是一个“坑”!

“坑”中的实现很可能在 iOS 17 正式版中会有所不同,所以  才会这样“遮遮掩掩”。


想要了解更多相关的内容,请移步如下链接观赏:


填上 WWDC 23 视频中的“坑”

WWDC 23 中对应内容的官方视频在下面,想要了解来龙去脉的小伙伴们可以“肆意”观赏:

尽管官方视频中的代码对如何完成饼图元素选中功能“闪烁其词”,但我们可以自己发挥“主观能动性”来大胆推测一下它的实现细节:即自己搞定“甜甜圈”的选中功能。

首先我们要搞清楚的是, chartAngleSelection 方法参数中的绑定值到底是个啥:

public func chartAngleSelection<P>(_ binding: Binding<P?>) -> some View where P : Plottable

我们可以通过监视 angleValue 的值,来看看它是如何跟随我们点击而变化的:

struct ContentView: View {    // 省略其它状态定义...    @Query private var items: [Item]    @State private var angleValue: Int?        var body: some View {        NavigationView {            List {                Chart(items) { item in                    SectorMark(angle: .value("power", item.power),   innerRadius: .ratio(innerRadius),   angularInset: 3.0                    )                    .cornerRadius(10)                    .foregroundStyle(by: .value("name", item.name))                }                .chartLegend(.hidden)                .chartAngleSelection($angleValue)                .onChange(of: angleValue){ old,new in                // 探查 angleValue 的真正面目...                    print("new angle value: \(new)")                }.padding(.vertical, 50)    ForEach(items) { ... }            }            .navigationTitle("饼图演示")        }    }}

在这里插入图片描述

如上图所示:chartAngleSelection($angleValue) 方法中的绑定是一个数量值(定义成浮点数类型也可以),我们还发现 angleValue 在 0° 位置附近点击时值越小,而在 360° 位置点击时值越大。

经过验证可得:angleValue 最大值就是 items 中所有元素 power 值的和!据此,我们可以轻松写一个从 angleValue 值找到对应选中 item 的方法:

private func findSltItem() -> Item? {    guard let slt = angleValue else { return nil }        var sum = 0    // 若 angleValue 小于第一个 item.power ,则表示选择的是图表中首张“大饼”!    var sltItem = items.first    for item in items {        sum += item.power        // 试探正确选中的饼图元素        if sum >= slt {            sltItem = item            break        }    }    return sltItem}

我们现在可以根据饼图中当前选中的 angleValue 值,轻松找到对应的 Item 了:

struct ContentView: View {    // 省略其它状态定义...    @Query private var items: [Item]    @State private var angleValue: Int?    @State private var sltItem: Item?        var body: some View {        NavigationView {            List {                Chart(items) { item in                    SectorMark(angle: .value("power", item.power),   innerRadius: .ratio(innerRadius),   angularInset: 3.0                    )                    .cornerRadius(10)                    .foregroundStyle(by: .value("name", item.name))                    .opacity(sltItem?.id == item.id ? 1.0 : 0.3)                }                .onChange(of: angleValue){ old,new in                    withAnimation {                        if let item = findSltItem() {if item == sltItem {    // 点击已被选中的元素时取消选择    sltItem = nil}else{    sltItem = item}                        }                    }                }.padding(.vertical, 50)    ForEach(items) {...}            }            .navigationTitle("饼图演示")        }    }}

效果如下:

在这里插入图片描述

看来为  WWDC 官方代码填坑的感觉也很不错哦😘💯

总结

在本篇博文中,我们介绍了 WWDC 23 最新 SwiftUI 5.0(iOS 17)中关于图表的新体验,学习了如何创建饼图(Pie)和实现 Charts 元素的选中功能,小伙伴们还不赶快操练起来!

感谢观赏,再会!😎

来源地址:https://blog.csdn.net/mydo/article/details/131121262

--结束END--

本文标题: iOS 17(SwiftUI 5.0)带来的图表(Charts)新类型:“大饼”与“甜甜圈”

本文链接: https://lsjlt.com/news/401284.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作