如何防止按钮在 ScrollView 中被禁用
How do I prevent buttons being disabled inside a ScrollView
在下面的代码中,从一张卡片滑动到另一张卡片似乎禁用了 ScrollView 内的按钮。我已经将问题确定为 ScrollPart 中的 .mask 行(.clippedShape 产生了类似的问题并且不符合我的设计目标),但不幸的是,在我正在进行的实际项目中,我无法得到为了视觉效果去掉它
import SwiftUI
extension AnyTransition {
public static func swipe(_ edge: Edge) -> AnyTransition {
.asymmetric(insertion: move(edge: edge), removal: move(edge: edge.flip()))
}
}
extension Edge {
public func flip() -> Edge {
switch self {
case .bottom:
return .top
case .top:
return .bottom
case .leading:
return .trailing
case .trailing:
return .leading
}
}
}
struct ContentView: View {
@State var index: Int = 0
@State var offset: CGFloat = 0
@State var transition = AnyTransition.identity
@State var ID = UUID()
var body: some View {
GeometryReader { geometry in
ScrollPart(index: self.index)
.frame(width: geometry.size.width)
.background(Background())
.offset(x: self.offset)
.id(self.ID)
.gesture(
DragGesture()
.onChanged {value in
self.offset = value.translation.width
}
.onEnded { _ in
if self.offset > geometry.size.width * 0.4 {
self.index += 1
self.ID = UUID()
self.transition = .swipe(.leading)
}
if self.offset < -geometry.size.width * 0.4 {
self.index -= 1
self.ID = UUID()
self.transition = .swipe(.trailing)
}
self.offset = 0
}
)
.transition(self.transition)
.animation(.easeOut)
}
}
}
import SwiftUI
struct ScrollPart: View {
var index : Int
@State var bool = false
var body: some View {
ScrollView {
Spacer().frame(height: 300)
Button (action: {self.bool.toggle()}){
ZStack {
RoundedRectangle(cornerRadius: 10)
.stroke(
style:
StrokeStyle(lineWidth: 1,
dash: [10, 1])).foregroundColor(.white)
.frame(width: 120)
.foregroundColor(.green)
Text("Index: \(self.index)")
.foregroundColor(.white)
.font(.title)
.padding()
}
}
Text(bool ? "True" : "False")
.foregroundColor(.white)
.font(.title)
}
.mask(Background())
}
}
import SwiftUI
struct Background: View {
var body: some View {
GeometryReader { geometry in
RoundedRectangle(cornerRadius: 10)
.foregroundColor(.green)
.frame(width: 0.9 * geometry.size.width, height: 0.9 * geometry.size.height)
}
}
}
我已经为此苦苦挣扎了一段时间,但我仍然希望有一些方法可以保留遮罩,同时解决 ScrollView 中按钮被禁用的问题。如果您滚动 ScrollView,该按钮会重新启用,但这仍然是一个设计缺陷,理想情况下可以修复。我对 UIKit 了解不多,我基本上才刚刚开始学习 SwiftUI,并且只在绝对必要时才学习旧方法,所以如果 UIKit 的回答记住我可能很难理解它,我将不胜感激
感谢您的帮助!
一种可能的解决方案是删除或修改 .mask(Background()), Apple Docs“The view which alpha the rendering system applies to the specified view.”中的掩码行。 “当你想将另一个视图的 alpha(不透明度)值应用到当前视图时,使用 mask(_:)。”应用具有相同背景的遮罩,在此背景视图内,几何 Reader 影响滚动视图内的按钮。
如果你评论 //.mask(Background) 对我来说很好用并且显示白色边框也很好。另一个使用掩码的解决方案在 ScrollView 上添加 VStack 并应用没有几何图形的掩码 Reader。如果你对这个蒙版应用不透明度也可以正常工作(将 .mask(Background1()) 更改为 .mask(Rectangle().opacity(0.6)))
struct Background1: View {
var body: some View {
RoundedRectangle(cornerRadius: 10)
.foregroundColor(.green)
}
}
struct ScrollPart: View {
var index : Int
@State var bool = false
var body: some View {
ScrollView {
VStack {
Spacer().frame(height: 300)
Button (action: {self.bool.toggle()}){
ZStack {
RoundedRectangle(cornerRadius: 10)
.stroke(
style:
StrokeStyle(lineWidth: 1, dash: [10,1])).foregroundColor(.white)
.frame(width: 120)
.foregroundColor(.green)
Text("Index: \(self.index)")
.foregroundColor(.white)
.font(.title)
.padding()
}
}
Text(bool ? "True" : "False")
.foregroundColor(.white)
.font(.title)
}
.mask(Background1())
}
}
}
在下面的代码中,从一张卡片滑动到另一张卡片似乎禁用了 ScrollView 内的按钮。我已经将问题确定为 ScrollPart 中的 .mask 行(.clippedShape 产生了类似的问题并且不符合我的设计目标),但不幸的是,在我正在进行的实际项目中,我无法得到为了视觉效果去掉它
import SwiftUI
extension AnyTransition {
public static func swipe(_ edge: Edge) -> AnyTransition {
.asymmetric(insertion: move(edge: edge), removal: move(edge: edge.flip()))
}
}
extension Edge {
public func flip() -> Edge {
switch self {
case .bottom:
return .top
case .top:
return .bottom
case .leading:
return .trailing
case .trailing:
return .leading
}
}
}
struct ContentView: View {
@State var index: Int = 0
@State var offset: CGFloat = 0
@State var transition = AnyTransition.identity
@State var ID = UUID()
var body: some View {
GeometryReader { geometry in
ScrollPart(index: self.index)
.frame(width: geometry.size.width)
.background(Background())
.offset(x: self.offset)
.id(self.ID)
.gesture(
DragGesture()
.onChanged {value in
self.offset = value.translation.width
}
.onEnded { _ in
if self.offset > geometry.size.width * 0.4 {
self.index += 1
self.ID = UUID()
self.transition = .swipe(.leading)
}
if self.offset < -geometry.size.width * 0.4 {
self.index -= 1
self.ID = UUID()
self.transition = .swipe(.trailing)
}
self.offset = 0
}
)
.transition(self.transition)
.animation(.easeOut)
}
}
}
import SwiftUI
struct ScrollPart: View {
var index : Int
@State var bool = false
var body: some View {
ScrollView {
Spacer().frame(height: 300)
Button (action: {self.bool.toggle()}){
ZStack {
RoundedRectangle(cornerRadius: 10)
.stroke(
style:
StrokeStyle(lineWidth: 1,
dash: [10, 1])).foregroundColor(.white)
.frame(width: 120)
.foregroundColor(.green)
Text("Index: \(self.index)")
.foregroundColor(.white)
.font(.title)
.padding()
}
}
Text(bool ? "True" : "False")
.foregroundColor(.white)
.font(.title)
}
.mask(Background())
}
}
import SwiftUI
struct Background: View {
var body: some View {
GeometryReader { geometry in
RoundedRectangle(cornerRadius: 10)
.foregroundColor(.green)
.frame(width: 0.9 * geometry.size.width, height: 0.9 * geometry.size.height)
}
}
}
我已经为此苦苦挣扎了一段时间,但我仍然希望有一些方法可以保留遮罩,同时解决 ScrollView 中按钮被禁用的问题。如果您滚动 ScrollView,该按钮会重新启用,但这仍然是一个设计缺陷,理想情况下可以修复。我对 UIKit 了解不多,我基本上才刚刚开始学习 SwiftUI,并且只在绝对必要时才学习旧方法,所以如果 UIKit 的回答记住我可能很难理解它,我将不胜感激 感谢您的帮助!
一种可能的解决方案是删除或修改 .mask(Background()), Apple Docs“The view which alpha the rendering system applies to the specified view.”中的掩码行。 “当你想将另一个视图的 alpha(不透明度)值应用到当前视图时,使用 mask(_:)。”应用具有相同背景的遮罩,在此背景视图内,几何 Reader 影响滚动视图内的按钮。
如果你评论 //.mask(Background) 对我来说很好用并且显示白色边框也很好。另一个使用掩码的解决方案在 ScrollView 上添加 VStack 并应用没有几何图形的掩码 Reader。如果你对这个蒙版应用不透明度也可以正常工作(将 .mask(Background1()) 更改为 .mask(Rectangle().opacity(0.6)))
struct Background1: View {
var body: some View {
RoundedRectangle(cornerRadius: 10)
.foregroundColor(.green)
}
}
struct ScrollPart: View {
var index : Int
@State var bool = false
var body: some View {
ScrollView {
VStack {
Spacer().frame(height: 300)
Button (action: {self.bool.toggle()}){
ZStack {
RoundedRectangle(cornerRadius: 10)
.stroke(
style:
StrokeStyle(lineWidth: 1, dash: [10,1])).foregroundColor(.white)
.frame(width: 120)
.foregroundColor(.green)
Text("Index: \(self.index)")
.foregroundColor(.white)
.font(.title)
.padding()
}
}
Text(bool ? "True" : "False")
.foregroundColor(.white)
.font(.title)
}
.mask(Background1())
}
}
}