SwiftUI ScrollView 停止在带有渐变的矩形下的 ZStack 中工作 [英] SwiftUI ScrollView stops working in ZStack under Rectangle with gradient
问题描述
我遇到了这个问题,当我在带有渐变填充的 ScrollView 上放置一个矩形时,滚动视图停止对触摸做出反应.
I'm having this issue where when I put a rectangle over a ScrollView with a gradient fill the scrollview stops reacting to touch.
目的是淡出滚动视图底部的项目,这样它们就不会与父视图中的自定义底部导航视图发生冲突.
The aim is to fade out items at the bottom of the scrollview so they don't clash with a custom bottom navigation view in the parent view.
我尝试使用 .frame 修饰符使淡入淡出高度仅在底部四分之一左右,以希望停止阻塞滚动视图,但没有奏效.
I've tried to use a .frame modifier to make the fades height only the bottom quarter or so to hopefully stop blocking the scrollview but it didnt work.
有没有人知道解决这个问题的方法?
Does anyone know a way around this?
import Foundation
import SwiftUI
import CoreData
struct TestView: View {
var managedObjectContext:NSManagedObjectContext
var spendings:FetchedResults<Spending>
var expenses:FetchedResults<Expense>
var settings:FetchedResults<Settings>
@State private var showAddSpending:Bool = false
@Binding var selection:Int
var body: some View{
VStack{
HStack{
Text("Spending").padding()
}.padding(.horizontal)
ZStack{
//List items
ScrollView{
ForEach(self.spendings) { spend in
//if(spend.currentMonth == true){
HStack{
// IS EXPANDED
if spend.isExpanded {
VStack{
HStack{
//NAME
if(spend.currentMonth){
Text("(spend.name)")
.lineLimit(1)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
.foregroundColor(Color .orange)
.onLongPressGesture {
spend.currentMonth.toggle()
}
} else {
Text("(spend.name)")
.lineLimit(1)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
.onLongPressGesture {
spend.currentMonth.toggle()
}
}
//AMOUNT
Text("(spend.amount)")
.frame(minWidth: 0, maxWidth: 70, alignment: .trailing)
//DELETE
DeleteStyle(text: "multiply", symbol: true)
.onTapGesture {
self.managedObjectContext.delete(spend)
do {
try self.managedObjectContext.save()
}catch{
print(error)
}
}
}
VStack{
//CATEGORY
Text("Category: (spend.category)")
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
}
}
.onTapGesture {
spend.isExpanded.toggle()
}
} else {
// ISNT EXPANDED
HStack{
//NAME
if(spend.currentMonth){
Text("(spend.name)")
.lineLimit(1)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
.foregroundColor(Color .orange)
.onLongPressGesture {
spend.currentMonth.toggle()
}
} else {
Text("(spend.name)")
.lineLimit(1)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
.onLongPressGesture {
spend.currentMonth.toggle()
}
}
Spacer()
//AMOUNT
Text("(spend.amount)")
.frame(minWidth: 0, maxWidth: 70, alignment: .trailing)
//DELETE
DeleteStyle(text: "multiply", symbol: true).onTapGesture {
self.managedObjectContext.delete(spend)
do {
try self.managedObjectContext.save()
}catch{
print(error)
}
}
}
.onTapGesture {
spend.isExpanded.toggle()
}
}
}
}
.foregroundColor(Color (UIColor .secondaryLabel))
}.padding(.horizontal)
//Button to add new item
VStack{
Spacer()
HStack{
Spacer()
/*
Text("Total: £(calculateTotalSpendingForCurrentMonth())")
.foregroundColor(.white)
.padding(15)
.background(Color .orange)
.cornerRadius(40)
*/
if spendings.isEmpty {
HStack{
Text("Record a spend")
Image(systemName: "arrow.right")
}
.foregroundColor(Color (UIColor .secondaryLabel))
.padding(.bottom, 90)
.padding(.horizontal, 40)
}
VStack{
Button(action: {
self.showAddSpending = true
}) {
NavStyle(text: "plus", symbol: true)
}.sheet(isPresented: $showAddSpending) {
AddSpendingView(managedObjectContext: self.managedObjectContext, spendings: self.spendings, expenses: self.expenses)
}
}
}
}
//Black Fade at bottom
VStack{
Spacer()
Rectangle()
.fill (
LinearGradient(gradient: Gradient(colors: [.clear, .black]),
startPoint: .center, endPoint: .bottom)
)
}
}
}.background(Color (UIColor.secondarySystemBackground))
}
}
推荐答案
ScrollView
本身是透明的,所以你可以使用渐变作为背景,就像下面的例子
ScrollView
is transparent itself, so you can use gradient as background, like in the example below
ScrollView {
ForEach(0..<100) { i in
Text("Item (i)")
}
}
.background(LinearGradient(gradient: Gradient(colors: [.clear, .black]),
startPoint: .center, endPoint: .bottom))
有时,对于叠加层,您可以使用带有值 false
的以下修饰符来传递触摸
For overlays sometimes you can use the following modifier with value false
to pass touches through
public func allowsHitTesting(_ enabled: Bool) -> some View
但是对于ScrollView来说,虽然它通过了tap手势事件,但它并不完全适合,因为滚动会被阻止.
but for ScrollView, even though it passes tap gesture events, it does not appropriate completely, because scroll would be blocked.
使用 Xcode 11.2.1/iOS 13.2 测试
Tested with Xcode 11.2.1 / iOS 13.2
这篇关于SwiftUI ScrollView 停止在带有渐变的矩形下的 ZStack 中工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!