4

この質問と同様に、UITextField を持つ UITableViewCell のカスタム サブクラスがあります。ユーザーが別のテーブルビューセルまたはテーブルの外にあるものに触れたときに、キーボードが消えないことを除いて、正常に動作します。セルの外側の何かが触れられたときに見つけるのに最適な場所を見つけようとしています。それから、テキスト フィールドで rejectFirstResponder を呼び出すことができます。

UITableViewCell がビュー外のタッチのタッチ イベントを受信できる場合は、ResignFirstResponder 自体を再起動できますが、セルでこれらのイベントを取得する方法がわかりません。

編集: UITableViewCell サブクラスでこれ(以下)を試しましたが、動作しません。イベントがコントロールによって処理された場合、 touchesBegan:withEvent: が呼び出されないためだと思います。イベントがレスポンダーチェーンに送信される前に、イベントをキャッチする必要があると思います。

私が検討している解決策は、ビュー コントローラーに touchesBegan:withEvent: メソッドを追加することです。そこで、タッチがあったものを除いて表示されているすべてのテーブルビュー セルに、resignFirstResponder を送信できます (タッチ イベントを取得して、それ自体を処理させます)。

たぶん、この擬似コードのようなもの:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    CGPoint touchPoint = // TBD - may need translate to cell's coordinates

    for (UITableViewCell* aCell in [theTableView visibleCells]) {
        if (![aCell pointInside:touchPoint withEvent:event]) {
             [aCell resignFirstResponder];
        }
    }
}

これが最善の方法であるかどうかはわかりません。tableviewcell 自体がビュー外のイベントのイベント通知を受け取る方法はないようです。

EDIT2: hitTest: withEvent : を使用して回答があると思いました (回答として投稿したこともありました) が、うまくいきませんでした。いつも呼ばれるとは限りません。:-(

4

3 に答える 3

10

[Edited: removed previous attempt which didn't always work, this one does]

OK、ついに完全に機能するソリューションを見つけました。UITableView をサブクラス化し、hitTest:withEvent: メソッドをオーバーライドしました。これは、テーブル ビュー内のすべてのタッチに対して呼び出されます。他に可能なタッチはナビゲーション バーまたはキーボードのみであり、テーブルビューの hitTest はそれらについて知る必要はありません。

これは、テーブル ビューでアクティブなセルを追跡し、別のセル (または非セル) をタップするたびに、非アクティブになるセルに rejectFirstResponder を送信します。これにより、キーボード (または日付ピッカー) を非表示にする機会が与えられます。

-(UIView*) hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
    // check to see if the hit is in this table view
    if ([self pointInside:point withEvent:event]) {
        UITableViewCell* newCell = nil;

        // hit is in this table view, find out 
        // which cell it is in (if any)
        for (UITableViewCell* aCell in self.visibleCells) {
            if ([aCell pointInside:[self convertPoint:point toView:aCell] withEvent:nil]) {
                newCell = aCell;
                break;
            }
        }

        // if it touched a different cell, tell the previous cell to resign
        // this gives it a chance to hide the keyboard or date picker or whatever
        if (newCell != activeCell) {
            [activeCell resignFirstResponder];
            self.activeCell = newCell;   // may be nil
        }
    }

    // return the super's hitTest result
    return [super hitTest:point withEvent:event];   
}    

UITextField を持つ私の UITableViewCell サブクラスでは、次のコードを追加して、キーボード (またはキーボードと同じようにスライドする日付ピッカー) を取り除きます。

-(BOOL)resignFirstResponder
{   
    [cTextField resignFirstResponder];  
    return [super resignFirstResponder];
}

わーい!

于 2010-03-16T04:05:18.930 に答える
0

これは非常に優れたソリューションであり、ネット上で見つけた中で最高のものです。私が発見した唯一の不具合は、テキストフィールドのあるセルから別のセルに移動すると、キーボードが閉じて再表示され、ぎくしゃくしたタイプのアニメーションになることです。

于 2010-08-10T23:34:26.423 に答える
0

あなたは正しい軌道に乗っていると思いますがtouchesBegan:withEvent:、UIResponder メソッドであるため、実際には UIViewController サブクラスではなく UIView サブクラスでオーバーライドする必要があります。オプションは次のとおりです。

  • すでに UITableViewCell をサブクラス化している場合は、そこでオーバーライドtouchesBegan:withEvent:してください。
  • 標準の UITableViewCell を使用している場合はtableView:didSelectRowAtIndexPath、UITableView のデリゲートに実装します。
于 2010-03-15T23:59:19.770 に答える