[英]How to add Context Menu into NavigationLink using SwiftUI?
[英]SwiftUI: Using LongPressGesture to display a Pinterest like context menu
我正在嘗試在他們的 iOS 應用程序中創建一個類似於 Pinterest 上下文菜單的上下文菜單。 長按一個帖子會顯示一個四按鈕視圖,當用戶繼續長按時,可以拖動其他按鈕 select。 讓 go 長按將 select 您當前選擇的任何按鈕或完全關閉菜單,如果您沒有選擇任何內容。 請參閱下面的示例:
到目前為止,我在這里嘗試過類似於 Apple 文檔的內容: https://developer.apple.com/documentation/swiftui/longpressgesture
但似乎手勢一旦達到手勢中定義的 minimumDuration 就結束了。 只要用戶按住,我希望手勢繼續,一旦他們讓 go 結束。
此外,當涉及到拖動和選擇其他按鈕時,我感到很困惑。 到目前為止,這是我的方法:
struct Example: View {
@GestureState var isDetectingLongPress = false
@State var completedLongPress = false
var longPress: some Gesture {
LongPressGesture(minimumDuration: 3)
.updating($isDetectingLongPress) { currentState, gestureState,
transaction in
gestureState = currentState
transaction.animation = Animation.easeIn(duration: 2.0)
}
.onEnded { finished in
self.completedLongPress = finished
}
}
var body: some View {
HStack {
Spacer()
ZStack {
// Three button array to fan out when main button is being held
Button(action: {
// ToDo
}) {
Image(systemName: "circle.fill")
.frame(width: 70, height: 70)
.foregroundColor(.red)
}
.offset(x: self.isDetectingLongPress ? -90 : 0, y: self.isDetectingLongPress ? -90 : 0)
Button(action: {
// ToDo
}) {
Image(systemName: "circle.fill")
.frame(width: 70, height: 70)
.foregroundColor(.green)
}
.offset(x: 0, y: self.isDetectingLongPress ? -120 : 0)
Button(action: {
// ToDo
}) {
Image(systemName: "circle.fill")
.frame(width: 70, height: 70)
.foregroundColor(.blue)
}
.offset(x: self.isDetectingLongPress ? 90 : 0, y: self.isDetectingLongPress ? -90 : 0)
// Main button
Image(systemName: "largecircle.fill.circle")
.gesture(longPress)
}
Spacer()
}
}
更新:我找到了一個可行的解決方案,但它使用的是 UIKit 因為我不相信 SwiftUI 提供了一種本機執行此操作的方法。 我遵循了此處找到的類似問題的答案的指導: https://stackoverflow.com/a/31591162/862561
但是它是用 ObjC 編寫的,所以我大致翻譯為 Swift。 對於那些好奇的人,這里是該過程的簡化版本:
class UIControlsView: UIView {
let createButton = CreateButtonView()
let secondButton = ButtonView(color: .red)
var currentDraggedButton: ButtonView!
required init?(coder: NSCoder) {
fatalError("-")
}
init() {
super.init(frame: .zero)
self.backgroundColor = .green
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(self.longPress))
createButton.addGestureRecognizer(longPress)
createButton.frame = CGRect(x: 0, y: 0, width: 80, height: 80)
createButton.center = CGPoint(x: UIScreen.main.bounds.size.width / 2, y: 40)
secondButton.frame = CGRect(x: 0, y: 0, width: 80, height: 80)
secondButton.center = CGPoint(x: UIScreen.main.bounds.size.width / 2, y: 40)
self.addSubview(secondButton)
self.addSubview(createButton)
}
@objc func longPress(sender: UILongPressGestureRecognizer) {
if sender.state == .began {
print("Started Long Press")
secondButton.center.x = secondButton.center.x + 90
}
if sender.state == .changed {
let location = sender.location(in: self)
guard let superViewLocation = self.superview?.convert(location, from: self) else {
return
}
guard let view = self.superview?.hitTest(superViewLocation, with: nil) else {
return
}
if view.isKind(of: ButtonView.self) {
let touchedButton = view as! ButtonView
if self.currentDraggedButton != touchedButton {
if self.currentDraggedButton != nil {
self.currentDraggedButton.untouchedUp()
}
}
self.currentDraggedButton = touchedButton
touchedButton.isTouchedUp()
} else {
if self.currentDraggedButton != nil {
print("Unsetting currentDraggedButton")
self.currentDraggedButton.untouchedUp()
}
}
}
if sender.state == .ended {
print("Long Press Ended")
let location = sender.location(in: self)
guard let superViewLocation = self.superview?.convert(location, from: self) else {
return
}
guard let view = self.superview?.hitTest(superViewLocation, with: nil) else {
return
}
if view.isKind(of: ButtonView.self) {
let touchedButton = view as! ButtonView
touchedButton.untouchedUp()
touchedButton.tap()
self.currentDraggedButton = nil
}
secondButton.center.x = secondButton.center.x - 90
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.