Rog*_*ber 7 xcode ios13 swiftui
对于 SwiftUI,默认按钮行为相当于 UIKit 的“向上触摸”,当您的手指触摸按钮时激活,然后在按钮范围内抬起。
有什么方法可以将其更改为“触摸”,以便在您的手指触摸按钮时立即运行动作关闭?
ake*_*rra 12
虽然DragGesture在许多情况下效果很好,但它可能会产生一些不需要的副作用,例如在滚动视图中使用时,它将优先于滚动视图的内置手势处理。
在 SwiftUI 中,Buttons 已经跟踪按下的状态,因此此问题的解决方案是使用自定义ButtonStyle来允许挂钩状态的更改isPressed。
这是一个可行的解决方案:
ButtonStyle:struct CustomButtonStyle: ButtonStyle {
var onPressed: () -> Void
var onReleased: () -> Void
// Wrapper for isPressed where we can run custom logic via didSet (or willSet)
@State private var isPressedWrapper: Bool = false {
didSet {
// new value is pressed, old value is not pressed -> switching to pressed state
if (isPressedWrapper && !oldValue) {
onPressed()
}
// new value is not pressed, old value is pressed -> switching to unpressed state
else if (oldValue && !isPressedWrapper) {
onReleased()
}
}
}
// return the label unaltered, but add a hook to watch changes in configuration.isPressed
func makeBody(configuration: Self.Configuration) -> some View {
return configuration.label
.onChange(of: configuration.isPressed, perform: { newValue in isPressedWrapper = newValue })
}
}
Run Code Online (Sandbox Code Playgroud)
您也可以didSet直接在修改器perform的块中编写逻辑onChange,但我认为这可以使其看起来干净。
Button
struct ExampleView: View {
@State private var text: String = "Unpressed"
var body: some View {
Text(self.text)
Button(action: { ... }, label: {
// your content here
}).buttonStyle(CustomButtonStyle(onPressed: {
self.text = "Pressed!"
}, onReleased: {
self.text = "Unpressed"
}))
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以将任何你想要的逻辑传递给onPressed和onReleased参数CustomButtonStyle。
我使用它来允许自定义onPressed处理ScrollView.
kon*_*iki 10
您可以使用最小距离为零的 DragGesture 并为 DOWN (onChanged()) 或 UP (onEnded()) 定义一个闭包:
struct ContentView: View {
@State private var idx = 0
var body: some View {
let g = DragGesture(minimumDistance: 0, coordinateSpace: .local).onChanged({
print("DOWN: \($0)")
}).onEnded({
print("UP: \($0)")
})
return Rectangle().frame(width: 100, height: 50).gesture(g)
}
}
Run Code Online (Sandbox Code Playgroud)
_onButtonGesture您可以在 上使用隐藏方法View,该方法是公共的。它甚至不需要附加到Button,但它看起来更好,因为你看到了按下的效果。
代码:
struct ContentView: View {
@State private var counter = 0
@State private var pressing = false
var body: some View {
VStack(spacing: 30) {
Text("Count: \(counter)")
Button("Increment") {
counter += 1
}
._onButtonGesture { pressing in
self.pressing = pressing
} perform: {}
Text("Pressing button: \(pressing ? "yes" : "no")")
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
由于帧速率的原因,GIF 看起来不太好,但每当您按下时pressing都会转到true,然后false松开。
您可以创建自定义视图修改器:
extension View {
func onTouchDownGesture(callback: @escaping () -> Void) -> some View {
modifier(OnTouchDownGestureModifier(callback: callback))
}
}
private struct OnTouchDownGestureModifier: ViewModifier {
@State private var tapped = false
let callback: () -> Void
func body(content: Content) -> some View {
content
.simultaneousGesture(DragGesture(minimumDistance: 0)
.onChanged { _ in
if !self.tapped {
self.tapped = true
self.callback()
}
}
.onEnded { _ in
self.tapped = false
})
}
}
struct MyView: View {
var body: some View {
Text("Hello World")
.onTouchDownGesture {
print("View did tap!")
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2138 次 |
| 最近记录: |