我想提出一个自定义Picker的SegmentedPickerStyle()。我想有相同的行为,但是当我点击内容和其中一个可能选择的边框之间的区域时,onTapGesture它不起作用。当我添加蓝色背景时,它确实有效,但背景清晰时则无效。
使用蓝色背景
无法在清晰的背景下工作
不工作的代码:
import SwiftUI
struct PickerElementView<Content>: View where Content : View {
@Binding var selectedElement: Int
let content: () -> Content
@inlinable init(_ selectedElement: Binding<Int>, @ViewBuilder content: @escaping () -> Content) {
self._selectedElement = selectedElement
self.content = content
}
var body: some View {
GeometryReader { proxy in
self.content()
.fixedSize(horizontal: true, vertical: true)
.frame(minWidth: proxy.size.width, minHeight: proxy.size.height)
// ##################################################################
// CHANGE COLOR HERE TO BLUE TO MAKE IT WORK
// ##################################################################
.background(Color.clear)
// ##################################################################
.border(Color.yellow, width: 5)
}
}
}
struct PickerView: View {
@Environment (\.colorScheme) var colorScheme: ColorScheme
var elements: [(id: Int, view: AnyView)]
@Binding var selectedElement: Int
@State var internalSelectedElement: Int = 0
private var width: CGFloat = 220
private var height: CGFloat = 100
private var cornerRadius: CGFloat = 20
private var factor: CGFloat = 0.95
private var color = Color(UIColor.systemGray)
private var selectedColor = Color(UIColor.systemGray2)
init(_ selectedElement: Binding<Int>) {
self._selectedElement = selectedElement
self.elements = [
(id: 0, view: AnyView(PickerElementView(selectedElement) {
Text("9").font(.system(.title))
})),
(id: 1, view: AnyView(PickerElementView(selectedElement) {
Text("5").font(.system(.title))
})),
]
self.internalSelectedElement = selectedElement.wrappedValue
}
func calcXPosition() -> CGFloat {
var pos = CGFloat(-self.width * self.factor / 4)
pos += CGFloat(self.internalSelectedElement) * self.width * self.factor / 2
return pos
}
var body: some View {
ZStack {
Rectangle()
.foregroundColor(self.selectedColor)
.cornerRadius(self.cornerRadius * self.factor)
.frame(width: self.width * self.factor / CGFloat(self.elements.count), height: self.height - self.width * (1 - self.factor))
.offset(x: calcXPosition())
.animation(.easeInOut(duration: 0.2))
HStack {
ForEach(self.elements, id: \.id) { item in
item.view
.gesture(TapGesture().onEnded { _ in
print(item.id)
self.selectedElement = item.id
withAnimation {
self.internalSelectedElement = item.id
}
})
}
}
}
.frame(width: self.width, height: self.height)
.background(self.color)
.cornerRadius(self.cornerRadius)
.padding()
}
}
struct PickerView_Previews: PreviewProvider {
static var previews: some View {
PickerView(.constant(1))
}
}
Run Code Online (Sandbox Code Playgroud)
更改我标记的颜色。
有谁知道为什么他们的行为不同以及我如何解决这个问题?
E.C*_*oms 19
一行答案不是设置 backgroundColor,而是设置contentShape为命中测试。
var body: some View {
GeometryReader { proxy in
self.content()
.fixedSize(horizontal: true, vertical: true)
.frame(minWidth: proxy.size.width, minHeight: proxy.size.height)
// ##################################################################
// CHANGE COLOR HERE TO BLUE TO MAKE IT WORK
// ##################################################################
.contentShape(Rectangle())
// ##################################################################
.border(Color.yellow, width: 5)
}
}
Run Code Online (Sandbox Code Playgroud)
默认情况下,SwiftUI 中的透明视图不可点击,因为它们的内容形状为零。
您可以使用.contentShape修饰符更改此行为:
Color.clear
.frame(width: 300, height: 300)
.contentShape(Rectangle())
.onTapGesture { print("tapped") }
Run Code Online (Sandbox Code Playgroud)
Color任何不透明度为 0 的物体都是不可利用的,这似乎是一个设计决定。
Color.clear.onTapGesture { print("tapped") } // will not print
Color.blue.opacity(0).onTapGesture { print("tapped") } // will not print
Color.blue.onTapGesture { print("tapped") } // will print
Color.blue.opacity(0.0001).onTapGesture { print("tapped") } // will print
Run Code Online (Sandbox Code Playgroud)
您可以使用第四个选项来解决这个问题,因为它在视觉上与第一个选项没有区别。
| 归档时间: |
|
| 查看次数: |
2455 次 |
| 最近记录: |