0

私は最近、選択および選択解除機能に関してUITableViewにいくつかの興味深いバグを見つけました。(mbそれ自体はバグではありませんが、この状況は非常に異常だと思います)。

先史時代:UIDatePickerを使用して日付を選択し、それをセルのラベルに配置できるカスタムTableViewCellクラスを作成しようとしていました。「CellDate」サンプルは私にはあまり良くありません。そのため、カスタムinputViewをセルに設定し、それをファーストレスポンダーにしようとしていました。しばらく調査した結果、カスタムUITableViewCellサブクラスの読み取り専用inputViewプロパティをオーバーライドする方法を見つけました。これで、完全に機能します。セルが選択され[self becomeFirstResponder]ている場合は呼び出し、セルが選択解除されている場合は呼び出す[self resignFirstResponder]ので、問題なく機能します。いくつかのバグがあります。

カスタムセルを画面に表示している場合(つまり、画面からスクロールアウトしていない場合)、すべてが正しいですが、それを選択すると

カスタムセルの選択

tableViewを下にスクロールして、セルが画面に表示されないようにします

下にスクロールすると、カスタムセルが画面に表示されなくなります

次に、別のセルを選択します

カスタムセルが画面に表示されていないときに他のセルを選択する

カスタムセルの選択が解除されません

予期しない結果

デフォルトのUITableViewCellの機能の唯一の主な変更点は次のとおりです。

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    if (selected)
    {
        [self becomeFirstResponder];
    }
    else
    {
        [self resignFirstResponder];
    }
}

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

このメソッドオーバーライドのみを使用すると、このバグが発生します。現在選択されているカスタムセルが画面外にある場合、何らかの理由で選択が解除されません。

私の質問は:誰かがこのようなことを経験しましたか、そして私にできることはありますか?これとは別に、日付セルの問題に対する完璧な解決策があるからです。

それはUITableViewCellsを操作する正しい方法ではありませんか?私は完全に間違ったことをしていますか?私はiOSを学び始めたばかりなので、iOSのいくつかの側面にあまり詳しくないかもしれません。

PS私の悪い言語で申し訳ありませんが、私は英語を母国語とはしていません。

アップデート:

私はいくつかの詳細を見つけました。いくつかの調査の結果、tableViewをスクロールして、tableViewCellを画面外に非表示にすると、その(セル)が破壊されていることがわかりました。スクロールバックすると、tableViewのデリゲートのtableView:cellForRowAtIndexPathを呼び出して再度作成されます。これとは別に、画面外にある行のindexPathに対して[tableView cellForRowAtIndexPath:indexPath]を呼び出そうとすると、tableViewはnilを返します。 。

ただし、奇妙なことに、カスタムセルがfirstResponderである場合、明らかに、tableViewのデリゲートのtableView:cellForRowAtIndexPath:を介して再作成されることはなく、[tableView cellForRowAtIndexPath:indexPath]を介してアクセスすることもできません。

私に関しては、それは非常に奇妙です。

4

2 に答える 2

0

質問に直接答えるために、UITableViewはそれ自体でセルの選択を解除しません。TableViewのコントローラーで、-(void)tableView:(UITableView *)tableView didselectRowAtIndexPath:(NSIndexPath *)indexPath選択したセルをオーバーライドして手動で選択解除する必要があります。

-(void)tableView:(UITableView *)tableView didselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animate:YES];
}

(編集して申し訳ありませんが、回答中に誤って保存してしまいました)

UITableViewCellのサブクラスでは、-(void)setEditing:(BOOL)editing animated:(BOOL)animatedセルを編集可能な状態に移行するためにオーバーライドする必要があります。(UITextFieldを編集可能に設定します)次に、セルで、テキストボックスをファーストレスポンダーにする/辞任します。

ファーストレスポンダーは、何かが編集可能であるときにキーボードに応答する次のオブジェクトになるために使用されます。

たとえば、セルc1とセルc2があるとします。c1とc2の両方にUITextFieldsがあります。あなたはc1にいて、キーボードのReturnボタンでテキストカーソルをc2に移動したい場合、c1の場合、UITextFieldをファーストレスポンダーとして辞任させ、c2にUITextFieldをファーストレスポンダーにするように指示する必要があります。これを行うには、カスタムセルをUITextFieldのデリゲートにし-(BOOL)textFieldShouldReturn:(UITextField *)textField、textFieldをファーストレスポンダーとして再署名するように実装します。次に、UITableViewのコントローラーに、次のセルにテキストフィールドをファーストレスポンダーにするように指示します。

于 2013-02-19T20:16:29.167 に答える
0

私は自分で解決策を見つけました。他の行が選択されているときにファーストレスポンダーを辞任するのと同じくらい簡単なようです。ちなみに、私はこれを達成するためにこの答えを使用しました。

それが誰かを助けることができることを願っています。

于 2013-02-20T09:51:04.960 に答える