47

私はしばらくこれについて頭を悩ませていましたが、それを理解しました。このウェブサイトから多くの助けを得たので、コミュニティに還元したいと思います:)。

ある UITableView から別の UITableView にアイテムをコピーしようとしていますが、これを行う方法に関してウェブで見た情報はせいぜい大ざっぱです。私は自分でそれを理解したので、私の小さなアーキテクチャについて説明します。

  • マスター UIView
    • UITableView を使用した UIView
      • カスタム UITableViewCell
        • コピーされるカスタム UIView (私の場合は Person オブジェクト)
    • UITableView を使用した UIView
      • カスタム UITableViewCell
        • コピーされるカスタム UIView (私の場合は Person オブジェクト)

UITableView にある人物オブジェクトは、あるテーブルから別のテーブルにドラッグ アンド ドロップしたいオブジェクトです。アイテムをテーブルからポップして、1 回のスムーズな動きでドラッグする方法を理解するのが最も困難でした。長い間、操作を実行するのに 2 回のタッチが必要でした。

Person オブジェクトから始めて、これは画像を含む単純なオブジェクトです。ドラッグが行われているときに Person の中心位置を変更するには、独自の touchesMoved メソッドを実装する必要がありました。

-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    if( m_moveable == YES ){
        UITouch *touch = [touches anyObject];
        CGPoint location = [touch locationInView:self.superview];

        if( 0 < location.x-50 && location.x+50 < 768 ){ 
            if( 0 < location.y-50 && location.y+150 < 1004 ){
                self.center = location;
            }
        }
    }
}

Person オブジェクトの userInteractionEnabled フラグを初期化時に NO に設定して、テーブル内のクリックが Person オブジェクトによってキャッチされないようにします。その場合、Person オブジェクトはテーブル内で移動し、目的に反します。

次のオブジェクトは、カスタム UITableViewCell です。このオブジェクトは、ユーザーの最初のタッチをキャッチする役割を果たします。それがすべきことは、このタッチをキャッチして Person を「ポップ」することです。Person は、カスタム UITableViewCell に属するサブビューの 1 つです。

 - (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UIView *parent = self.superview.superview.superview;    

    Person *s = nil;
    for( UIView *child in self.subviews ){
        if( [child isKindOfClass:[Person class]] ){
            s = child;
            s removeFromSuperview];
            break;
        }        
    }

    if( s != nil ){
        self.userInteractionEnabled = NO;
        s.userInteractionEnabled = YES;
        UITableView *subParent = self.superview;   //EDIT #1
        subParent.scrollEnabled = NO;              //EDIT #1

        [parent addSubview:s];
        //[self touchesEnded:touches withEvent:event]; //EDIT #1
    }
}

上記のメソッドで userInteractionEnabled フラグが反転することに注意することが重要です。タッチする前は、Person オブジェクトは人のタッチに対して「立入禁止」になっています。カスタム セルが移動をキャッチした後、親のビューに追加して Person を解放し、アクティブ化します (userInteractionEnabled=YES)。次に、Person オブジェクトが「生まれ」、それ自体で移動タッチを処理できます。

これには、Person オブジェクトが左上隅で点滅するが、すぐにユーザーの指に落ちるという小さな不具合が 1 つあります。

この設計の最後の部分は、マスター UIView が「タッチ遷移」を処理する必要があることです。ユーザーがテーブルに触れて Person オブジェクトがポップアウトされた場合、アプリはフォーカスをテーブルから削除して Person オブジェクトに向ける必要があることを認識する必要があります。これが行われた方法は、マスター UIView の hitTest メソッドが次のようにオーバーロードされたことです。

- (UIView*) hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    UIView *rv = nil;
    for(UIView *child in self.subviews){
        if( [child isKindOfClass:[Person class]] ){
            rv = child;
            child.center = point;
            break;
        }
    }
    if( rv == nil ){
        rv = [super hitTest:point withEvent:event];
    }   
    return rv;
}

このコードが機能する方法は、Person がテーブルからポップアウトされたときに、それに焦点を合わせていないということです。タッチは、Person がポップアウトされた UITableView によって「所有」されます。hitTest メソッドは、そのタッチに焦点を合わせ直すための鍵です。定期的に、システムはどの UIView がタッチのフォーカスであるかを確認します。hitTest メソッドは、その UIView を識別するためにシステムによって呼び出されます。Person がマスター ビューにアタッチされている場合、この hitTest 関数はすべてのサブビューを反復し、Person の存在を検出して、それを「主要な」タッチ オブジェクトとして返します。指の動きは、UITableView ではなく Person にすぐに報告されます。

これが実装の根性です。UITableView で移動オブジェクトを「キャッチ」するのは簡単です。ご不明な点がございましたら、投稿してください。

EDIT #1 Person オブジェクトの削除は、思ったよりも難しいことがわかりました :)。UITableView がすべての移動イベントを吸い込んでいるため、親が移動しているときに UITableView がスクロールしないようにする行を追加する必要がありました。
touchesEnded 関数はカスタム UITableViewCell クラスで起動します。
mj

4

1 に答える 1

7

こんにちは、UITableView の行を同じテーブルの別の行にドラッグ アンド ドロップすることができました。移動するアイテム (テーブルから削除されていない) を表す uiImageView を作成し、最前面の UIView にアタッチして、画面全体でドラッグできるようにしました。ここに私が直面した痛みに関するいくつかの投稿があります:

  1. UITableView: 行を別の行にドラッグします
  2. UITableView: プログラムによるコンテンツ ビューのスクロール
  3. UITableView: カスタム ジェスチャにより、スクロールしなくなりました

これが役立つことを願っています^^

于 2010-08-21T07:01:04.403 に答える