考虑使用以下可拖动元素的简化代码
HStack {
Icon(icon: .iconDrag)
Text("Title")
Spacer()
}
.padding(16)
.onDrag {
return NSItemProvider(object: id.uuidString as NSString)
}
这会导致下面的行为,一旦开始拖动,就会显示预览元素,但它只是原始元素大小的一小部分并且具有透明度。
我尝试将
preview : {}
添加到具有相同原始元素副本的 onDrag
中,但它的大小仍然不准确并且具有透明度。有没有办法以某种方式扩展预览(例如使用 uikit),使其与原始元素完全相同?我相信预览元素有最大宽度,此时它可能开始缩小?
UIDragInteractionDelegate
中采用 UIViewRepresentable
来实现自定义拖动预览:通过使用 UIDragPreview
并设置 UIDragItem
的预览提供程序,您可以为预览指定一个自定义视图,该视图的大小与原始视图相同,并且没有任何透明度。
+---------------------------------+
| +----+ +-------------------+ |
| |Icon| |Title | |
| +----+ +-------------------+ |
| | UIViewRepresentable wrapper |
| +-------------------------------+
| | UIDragInteractionDelegate |
+---------------------------------+
|
| Custom drag behavior
| (UIDragInteractionDelegate)
v
+----------------------------------+
| UIDragPreview (Custom preview) |
| Same size, no transparency |
+----------------------------------+
Client/Frontend/TabChrome/TopBar/LocationView/LocationViewTouchHandler.swift
import SwiftUI
import UIKit
// Wrap your SwiftUI view in a UIViewRepresentable
struct DraggableView: UIViewRepresentable {
var text: String
func makeUIView(context: Context) -> UIView {
let view = UIHostingController(rootView: DraggableTextView(text: text)).view!
view.backgroundColor = .clear
let dragInteraction = UIDragInteraction(delegate: context.coordinator)
view.addInteraction(dragInteraction)
return view
}
func updateUIView(_ uiView: UIView, context: Context) {}
func makeCoordinator() -> Coordinator {
Coordinator()
}
class Coordinator: NSObject, UIDragInteractionDelegate {
func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] {
let provider = NSItemProvider(object: "Dragged content" as NSString)
let item = UIDragItem(itemProvider: provider)
item.previewProvider = { return UIDragPreview(view: interaction.view!) }
return [item]
}
}
}
// Your original SwiftUI view
struct DraggableTextView: View {
var text: String
var body: some View {
HStack {
Image(systemName: "hand.point.up.left.fill") // Example icon
Text(text)
Spacer()
}
.padding(16)
.background(Color.gray) // For demo purposes
}
}
struct ContentView: View {
var body: some View {
DraggableView(text: "Draggable Text")
}
}
代码中应允许“相同大小,无透明度”拖动预览的关键部分是
previewProvider
的 UIDragItem
闭包。
item.previewProvider = { return UIDragPreview(view: interaction.view!) }
UIDragPreview
初始值设定项传递给 interaction.view
,它是由 UIHostingController
创建的 UIView,其中包含 SwiftUI 视图。由于您使用原始视图本身进行预览,因此它的大小应与原始视图相同。