iOS16使用SwiftUI Charts创建折线图实现实例
<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>前言</li><li>简单折线图</li><li>其他图表</li><li>让折线图增加可访问性</li><li>为折线图添加多个数据序列</li><li>显示步数系列</li><li>结论</li></ul></div><p class="maodian"></p><h2>前言</h2><p>苹果在 WWDC 2022 上推出了 SwiftUI 图表,这使得在 SwiftUI 视图中创建图表变得异常简单。图表是以丰富的格式呈现可视化数据的一种很好的方式,而且易于理解。本文展示了如何用比以前从头开始创建同样的折线图少得多的代码轻松创建折线图。此外,自定义图表的外观和感觉以及使图表中的信息易于访问也是非常容易的。</p>
<p>如以前的文章所示,不使用 SwiftUI Charts 也可以创建一个折线图。然而,使用 Charts 框架可以提供大量的图表来探索对应用程序中的数据最有效的方法,从而使它变得更加容易。</p>
<p class="maodian"></p><h2>简单折线图</h2>
<p>从包含一周的步数的数据开始,类似于 <strong>在SwiftUI中创建折线图</strong> 中使用的数据。定义一个结构来保存日期和该日的步数,并为当前周创建一个数组。</p>
<div class="jb51code"><pre class="brush:cpp;">struct StepCount: Identifiable {
let id = UUID()
let weekday: Date
let steps: Int
init(day: String, steps: Int) {
let formatter = DateFormatter()
formatter.dateFormat = "yyyyMMdd"
self.weekday = formatter.date(from: day) ?? Date.distantPast
self.steps = steps
}
}
let currentWeek: = [
StepCount(day: "20220717", steps: 4200),
StepCount(day: "20220718", steps: 15000),
StepCount(day: "20220719", steps: 2800),
StepCount(day: "20220720", steps: 10800),
StepCount(day: "20220721", steps: 5300),
StepCount(day: "20220722", steps: 10400),
StepCount(day: "20220723", steps: 4000)
]
</pre></div>
<p>要创建一个折线图,为步数数据中的每个元素创建一个带有LineMark的图表。在<code>LineMark</code>的 X 值中指定工作日,在 Y 值中指定步数。注意,还需要导入<code>Charts</code>框架。</p>
<p>这就为步数数据创建了一个线形图。由于只有一个系列的数据,<code>ForEach</code> 可以省略,数据可以直接传递给 <code>Chart</code> 初始化器。两个部分都产生相同的折线图。</p>
<div class="jb51code"><pre class="brush:cpp;">import SwiftUI
import Charts
struct LineChart1: View {
var body: some View {
VStack {
GroupBox ( "Line Chart - Step Count") {
Chart {
ForEach(currentWeek) {
LineMark(
x: .value("Week Day", $0.weekday, unit: .day),
y: .value("Step Count", $0.steps)
)
}
}
}
GroupBox ( "Line Chart - Step Count") {
Chart(currentWeek) {
LineMark(
x: .value("Week Day", $0.weekday, unit: .day),
y: .value("Step Count", $0.steps)
)
}
}
}
}
}
</pre></div>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202211/20221108083737047.png" /></p>
<p>使用 SwiftUI Charts 创建的折线图显示每日步数</p>
<p class="maodian"></p><h2>其他图表</h2>
<p>SwiftUI Charts 有许多可用的图表选项。这些可以通过将图表标记从<code>LineMark</code>改为其他类型的标记(如<code>BarMark</code>)来生成条形图。</p>
<div class="jb51code"><pre class="brush:cpp;">struct OtherCharts: View {
var body: some View {
VStack {
GroupBox ( "Line Chart - Step count") {
Chart(currentWeek) {
LineMark(
x: .value("Week Day", $0.weekday, unit: .day),
y: .value("Step Count", $0.steps)
)
}
}
GroupBox ( "Bar Chart - Step count") {
Chart(currentWeek) {
BarMark(
x: .value("Week Day", $0.weekday, unit: .day),
y: .value("Step Count", $0.steps)
)
}
}
GroupBox ( "Point Chart - Step count") {
Chart(currentWeek) {
PointMark(
x: .value("Week Day", $0.weekday, unit: .day),
y: .value("Step Count", $0.steps)
)
}
}
GroupBox ( "Rectangle Chart - Step count") {
Chart(currentWeek) {
RectangleMark(
x: .value("Week Day", $0.weekday, unit: .day),
y: .value("Step Count", $0.steps)
)
}
}
GroupBox ( "Area Chart - Step count") {
Chart(currentWeek) {
AreaMark(
x: .value("Week Day", $0.weekday, unit: .day),
y: .value("Step Count", $0.steps)
)
}
}
}
}
}
</pre></div>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202211/20221108083737048.png" /></p>
<p>使用 SwiftUI 图表创建的其他图表类型,显示每日步数</p>
<p class="maodian"></p><h2>让折线图增加可访问性</h2>
<p>将图表植入 SwiftUI 的一个好处是,可以很容易地使用 <strong>可访问性修饰符</strong> 使图表变得可访问。为 StepCount 添加一个计算属性,将数据返回为一个字符串,可由 <code>accessibilityLabel</code> 使用。然后为图表中的每个标记添加可访问性标签和值。</p>
<div class="jb51code"><pre class="brush:cpp;">struct StepCount: Identifiable {
let id = UUID()
let weekday: Date
let steps: Int
init(day: String, steps: Int) {
let formatter = DateFormatter()
formatter.dateFormat = "yyyyMMdd"
self.weekday = formatter.date(from: day) ?? Date.distantPast
self.steps = steps
}
var weekdayString: String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyyMMdd"
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .none
dateFormatter.locale = Locale(identifier: "en_US")
returndateFormatter.string(from: weekday)
}
}
</pre></div>
<div class="jb51code"><pre class="brush:cpp;"> GroupBox ( "Line Chart - Daily Step Count") {
Chart(currentWeek) {
LineMark(
x: .value("Week Day", $0.weekday, unit: .day),
y: .value("Step Count", $0.steps)
)
.accessibilityLabel($0.weekdayString)
.accessibilityValue("\($0.steps) Steps")
}
}
</pre></div>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202211/20221108083737049.png" /></p>
<p>在 SwiftUI 图表中使折线图可访问性</p>
<p class="maodian"></p><h2>为折线图添加多个数据序列</h2>
<p>折线图是比较两个不同系列数据的好方法。创建第二个系列,即前一周的步数,并将这两个系列添加到折线图中。</p>
<div class="jb51code"><pre class="brush:cpp;">let previousWeek: = [
StepCount(day: "20220710", steps: 15800),
StepCount(day: "20220711", steps: 7300),
StepCount(day: "20220712", steps: 8200),
StepCount(day: "20220713", steps: 25600),
StepCount(day: "20220714", steps: 16100),
StepCount(day: "20220715", steps: 16500),
StepCount(day: "20220716", steps: 3200)
]
let currentWeek: = [
StepCount(day: "20220717", steps: 4200),
StepCount(day: "20220718", steps: 15000),
StepCount(day: "20220719", steps: 2800),
StepCount(day: "20220720", steps: 10800),
StepCount(day: "20220721", steps: 5300),
StepCount(day: "20220722", steps: 10400),
StepCount(day: "20220723", steps: 4000)
]
let stepData = [
(period: "Current Week", data: currentWeek),
(period: "Previous Week", data: previousWeek)
]
</pre></div>
<p>第一次尝试添加这两个系列的数据没有按预期显示。</p>
<div class="jb51code"><pre class="brush:cpp;">struct LineChart2: View {
var body: some View {
GroupBox ( "Line Chart - Daily Step Count") {
Chart {
ForEach(stepData, id: \.period) {
ForEach($0.data) {
LineMark(
x: .value("Week Day", $0.weekday, unit: .day),
y: .value("Step Count", $0.steps)
)
.accessibilityLabel($0.weekdayString)
.accessibilityValue("\($0.steps) Steps")
}
}
}
}
}
}
</pre></div>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202211/20221108083737050.png" /></p>
<p>第一次尝试在 SwiftUI Charts 中创建一个包含两个系列步数数据的折线图</p>
<p class="maodian"></p><h2>显示步数系列</h2>
<p>在折线图中显示多个基于工作日的步数系列</p>
<p>最初尝试在折线图中显示多组数据的问题是X轴使用了日期。当前的周数紧接着上一周,所以每一个点都是沿着X轴线性递增绘制的。</p>
<p>有必要只用工作日作为X轴的数值,这样所有的周日都在同一个X坐标上绘制。</p>
<p>在<code>StepCount</code>中添加另一个计算属性,以便以字符串格式返回工作日的短日。</p>
<div class="jb51code"><pre class="brush:cpp;">struct StepCount: Identifiable {
. . .
var shortDay: String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEE"
returndateFormatter.string(from: weekday)
}
}
</pre></div>
<p>此 <code>shortDay</code> 用于图表中 <code>LineMarks</code> 的 x 值。另外,前景的样式设置为基于<code>stepCount</code>数组的周期。折线图使用 x 轴的工作日来显示两周的步数,以便在周之间进行比较。</p>
<div class="jb51code"><pre class="brush:cpp;">struct LineChart3: View {
var body: some View {
VStack {
GroupBox ( "Line Chart - Daily Step Count") {
Chart {
ForEach(stepData, id: \.period) { steps in
ForEach(steps.data) {
LineMark(
x: .value("Week Day", $0.shortDay),
y: .value("Step Count", $0.steps)
)
.foregroundStyle(by: .value("Week", steps.period))
.accessibilityLabel($0.weekdayString)
.accessibilityValue("\($0.steps) Steps")
}
}
}
.frame(height:400)
}
.padding()
Spacer()
}
}
}
</pre></div>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202211/20221108083737051.png" /></p>
<p>SwiftUI 图表中带有两个系列的步数数据的折线图</p>
<p class="maodian"></p><h2>结论</h2>
<p>在 SwiftUI Charts 中还有很多东西可以探索。使用这个框架显然比从头开始建立你自己的图表要好。</p>
<p>以上就是iOS16使用SwiftUI Charts创建折线图实现实例的详细内容,更多关于iOS16 SwiftUI Charts折线图的资料请关注琼殿技术社区其它相关文章!</p>
<div class="art_xg">
<b>您可能感兴趣的文章:</b><ul><li>iOS底层实例解析Swift闭包及OC闭包</li><li>IOS开发Swift 与 OC相互调用详解</li><li>Flutter iOS开发OC混编Swift动态库和静态库问题填坑</li><li>iOS Swift读取本地json文件报错的解决方法</li><li>IOS 开发之swift中手势的实例详解</li><li>iOS Swift Lazy var View失效问题解决</li></ul>
</div>
</div>
<!--endmain-->
頁:
[1]