我正在尝试在SwiftUI中为Button轻按开始时实现触觉反馈。因此,我正在尝试同时使用手势,但是我仍在挣扎。我无法弄清楚水龙头何时开始。
还没有为Swift UI实现触觉反馈,所以我想我可以从UIKit中将其融合进来?
我试图实现TapGesture的更新方法,但它似乎无能为力。这就是到目前为止。感谢您的提示。
<?php
function multi_key_in_array($needle, $haystack, $key)
{
foreach ($haystack as $h)
{
if (array_key_exists($key, $h) && $h[$key]==$needle)
{
return true;
}
}
return false;
}
$myArray = Array
(
'Standardbox' => Array
(
'details' => Array
(
'name' => 'Standardbox'
),
'resources' => Array
(
0 => Array
(
'resourceId' => 1,
'resourceName' => 'Knife',
'amount' => 1,
'unit' => 2
),
1 => Array
(
'resourceId' => 2,
'resourceName' => 'Fork',
'amount' => 1,
'unit' => 2
)
)
)
);
if(multi_key_in_array(1, $myArray['Standardbox']['resources'], "resourceId"))
{
echo 'true';
} else {
echo 'false';
}
> Blockquote
答案 0 :(得分:14)
据我所知,这是在SwiftUI中获得触觉反馈的最简单方法
点击按钮时:
Button(action: {
let impactMed = UIImpactFeedbackGenerator(style: .medium)
impactMed.impactOccurred()
}) {
Text("This is a Button")
}
您可以通过将.medium
替换为.light
或.heavy
来降低或增加触觉反馈的强度
或在点击其他任何内容时:
.onTapGesture {
let impactHeavy = UIImpactFeedbackGenerator(style: .heavy)
impactHeavy.impactOccurred()
}
如果您想制作类似Haptic Touch的东西,请像这样用.onTapGesture
替换.onLongPressGesture
.onLongPressGesture {
let impactHeavy = UIImpactFeedbackGenerator(style: .heavy)
impactHeavy.impactOccurred()
}
答案 1 :(得分:1)
您还可以将 Haptic 生成器封装在单例中:
import UIKit
class Haptics {
static let shared = Haptics()
private init() { }
func play(_ feedbackStyle: UIImpactFeedbackGenerator.FeedbackStyle) {
UIImpactFeedbackGenerator(style: feedbackStyle).impactOccurred()
}
func notify(_ feedbackType: UINotificationFeedbackGenerator.FeedbackType) {
UINotificationFeedbackGenerator().notificationOccurred(feedbackType)
}
}
呼叫站点:
// As a button action
Button(action: {
// some action
Haptics.shared.play(.heavy)
}, label: {
Text("Button")
})
// As a tap gesture on a View
SomeView()
.onTapGesture(perform: {
Haptics.shared.play(.light)
})
// In a function
func someFunc() {
Haptics.shared.notify(.success)
}
选项:
Haptics.shared.play(.heavy)
Haptics.shared.play(.light)
Haptics.shared.play(.medium)
Haptics.shared.play(.rigid)
Haptics.shared.play(.soft)
Haptics.shared.notify(.error)
Haptics.shared.notify(.success)
Haptics.shared.notify(.warning)
答案 2 :(得分:0)
您可以像这样使用UIFeedbackGenerator:
let generator = UINotificationFeedbackGenerator()
generator.notificationOccurred(.error)
或者,当您使用SwiftUI时,您将可以像这样使用CoreHaptics:
let engine = try CHHapticEngine()
try engine.start()
let hapticEvent = CHHapticEvent(eventType: .hapticTransient, parameters: [
CHHapticEventParameter(parameterID: .hapticSharpness, value: sharpness), CHHapticEventParameter(parameterID: .hapticIntensity, value: intensity),
], relativeTime: 0)
let audioEvent = CHHapticEvent(eventType: .audioContinuous, parameters: [
CHHapticEventParameter(parameterID: .audioVolume, value: volume),
CHHapticEventParameter(parameterID: .decayTime, value: decay),
CHHapticEventParameter(parameterID: .sustained, value: 0),
], relativeTime: 0)
let pattern = try CHHapticPattern(events: [hapticEvent, audioEvent], parameters: [])
let hapticPlayer = try engine.makePlayer(with: pattern)
try hapticPlayer?.start(atTime: CHHapticTimeImmediate)
答案 3 :(得分:0)
下面的纯SwiftUI解决方案:
HStack {
Image("icon")
Text("Login")
}
.onTouchGesture(
touchBegan: { self.generateHapticFeedback = true },
touchEnd: { _ in self.generateHapticFeedback = false }
)
只需将此代码段添加到项目中的某个位置即可:
struct TouchGestureViewModifier: ViewModifier {
let touchBegan: () -> Void
let touchEnd: (Bool) -> Void
@State private var hasBegun = false
@State private var hasEnded = false
private func isTooFar(_ translation: CGSize) -> Bool {
let distance = sqrt(pow(translation.width, 2) + pow(translation.height, 2))
return distance >= 20.0
}
func body(content: Content) -> some View {
content.gesture(DragGesture(minimumDistance: 0)
.onChanged { event in
guard !self.hasEnded else { return }
if self.hasBegun == false {
self.hasBegun = true
self.touchBegan()
} else if self.isTooFar(event.translation) {
self.hasEnded = true
self.touchEnd(false)
}
}
.onEnded { event in
if !self.hasEnded {
let success = !self.isTooFar(event.translation)
self.touchEnd(success)
}
self.hasBegun = false
self.hasEnded = false
})
}
}
extension View {
func onTouchGesture(touchBegan: @escaping () -> Void = {},
touchEnd: @escaping (Bool) -> Void = { _ in }) -> some View {
modifier(TouchGestureViewModifier(touchBegan: touchBegan, touchEnd: touchEnd))
}
}
答案 4 :(得分:0)
我有一个包装视图,该视图播放一个触觉事件,然后调用该动作:
struct HapticButton: View {
let content: String
let action: () -> Void
init(_ content: String, _ action: @escaping () -> Void) {
self.content = content
self.action = action
}
var body: some View {
Button(content) {
HapticService.shared.play(event: .buttonTap)
self.action()
}
}
}
使用方式:
HapticButton("Press me") { print("hello") } // plays haptic and prints