[iOS]ストーリーボードでマルチタップの優先度を設定したい


このメソッド、UIViewControllerのカテゴリに仕込むと幸せになれます。要するに「数の多いタップジェスチャを先に処理する」ように設定するものです。
この処理が必要なストーリーボードのviewDidLoadメソッドで[self tapPriolityChange];のように呼んでおけばオシマイ。

Objective-Cの良さって、Objectのpropertyの値でソートします、みたいなのがまあまあ簡単に書けちゃうところにあるんだよね、的な。それにしても、この書き方、色々なところで応用できそうですね。

//ストーリーボードで生成したtapジェスチャで複数回タップを優先処理させるための設定を行うための初期化メソッド

code

-(void)tapPriolityChange
{
    NSMutableArray *sorting = [NSMutableArray new];
    NSSortDescriptor *tapsSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"self.numberOfTapsRequired" ascending:YES];
    NSArray *grs = [[self view]gestureRecognizers];//viewに設定されているジェスチャーレコグナイザの配列を取り出す。
    if (!sorting || !tapsSortDescriptor || !grs)//データが揃ってなければ終了
    {
        sorting = nil; tapsSortDescriptor = nil; grs = nil;
        return;
    }
    for ( id gr in  grs )//高速列挙にて、UITapGestureRecognizerのみを取り出す
    {
        if([gr isMemberOfClass:[UITapGestureRecognizer class]])
        {
            [sorting addObject:(UITapGestureRecognizer*)gr];
        }
    }
    NSArray *sortedGrs = [sorting sortedArrayUsingDescriptors:@[tapsSortDescriptor]];//Tap数でascendソートした結果をsortedGrsへ
    if (sortedGrs && sortedGrs.count > 1)//タップジェスチャーが複数ある場合だけ優先度を付ける。ascendソート済みなので、後ろのものが優先されるように設定する
    {
        for (int i = 1; i < sortedGrs.count; i++)
        {
            [(UITapGestureRecognizer*)sortedGrs[i-1] requireGestureRecognizerToFail:(UIGestureRecognizer *)sortedGrs[i]];
        }
    }
    sorting =nil; tapsSortDescriptor = nil; grs = nil; sortedGrs = nil;
    return;
}