SwiftUI ScrollView在带有渐变的矩形下的ZStack中停止工作
我遇到了这样一个问题,当我在滚动视图上放置一个带有渐变填充的矩形时,滚动视图对触摸停止反应 其目的是淡出scrollview底部的项目,以便它们不会与父视图中的自定义底部导航视图冲突 我曾尝试使用.frame修改器使淡入高度仅为底部四分之一左右,以希望停止阻止滚动视图,但它没有起作用 有人知道怎么解决这个问题吗SwiftUI ScrollView在带有渐变的矩形下的ZStack中停止工作,swiftui,Swiftui,我遇到了这样一个问题,当我在滚动视图上放置一个带有渐变填充的矩形时,滚动视图对触摸停止反应 其目的是淡出scrollview底部的项目,以便它们不会与父视图中的自定义底部导航视图冲突 我曾尝试使用.frame修改器使淡入高度仅为底部四分之一左右,以希望停止阻止滚动视图,但它没有起作用 有人知道怎么解决这个问题吗 import Foundation import SwiftUI import CoreData struct TestView: View { var managedOb
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))
}
}
<代码>导入基础
导入快捷键
导入CoreData
结构测试视图:视图{
var managedObjectContext:NSManagedObjectContext
var支出:获取的结果
var费用:获取的结果
变量设置:FetchedResults
@国有私有var showaddExpanding:Bool=false
@绑定变量选择:Int
var body:一些观点{
VStack{
HStack{
文本(“支出”).padding()
}.padding(.卧式)
ZStack{
//清单项目
滚动视图{
每个人(自我消费){花在
//如果(spend.currentMonth==true){
HStack{
//扩大
如果expand.isExpanded{
VStack{
HStack{
//名字
如果(花费当前月){
文本(“\(spend.name)”)
.lineLimit(1)
.frame(最小宽度:0,最大宽度:。无穷大,对齐:。前导)
.foregroundColor(颜色为橙色)
.ONLONGPRESS手势{
explore.currentMonth.toggle()
}
}否则{
文本(“\(spend.name)”)
.lineLimit(1)
.frame(最小宽度:0,最大宽度:。无穷大,对齐:。前导)
.ONLONGPRESS手势{
explore.currentMonth.toggle()
}
}
//数量
文本(“\(支出金额)”)
.frame(最小宽度:0,最大宽度:70,对齐方式:。尾部)
//删除
DeleteStyle(文本:“乘法”,符号:true)
.ontapsigne{
self.managedObjectContext.delete(支出)
做{
请尝试self.managedObjectContext.save()
}抓住{
打印(错误)
}
}
}
VStack{
//类别
文本(“类别:\(支出类别)”)
.frame(最小宽度:0,最大宽度:。无穷大,对齐:。前导)
}
}
.ontapsigne{
expand.isExpanded.toggle()的
}
}否则{
//没有扩展
HStack{
//名字
如果(花费当前月){
文本(“\(spend.name)”)
.lineLimit(1)
.frame(最小宽度:0,最大宽度:。无穷大,对齐:。前导)
.foregroundColor(颜色为橙色)
.ONLONGPRESS手势{
explore.currentMonth.toggle()
}
}否则{
文本(“\(spend.name)”)
.lineLimit(1)
.frame(最小宽度:0,最大宽度:。无穷大,对齐:。前导)
.ONLONGPRESS手势{
explore.currentMonth.toggle()
}
}
垫片()
//数量
文本(“\(支出金额)”)
.frame(最小宽度:0,最大宽度:70,对齐方式:。尾部)
//删除
DeleteStyle(文本:“乘法”,符号:true)。ontapsignature{
self.managedObjectContext.delete(支出)
做{
请尝试self.managedObjectContext.save()
}抓住{
打印(错误)
}
}
}
.onTapGest
ScrollView {
ForEach(0..<100) { i in
Text("Item \(i)")
}
}
.background(LinearGradient(gradient: Gradient(colors: [.clear, .black]),
startPoint: .center, endPoint: .bottom))
public func allowsHitTesting(_ enabled: Bool) -> some View
struct ContentView: View {
var body: some View {
UIViewControllerWrapper()
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
struct UIViewControllerWrapper: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> MyViewController {
return MyViewController()
}
func updateUIViewController(_ uiViewController: MyViewController, context: Context) {}
}
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// SwiftUI content wrapper
let swiftUIContent = UIHostingController(rootView: SwiftUIContent())
swiftUIContent.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(swiftUIContent.view)
swiftUIContent.view.leadingAnchor.constraint(
equalTo: view.leadingAnchor).isActive = true
swiftUIContent.view.trailingAnchor.constraint(
equalTo: view.trailingAnchor).isActive = true
swiftUIContent.view.topAnchor.constraint(
equalTo: view.topAnchor).isActive = true
swiftUIContent.view.bottomAnchor.constraint(
equalTo: view.bottomAnchor).isActive = true
swiftUIContent.didMove(toParent: self)
// UIKit view overlay
let viewOverlay = UIView(frame: UIScreen.main.bounds)
let gradient = CAGradientLayer()
gradient.frame = view.bounds
gradient.colors = [UIColor.red.withAlphaComponent(0.5).cgColor, UIColor.green.withAlphaComponent(0.5).cgColor]
viewOverlay.layer.insertSublayer(gradient, at: 0)
viewOverlay.isUserInteractionEnabled = false
view.addSubview(viewOverlay)
}
}
struct SwiftUIContent: View{
var body: some View {
let body =
ZStack{
// ScrollView {
List{
ForEach(0..<100) { i in
Text("Item \(i)")
.gesture(TapGesture()
.onEnded({ _ in
print("Item \(i)")
}))
}
}
}
return body
}
}
struct FadingScrollView<Content: View>: View {
let fadeDistance: CGFloat
let axes: Axis.Set
let showsIndicators: Bool
let content: Content
init(
fadeDistance: CGFloat,
_ axes: Axis.Set = .vertical,
showsIndicators: Bool = true,
@ViewBuilder content: () -> Content
) {
self.fadeDistance = fadeDistance
self.axes = axes
self.showsIndicators = showsIndicators
self.content = content()
}
var body: some View {
ZStack(alignment: .bottomTrailing) {
ScrollView(axes, showsIndicators: showsIndicators) {
// Pad the content depending on the axes so that bottom or trailing
// part of the content isn't faded when scrolling all the way to the end.
if axes == .vertical {
HStack(spacing: 0) {
content
Spacer()
}
Spacer(minLength: fadeDistance)
} else if axes == .horizontal {
HStack(spacing: 0) {
VStack(spacing: 0) {
content
Spacer()
}
Spacer(minLength: fadeDistance)
}
} else {
HStack(spacing: 0) {
content
Spacer(minLength: fadeDistance)
}
Spacer(minLength: fadeDistance)
}
}
if axes.contains(.vertical) {
fadeGradient(for: .vertical)
.frame(height: fadeDistance)
.allowsHitTesting(false) // Maybe Apple will make this work in the future
}
if axes.contains(.horizontal) {
fadeGradient(for: .horizontal)
.frame(width: fadeDistance)
.allowsHitTesting(false) // Maybe Apple will make this work in the future
}
}
}
private func fadeGradient(for axis: Axis) -> some View {
LinearGradient(
gradient: Gradient(colors: [
Color(.systemBackground).opacity(0),
Color(.systemBackground).opacity(1)
]),
startPoint: axis == .vertical ? .top : .leading,
endPoint: axis == .vertical ? .bottom : .trailing
)
}
}
ZStack {
ScrollView {
Text("Lorem ipsum dolor sit amet, consectetuer...")
}
LinearGradient(gradient: Gradient(colors: [Color.black,
Color.clear]),
startPoint: .top,
endPoint: .bottom)
.allowsHitTesting(false)
}
var body: some View {
ScrollView {
Text("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc")
.multilineTextAlignment(.center)
}
}
.mask(
LinearGradient(gradient: Gradient(colors: [Color.black,
Color.black,
Color.clear]),
startPoint: .top,
endPoint: .bottom)
)
.ignoresSafeArea(edges: .bottom)
}
}