在 iOS 上启用拖放功能可以有效连接理想的用户体验流程。让我们看看在 NativeScript 应用程序中启用此行为有多么简单。
此处提供的详细信息的基础均直接取自官方 iOS 平台文档,Apple 开发者文档。
您现在甚至可以在 StackBlitz 上亲身体验: 👉 https://stackblitz.com/edit/nativescript-drag-n-drop-ios
让我们设置一个工具,它可以接收任何 View 并为我们连接拖放交互。
import { View } from '@nativescript/core'
export function createDropZone(
view: View,
callback: (image: UIImage) => void
) {
// 1. Create a delegate with our callback reference
const dropDelegate = DropDelegate.new() as DropDelegate
dropDelegate.callback = callback
// 2. Add desired interaction configured with the delegate to our View
const drop = UIDropInteraction.alloc().initWithDelegate(dropDelegate)
(view.ios as UIView).addInteraction(drop)
}
第一个参数允许我们传入任何 NativeScript View
实例。第二个参数允许我们传入一个回调,其中包含拖放到我们的 View
上的图像。
根据Apple 开发者文档,我们想要设置一个UIDropInteractionDelegate,其中包含概述的方法,并创建一个UIDropInteraction 并绑定到该委托。
我们可以如下在 TypeScript 中直接设置这样的委托
@NativeClass()
export class DropDelegate
extends NSObject
implements UIDropInteractionDelegate
{
// This tells iOS our object conforms to UIDropInteractionDelegate
static ObjCProtocols = [UIDropInteractionDelegate]
// A reference to our callback to communicate when the drop occurred
callback: (image: UIImage) => void
// iOS delegate implementation details
dropInteractionCanHandleSession(
interaction: UIDropInteraction,
session: UIDropSession
): boolean {
return session.canLoadObjectsOfClass(UIImage.class())
}
dropInteractionSessionDidUpdate(
interaction: UIDropInteraction,
session: UIDropSession
): UIDropProposal {
return UIDropProposal.alloc().initWithDropOperation(UIDropOperation.Copy)
}
dropInteractionPerformDrop(
interaction: UIDropInteraction,
session: UIDropSession
): void {
session.loadObjectsOfClassCompletion(UIImage.class(), (imageItems) => {
const image = imageItems.objectAtIndex(0)
this.callback(image as UIImage)
});
}
}
让我们分解一下此实现中发生的事情
@NativeClass()
装饰类,因为我们正在扩展一个平台原生类,NSObject。implements UIDropInteractionDelegate
为所有可从该接口使用的方法提供丰富的 TypeScript 智能感知。static ObjCProtocols = [UIDropInteractionDelegate]
以告知 iOS 我们的对象符合UIDropInteractionDelegate。callback: (image: UIImage) => void
主要用于友好的 TypeScript 用法,以引用我们的回调并在拖放发生时进行通信。设置好这些细节后,我们的 JavaScript 工具函数现在可以为任何所需的 View 创建委托,以向其添加拖放交互。
// 1. Create a delegate with our callback reference
const dropDelegate = DropDelegate.new() as DropDelegate
dropDelegate.callback = callback
// 2. Add desired interaction configured with the delegate to our View
const drop = UIDropInteraction.alloc().initWithDelegate(dropDelegate)
(view.ios as UIView).addInteraction(drop)
我们可以获取任何 View 并使用它的 loaded
事件来设置连接。
<GridLayout (loaded)="loadedDropZone($event)">
<Image [src]="droppedImage" />
</GridLayout>
当 loaded
事件触发时,它会将 View
引用传递给我们的工具
function loadedDropZone(event) {
createDropZone(event.object, image => {
this.droppedImage = image
})
}
使用任何你喜欢的风格及其自己的绑定语法,这将在任何条件下都能正常工作。
令人惊奇的是,这一切现在都在 StackBlitz 上运行! 👉 https://stackblitz.com/edit/nativescript-drag-n-drop-ios