如何在整个应用程序中禁用 iOS 11 拖动?

Posted

技术标签:

【中文标题】如何在整个应用程序中禁用 iOS 11 拖动?【英文标题】:How to disable iOS 11 dragging within the whole app? 【发布时间】:2018-02-14 01:00:25 【问题描述】:

出于安全原因,我想在整个应用程序中禁用新的 ios 11 拖放功能。更具体地说是拖动部分。

在 iOS 11 中,默认情况下,所有可以选择文本的地方的文本都会发生这种情况 - 弹出窗口、文本视图、网络视图等。

【问题讨论】:

【参考方案1】:

我不知道有什么方法可以完全禁用拖动功能,但有一种方法可以将拖动会话仅限于您自己的应用程序。这在安全性方面应该已经有了很大的改进。

看看sessionIsRestrictedToDraggingApplication。

dragInteraction(_:sessionIsRestrictedToDraggingApplication:)

调用以询问您的应用是否应将拖动会话限制在它开始的应用中。

【讨论】:

【参考方案2】:

默认情况下不启用拖放。您需要通过向视图提供拖动交互委托来启用它。所以你可能不需要禁用拖放,如果你没有实现它。

注意: Text views and text fields automatically support drag and drop. 但它的默认行为是允许使用 UIMenuController 将内容从一个源复制到另一个源。拖放可以轻松复制粘贴文本输入视图的文本内容。与当前使用 UIMenuController 进行数据共享的稳定 OS 功能相比,拖放对数据安全问题没有影响。

这是 Apple 的声明。

Making a View into a Drag Source通过实现拖拽 交互委托 (UIDragInteractionDelegate) 的视图,你 使该视图在您的应用中用作拖动源。

启用视图作为拖动源 UIView 的任何实例或子类都可以作为拖动源。实现这一目标的第一步是:

    创建拖动交互(UIDragInteraction 实例)。 指定拖动交互的委托(符合 UIDragInteractionDelegate 协议的对象)。 将交互添加到视图的交互属性中。

以下是如何使用自定义帮助方法来执行此操作,您通常会在视图控制器的 viewDidLoad() 方法中调用该方法:

func customEnableDragging(on view: UIView, dragInteractionDelegate: UIDragInteractionDelegate) 
    let dragInteraction = UIDragInteraction(delegate: dragInteractionDelegate)
    view.addInteraction(dragInteraction)

创建拖动项 拖动项封装了源应用程序为一个模型对象提供各种数据表示的承诺。 要创建拖动项,请实现dragInteraction(_:itemsForBeginning:) 拖动交互委托中的方法,如下所示以最小形式显示:

func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] 
    // Cast to NSString is required for NSItemProviderWriting support.
    let stringItemProvider = NSItemProvider(object: "Hello World" as NSString)
    return [
        UIDragItem(itemProvider: stringItemProvider)
    ]

此实现使用 init(object:) 便利初始化程序。当你实例化一个拖动项时,以你的应用程序的本机表示形式传递一个对象,或者以你支持的最高保真表示形式传递一个对象。通常,请确保项目提供程序的registeredTypeIdentifiers 数组中的第一个元素代表您的拖动交互委托可以提供的最高保真度数据。 要向拖动项添加更多数据表示,就像您通常在应用程序中所做的那样,请按照保真度从高到低的顺序添加它们。添加表示时,您可以选择:

在许多情况下,将多个数据表示添加到拖动项的最佳选择是在模型类中采用NSItemProviderWriting 协议。使用此协议,您可以在模型类中放置用于提供多种数据表示的代码。 您可以使用registerObject(_:visibility:) 方法或NSItemProvider 类中的相关方法来显式注册数据表示。

【讨论】:

文本默认启用。 我已经更新了我的答案。希望对您了解它对数据安全的影响有所帮助。 抱歉,这不是我的问题的答案。我需要禁用将文本从我的应用程序拖动到另一个应用程序。我已经禁用了所有其他让文本离开应用程序的方法。【参考方案3】:

找到了解决办法。这是在您的应用程序可能需要的情况下,对 UIDragInteraction 的 isEnabled 方法进行方法调配以返回 NO。请注意,通常使用 swizzle 方法不是一个好主意。

@implementation UIDragInteraction (TextLimitations)
+ (void)load

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^

        Class class = [self class];

        SEL originalSelector = @selector(isEnabled);
        SEL swizzledSelector = @selector(restrictIsEnabled);

        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

        BOOL didAddMethod =
        class_addMethod(class,
                        originalSelector,
                        method_getImplementation(swizzledMethod),
                        method_getTypeEncoding(swizzledMethod));

        if (didAddMethod) 
            class_replaceMethod(class,
                                swizzledSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
         else 
            method_exchangeImplementations(originalMethod, swizzledMethod);
        
    );


-(BOOL)restrictIsEnabled

    if (restrictedCondition)
    
        return NO;
    
    return [self restrictIsEnabled];

【讨论】:

以上是关于如何在整个应用程序中禁用 iOS 11 拖动?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 11 的 UITextfield 中启用拖动

如何在 iOS 11 应用程序登录屏幕中禁用新密码自动填充功能?

如何在 iOS 网络应用程序中禁用橡皮筋?

iOS 7:禁用整个应用程序的 UINavigationBar 半透明

如何在IOS中禁用自动省略号

禁止在整个项目 HTML 页面中拖动图像