とある案件で諸事情によりiOS11で入った新機能、Drag and Dropを無効化しないといけなくなったため、調査して実際に入れた方法を記載します。
アプリがObjective-Cで書かれているため、ドキュメント込みで色々検索した結果、以下の投稿記事が引っかかったので参考にさせていただきました。
アプリ全体でiOS 11のドラッグを無効にするにはどうすればよいですか?
Swizzling(黒魔術)を使って無効化
参考にした投稿記事の通り、Swizzlingで一律無効化してしまいます。
コードは以下の通りです。アプリで一律無効化したいので、今回の例ではAppController.mmという名前のクラスに記載しています。
AppController.mm
#import <UIKit/UIKit.h>
#import <objc/runtime.h>
@implementation UIDragInteraction (TextLimitations)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class c = [self class];
SEL originalSelector = @selector(isEnabled);
SEL swizzledSelector = @selector(restrictIsEnabled);
Method originalMethod = class_getInstanceMethod(c, originalSelector);
Method swizzledMethod = class_getInstanceMethod(c, swizzledSelector);
BOOL didAddMethod =
class_addMethod(c,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(c,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
/**
* 差し替え用のisEnabledクラス
* 一律でNoを返す
*/
-(BOOL)restrictIsEnabled {
return NO;
}
@end
こんな感じでUIDragInteraction.isEnabledをSwizzlingして、iPadもNOが返るようにしました。
完全な黒魔術ですw
まとめ
Objective-CだとDrag and Drop無効化のやり方について情報がほとんど引っかからなかったので、結構苦労したのでメモがわりに書きました。
今回の無効化は、自分が調査した結果のあくまで一例です。
swizzlingで入れ替えるのは結構な黒魔法であり、あまり推奨されたやり方ではないので、他にも良い方法があるかもしれません。
Objective-Cはまだまだ勉強不足なため、コメント等で何か他にいい方法があれば意見をいただけると嬉しいです。