UITableViewCellのコンテンツビューにサブビューを追加すると、セルが選択不可能になります

私はいくつかの静的テキストをUITextViewのUITableViewCellに追加したいと思います。

UITextView *addressField = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 300, 75)];
[addressField setBackgroundColor:[UIColor clearColor]];
[addressField setFont:[UIFont fontWithName:@"HelveticaNeue" size:14]];
[addressField setContentInset:UIEdgeInsetsMake(0, 20, 0, 0)];
[addressField setEditable:NO];
[addressField setScrollEnabled:NO];

// change me later
[addressField setText:@"John Doe\n555 Some Street\nSan Francisco, CA, 00000"];

[cell.contentView addSubview:addressField];

[addressField release];

これはうまくいくが、私はこのコードによって、UITextViewがセル全体をカバーしているため、おそらくセルを選択不能にする。

私はUITextViewと選択可能なセルの両方を持つことができるように、どうすればこの問題を回避できますか?

btw、私はUITextViewのサイズを少し小さくすることができますが、ユーザーがUITextViewに触れてもセルを選択することはできません。

1

4 答え

私はそれを行うためのやや良い方法は、テーブル全体にタップジェスチャ認識機能を作成することだと思います。 (たとえば、あなたのviewDidLoadで)

// gesture recognizer to make the entire cell a touch target
UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] 
                             initWithTarget:self action:@selector(changeFocus:)];
[tableView addGestureRecognizer:tap];
[tap release];

次に、実際の選択を行うセレクタ(この場合はchangeFocus:)を作成します。

- (void)changeFocus:(UITapGestureRecognizer *)tap
{
  if (tap.state == UIGestureRecognizerStateEnded)
  {
    CGPoint tapLocation = [tap locationInView:self.tableView];
    NSIndexPath* path = [self.tableView indexPathForRowAtPoint:tapLocation];
    [self tableView:self.tableView didSelectRowAtIndexPath:path];
  }
}

changeFocusメソッドをより精巧にして、選択を妨げたり、選択したindexPathの特定のサブビューにフォーカスを当てたりすることができます。

2
追加された
このコードをお寄せいただきありがとうございます。私は元の投稿のような同様の問題について考えて2時間を過ごしました。私はこれを読みやすく簡単な解決策で保存しました:)
追加された 著者 d3p0nit,

私はこれが少しあなたを助けることを願っています:

[self.view insertSubview:TextView aboveSubview:TableView];

または、その逆も同様です。

1
追加された

UITextViewとUITableViewCellの両方でインタラクションを有効にするために、次のアプローチを採用します。

  • あなたのコントローラクラス(UITableViewControllerと思いますか?)をUITexViewデリゲートとして宣言してください。
  • UITextViewを宣言するときに、テーブルビューコントローラを委譲者として設定します。
  • テーブルビューコントローラ.mファイルのUITextViewDelegateメソッド(例: - (void)textViewDidChangeSelection:(UITextView *)textView)を実装します。
  • このメソッドの中から、カスタムコードを使用するか、tableView:(UITableView *)をトリガーすることによって、ターゲットセルを操作できます。tableView didSelectRowAtIndexPath:(NSIndexPath *)selectRowAtIndexPath:animated:scrollPosition:

あなたのコードは次のようになります。

テーブルビューコントローラの.hファイル:

@interface MyTableViewController : UITableViewController  { ...
...
}

テーブルビューコントローラ.mファイルの場合:

UITextView *addressField = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 300, 75)];
[addressField setDelegate:self];
...

次に、この関数を実装します(または他の適切なUITextViewDelegate関数)。

- (void)textViewDidChangeSelection:(UITextView *)textView {

   //Determine which text view triggered this method in order to target the right cell
    ...
   //You should have obtained an indexPath here
    ...
   //Call the following function to trigger the row selection table view  delegate method
    [self.tableView selectRowAtIndexPath:indexPath animated:YES    scrollPosition:UITableViewScrollPositionNone]

}

UITextViewをサブクラス化し、そのメソッドを処理するような他の選択肢があることに注意してください。私はその代理人のプロトコルによって提供される可能性を使用することをお勧めします。

また、UITextViewを宣言したり、少なくともテーブルビューコントローラクラスのインスタンス変数として参照したりすると便利かもしれません。これにより、どのaddressFieldがヒットしたかを容易に把握し、正しいindexPathを取得するのに役立ちます。

1
追加された
[addressField setUserInteractionEnabled:NO];
1
追加された