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

这篇具有很好参考价值的文章主要介绍了iOS 17(SwiftUI 5.0)带来的图表(Charts)新类型:“大饼”与“甜甜圈”。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

概览

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

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

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

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

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

Let’s go!!!😃


“大饼"与"甜甜圈”

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


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


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

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

代码如下:

@Model
final 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))

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

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

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

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

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

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

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

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

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

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

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

图表元素的选中

除了加入新图表类型以外,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)中。

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

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

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)

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

那么问题来了,能不能选中 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:) 修改器方法实现了饼图元素的选中:

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

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

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

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


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

  • 有用的知识又增加了:为何无法编译某些  WWDC 官方视频中的代码?

填上 WWDC 23 视频中的“坑”

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

  • Explore pie charts and interactivity in Swift Charts

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

首先我们要搞清楚的是, 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("饼图演示")
        }
    }
}

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

如上图所示: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("饼图演示")
        }
    }
}

效果如下:

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

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

总结

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

感谢观赏,再会!😎文章来源地址https://www.toymoban.com/news/detail-476995.html

到了这里,关于iOS 17(SwiftUI 5.0)带来的图表(Charts)新类型:“大饼”与“甜甜圈”的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++ Qt开发:Charts绘制各类图表详解

    Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍 TreeWidget 与 QCharts 的常用方法及灵活运用。 在之前的文章中笔者介绍了如何使

    2024年02月04日
    浏览(46)
  • 如何在 SwiftUI 中实现音频图表

    在可访问性方面,图表是复杂的事物之一。iOS 15 引入了一项名为“音频图表”的新功能。 下面我们将学习如何通过使用 accessibilityChartDescriptor 视图修饰符为任何 SwiftUI 视图构建音频表示,呈现类似自定义条形图视图或图像的图表。 让我们从在 SwiftUI 中构建一个简单的条形图

    2024年01月22日
    浏览(37)
  • Github每日精选(第87期):轻量级图表lightweight-charts

    lightweight-charts TradingView 轻量级图表是最小和最快的金融 HTML5 图表之一。 如果您想在网页上将财务数据显示为交互式图表而不影响网页加载速度和性能,轻量级图表库是您的最佳选择。 如果您想用交互式图表替换静态图像图表,它是您的最佳选择。该库的大小接近静态图像,

    2024年02月05日
    浏览(42)
  • web3:使用Docker-compose方式部署blockscout浏览器+charts图表

    最近做的项目,需要blockscout来部署一个区块链浏览器,至于blockscout是什么,咱们稍后出一篇文章专门介绍下,本次就先介绍一下如何使用Docker-compose方式部署blockscout,以及过程中遇到的种种坑

    2024年02月11日
    浏览(45)
  • iOS Xcode14 Charts集成时编译报错

    4.1.0解决了这两个问题 下载4.1.0的demo, 然后手动导入Charts Type ‘ChartDataSet’ does not conform to protocol ‘RangeReplaceableCollection’ Unavailable instance method ‘replaceSubrange(_:with:)’ was used to satisfy a requirement of protocol ‘RangeReplaceableCollection’ 解决方案: 在上面的扩展中加上下面的方法 参考

    2024年02月16日
    浏览(41)
  • 关于iOS:如何使用SwiftUI调整图片大小?

    我在Assets.xcassets中拥有很大的形象。 如何使用SwiftUI调整图像大小以缩小图像? 我试图设置框架,但不起作用: 1 2 Image(room.thumbnailImage)     .frame(width: 32.0, height: 32.0) 在Image上应用任何大小修改之前,应使用.resizable()。 1 2 Image(room.thumbnailImage).resizable() .frame(width: 32.0, height: 3

    2024年02月05日
    浏览(38)
  • SwiftUI适配iOS16导航控制器引起的闪退

    当时iPhone14系列手机升级到iOS16.5.1系统以后,当用户登录后再次退出登录闪退货登录后退出登录闪退。 由于SwiftUI提倡用struct代替类,导致悲剧产生,闪退时无法打印是那个结构体(class类实现时会打印类名),因为是struct也没有deinit跟踪内存是否泄漏。开启僵尸进程打印只有

    2024年02月11日
    浏览(54)
  • 如何将自定义字体添加到 iOS 应用程序(SwiftUI + 得意黑)

    Xcode Version 14.3 (14E222b) SwiftUI 得意黑 Smiley Sans https://github.com/atelier-anchor/smiley-sans/releases https://sarunw.com/posts/how-to-add-custom-fonts-to-ios-app/ 熊猫小账本 一个简洁的记账 App,用于记录日常消费开支收入,使用 iCloud 保存同步数据。 支持备注,自定义时间偶尔忘记记账也没关系。 搜索

    2024年02月13日
    浏览(58)
  • SwiftUI 实现一个 iOS 上 Files App 兼容的文件资源管理器

    在 SwiftUI 中自己白手起家写一个 iOS(或iPadOS)上迷你的文件资源管理器是有些难度滴,不过从 iOS 11 (2017年) 官方引入自家的 Files App 之后,我们就可以借助它的魔力轻松完成这一个功能了。 如上所示,我们使用 SwiftUI 原生功能完成了一个小巧的 iOS Files App 文件管理器,

    2024年02月10日
    浏览(55)
  • SwiftUI 视频教程之 快速播放本地视频,URL 播放视频,自动播放视频,视频结束通知VideoPlayer (iOS 14 +)

    iOS 14引入了viewAVKit的世界。显示实例的内容。在框架内部定义,让我们可以在本地播放视频,而无需从.SwiftUIVideoPlayerVideoPlayerAVPlayerViewAVKitSwiftUIUIKit VideoPlayer以 player 作为初始化参数,是 AVPlayer 的一个实例。 通过 URL 播放视频 带叠加层的视频播放器 自动播放视频 视频结束通

    2024年02月06日
    浏览(112)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包