我需要创建一个组件,使用户能够通过水平滚动SwiftUI图表来 Select 特定日期的值.组件的图像如下所示.

enter image description here

我的代码块如下:

struct SampleModel: Identifiable {
    var id = UUID()
    var date: String
    var value: Double
    var animate: Bool = false
}

struct ContentView: View {
    @State private var data = [
        SampleModel(date: "26\nFr", value: 9.2),
        SampleModel(date: "27\nSa", value: 12.5),
        SampleModel(date: "28\nSu", value: 15.0),
        SampleModel(date: "29\nMo", value: 20.0),
        SampleModel(date: "30\nTu", value: 5.0),
        SampleModel(date: "31\nWe", value: 7.0),
        SampleModel(date: "01\nTh", value: 3.0),
        SampleModel(date: "02\nFr", value: 20.0),
        SampleModel(date: "03\nSa", value: 5.0),
        SampleModel(date: "04\nSu", value: 7.0),
        SampleModel(date: "05\nMo", value: 3.0),
        SampleModel(date: "06\nTu", value: 10.0),
        SampleModel(date: "07\nWe", value: 21.0),
        SampleModel(date: "08\nTh", value: 14.0),
        SampleModel(date: "09\nFr", value: 10.0),
        SampleModel(date: "10\nSt", value: 7.0),
        SampleModel(date: "11\nSu", value: 15.0),
        SampleModel(date: "12\nMo", value: 17.0),
        SampleModel(date: "13\nTu", value: 29.0)
    ]
    @State private var scrollPosition: String = "26\nFr"
    @State var priceText: String = ""

    var body: some View {
        GeometryReader { geometry in
            VStack {
                Text(priceText)
                    .padding()

                Chart(data) { flight in
                    BarMark(x: .value("Date", flight.date),
                            y: .value("Price", flight.value),
                            width: 10.0)
                    .foregroundStyle(
                        Gradient(
                            colors: [
                                .blue,
                                .green
                            ]
                        )
                    )
                    .clipShape(RoundedRectangle(cornerRadius: 16))
                }
                .frame(width: .infinity, height: 180)
                .background(content: {
                    VStack {
                        Color.gray.frame(width: 1)
                        Color.clear.frame(height: 40)
                    }
                })
                .chartXAxis(content: {
                    AxisMarks(preset: .extended, position: .bottom) { value in
                        let label = value.as(String.self)!
                        AxisValueLabel(label)
                            .foregroundStyle(.gray)
                    }
                })
                .chartScrollableAxes(.horizontal)
                .chartXVisibleDomain(length: 11)
                .chartYAxis(.hidden)
                .chartScrollTargetBehavior(
                    .valueAligned(unit: 1)
                )
                .chartOverlay { proxy in
                    
                }
            }
            .frame(width: .infinity)

        }
    }
}

我需要观察水平滚动图表的内容偏移,以便使用proxy of chartOverlay根据位置检索中心值.有没有办法观察滚动图表的内容偏移量?或者是否有另一个Angular 来检索滚动图表中的中心值?

推荐答案

按照你的方法, 我增加了一些改进,我增加了左边距和右边距,允许在滚动时进行适当的 Select ,还定义了一个ScrollPosition,它是Int来跟踪您的数据所选的索引.

如果要更改顶部显示的值,只需根据需要将selectionText函数修改为返回.value

希望这就是你想要的.

enter image description here

import SwiftUI
import Charts

struct SampleModel: Identifiable {
    var id = UUID()
    var date: String
    var value: Double
    var animate: Bool = false
}

struct ContentView: View {
    @State private var data = [
        SampleModel(date: "26\nFr", value: 9.2),
        SampleModel(date: "27\nSa", value: 12.5),
        SampleModel(date: "28\nSu", value: 15.0),
        SampleModel(date: "29\nMo", value: 20.0),
        SampleModel(date: "30\nTu", value: 5.0),
        SampleModel(date: "31\nWe", value: 7.0),
        SampleModel(date: "01\nTh", value: 3.0),
        SampleModel(date: "02\nFr", value: 20.0),
        SampleModel(date: "03\nSa", value: 5.0),
        SampleModel(date: "04\nSu", value: 7.0),
        SampleModel(date: "05\nMo", value: 3.0),
        SampleModel(date: "06\nTu", value: 10.0),
        SampleModel(date: "07\nWe", value: 21.0),
        SampleModel(date: "08\nTh", value: 14.0),
        SampleModel(date: "09\nFr", value: 10.0),
        SampleModel(date: "10\nSt", value: 7.0),
        SampleModel(date: "11\nSu", value: 15.0),
        SampleModel(date: "12\nMo", value: 17.0),
        SampleModel(date: "13\nTu", value: 29.0)
    ]
    @State private var scrollPosition: Int = 0
    @State var priceText: String? = nil
    @State var selectedIndex: Int = 0

    var body: some View {
        GeometryReader { geometry in
            VStack {
                if let price = priceText {
                    Text(price)
                        .padding()
                }

                    Text(selectionText())
                        .padding()

                Chart(Array(zip(data.indices, data)), id: \.0) { index, flight in
                    BarMark(x: .value("Index", index),
                            y: .value("Price", flight.value), width: .fixed(10))
                    .foregroundStyle(
                        Gradient(
                            colors: [
                                .blue,
                                .green
                            ]
                        )
                    )
                    .clipShape(RoundedRectangle(cornerRadius: 16))
                }
                .frame(height: 180)
                .background(content: {
                    VStack {
                        Color.gray.frame(width: 1)
                        Color.clear.frame(height: 40)
                    }
                })
                .chartXAxis(content: {
                    AxisMarks(preset: .aligned, position: .bottom, values: .stride(by: 1)) { value in
                        let label = data[value.index].date
                        AxisValueLabel(label)
                            .foregroundStyle(.gray)
                    }
                })
                .chartXVisibleDomain(length: 10)
                .chartYAxis(.hidden)
                .chartScrollTargetBehavior(
                    .valueAligned(unit: 1)
                )
                .chartScrollableAxes(.horizontal)
                .chartScrollPosition(x: $scrollPosition)
                .contentMargins(Edge.Set(arrayLiteral: [.leading, .trailing]), geometry.size.width/2)
            }
        }
    }

    private func selectionText() -> String {
        guard scrollPosition >= .zero else {
            return data[.zero].date
        }

        guard scrollPosition < data.count else {
            return data[data.count - 1].date
        }

        return data[scrollPosition].date
    }
}

Ios相关问答推荐

React Native Text组件内部TextInput组件在iOS上的问题:在TextInput组件内部键入文本时失go 焦点

Nomb iOS 17.4.0中崩溃

使用CGAffineTransform旋转视图只起作用一次吗?

在SwiftUI中使用系统图像和色调创建圆形按钮

Xcode -Google Mobile Ads SDK在没有AppMeasurement的情况下初始化

安装新版本 XCode 15.0 后无法运行应用程序 XCode

如何在集合视图中创建装饰视图?

NavigationLink 只能在文本部分点击

如何在 SwiftUI 视图中显示协议视图?

使用 SwiftUI 显示多个 VNRecognizedObjectObservation 边界框时偏移量错误

SwiftUI 解除 .alert 弹出 NavigationView

如何在swiftui中更改可搜索的搜索图标 colored颜色

访问未定义的 stage_in 金属着色器参数

如何以编程方式调用视图控制器?

关闭所有打开的视图控制器的单个函数

swift 语言中的 null / nil

如何防止 iOS 设备上的显示屏变暗和关闭?

如何立即移动 CALayer(无动画)

打开 XIB 文件后 Xcode 6.3 冻结/挂起

我可以在 UIScrollView 中使用 UIRefreshControl 吗?