我在我的滚动视图中做了很多工作。一切都写好了,但有问题。我希望当用户停止滚动时,最后选择的值进入滚动视图的中心,并且所选值不会保留在中心的外部。
//
// TextView.swift
// Blood Pressure Tracker
//
// Created by MacBook on 27/09/2024.
//
import SwiftUI
struct HorizontalPicker<T: Hashable & CustomStringConvertible>: View {
@Binding var selectedValue: T // Binding for the selected value
let values: [T] // The array of values to display
let itemWidth: CGFloat = 80 // Width of each item
var body: some View {
VStack(alignment: .leading, spacing: 30) {
// Picker label
VStack {
Text("Select Value")
.fontWeight(.semibold)
ZStack {
Circle()
.frame(width: 60)
.foregroundColor(.green)
ScrollView(.horizontal, showsIndicators: false) {
ScrollViewReader { scrollView in
HStack(spacing: 20) {
// Add padding to ensure centering for the first and last elements
Spacer()
.frame(width: (UIScreen.main.bounds.width / 2) - (itemWidth / 2))
ForEach(values, id: \.self) { value in
Text("\(value.description)")
.font(.title2)
.fontWeight(.bold)
.padding()
.foregroundColor(selectedValue == value ? .white : .black)
.background(
Circle()
.frame(width: 40, height: 40)
.foregroundColor(selectedValue == value ? .blue : .clear)
)
.background(GeometryReader { geo in
Color.clear
.onChange(of: geo.frame(in: .global).midX) { midX in
// Calculate screen's center
let screenCenterX = UIScreen.main.bounds.width / 2
let distance = abs(midX - screenCenterX)
let tolerance: CGFloat = 20 // Adjust tolerance as needed
if distance < tolerance {
selectedValue = value
}
}
})
.onTapGesture {
// Scroll to the tapped value and select it
withAnimation {
selectedValue = value
scrollView.scrollTo(value, anchor: .center)
}
}
.id(value) // Assign id for ScrollViewReader
}
Spacer()
.frame(width: (UIScreen.main.bounds.width / 2) - (itemWidth / 2))
}
.onAppear {
// Scroll to the initially selected value when the view appears
DispatchQueue.main.async {
scrollView.scrollTo(selectedValue, anchor: .center)
}
}
}
}
.frame(height: 100) // Constrain the height of the ScrollView
}
}
Spacer()
// Show selected value
VStack(alignment: .leading) {
Text("Selected Value: \(selectedValue.description)")
}
}
.padding()
}
}
// Preview
struct HorizontalPickerPreview: View {
@State private var selectedInt = 110
@State private var selectedString = "Apple"
@State private var selectedFloat: Float = 5.5
var body: some View {
VStack(spacing: 30) {
// Integer picker
HorizontalPicker(selectedValue: $selectedInt, values: Array(80...200))
.frame(height: 150)
// String picker
HorizontalPicker(selectedValue: $selectedString, values: ["Apple", "Banana", "Cherry", "Date", "Elderberry"])
.frame(height: 150)
// Float picker
HorizontalPicker(selectedValue: $selectedFloat, values: stride(from: 1.0, through: 10.0, by: 0.5).map { Float($0) })
.frame(height: 150)
}
}
}
#Preview {
HorizontalPickerPreview()
}
这是我的代码。
我也来chatgpt。但我无法成功。我做什么?
看看这篇文章/教程。我想这可能正是您正在寻找的Hacking with Swift
具体看scrollTargetLayout和scrollTargetBehavior