我有一个复杂的项目,但我创建了一个示例应用程序来获得帮助,因此用于渐变的代码和颜色可能看起来不专业。无论如何,我有一个滚动视图,其中有按钮列表。我只希望一次显示3个按钮,所以我已经降低了VStack的高度,用户可以滚动时,他们希望查看其他选项。
- 以下是条件:*
- 任何中心按钮都不应该有渐变,只有顶部可见和底部可见的按钮应该有渐变,所以用户知道还有更多的滚动。
- 如果任何时候,顶部或底部按钮被选择,则该按钮不应具有梯度,即对于3个按钮(顶部、中心和底部),如果选择顶部,则顶部不应具有渐变,中心不应具有渐变,按照条件1,并且在这种情况下只有底部将具有渐变。
所选按钮是带有蓝色边框的按钮。总是会有一个可见的按钮被选中,它可以是顶部,中心或底部按钮。
在我的代码中,除了选中的按钮外,所有按钮都有渐变。使用SwiftUI,我并没有找到一种简单的方法来知道哪个按钮目前在显示器上,以及它们在显示器上的位置。我想要达到的是ScrollView吗?
验证码:
import SwiftUI
import Foundation
@main
struct SampleAppApp: App {
var body: some Scene {
WindowGroup {
ContentView().frame(maxHeight: 140.0)
}
}
}
struct SimpleTestData {
let id = UUID()
let score: Int
}
struct ContentView: View {
@State private var currentlySelectedData: Int?
let results = [
SimpleTestData(score: 8),
SimpleTestData(score: 5),
SimpleTestData(score: 10),
SimpleTestData(score: 15),
SimpleTestData(score: 1)
]
var body: some View {
ScrollViewReader { proxy in
ScrollView(showsIndicators: false) {
VStack {
ForEach(results, id: \.id) { result in
makeDataButton(data: result.score).frame(height: 40.0).padding([.bottom, .top], 2.0)
}
}
}
}
}
@ViewBuilder func makeDataButton(data: Int) -> some View {
VStack {
Text("\(data)")
.frame(maxWidth: .infinity)
.foregroundColor(Color.black)
.onTapGesture {
self.currentlySelectedData = data
}
.background {
if currentlySelectedData == data {
RoundedRectangle(cornerRadius: 10)
.frame(width: 40 - 3, height: 40 - 3)
.foregroundColor(Color.white)
.border(Color.blue)
.shadow(color: Color.gray.opacity(0.1), radius: 3.5, x: 0, y: 1.0)
}
}
.overlay {
if currentlySelectedData != data {
LinearGradient(
gradient: Gradient(
colors: [Color.gray.opacity(0.2), Color.clear]
),
startPoint: .top,
endPoint: .bottom
)
.allowsHitTesting(false)
.transition(.opacity)
.frame(width: 39.0, height: 39.0)
}
}
}
}
}
1条答案
按热度按时间jdzmm42g1#
你的代码完全按照你的要求去做。
如果所选的currentlySelectedData不等于传入的值,则告诉它添加覆盖。但是您应该检查的是,该值是否是数组中的第一个或最后一个,并且不等于传入的值。
最快的方法是改变:
致:
这应该能解决你的简单案子。