web-dev-qa-db-ja.com

-didSelectRowAtIndexPath:呼び出されていません

私はタブビュー内にテーブルビューを持つiOSアプリを書いています。私のUITableViewControllerでは、-tableView:didSelectRowAtIndexPath:を実装しましたが、実行時に行を選択してもメソッドが呼び出されません。テーブルビューが生成されているので、私は私のコントローラ内の他のtableViewメソッドが呼び出されていることを知っています。

これを実現するために私が失敗したかもしれないという考えを誰かが持っていますか?

284
Matt Pfefferle

UITableViewDelegateは自動的に設定されるはずですが、おそらくそのクラスはそのテーブルビューのUITableViewControllerではないようです。

あなたがデリゲートを他のクラスにリセットした可能性はありますか?

94
Hunter

念のために、誰かが私と同じ愚かなミスをしました。

あなたがdidSelectであることを期待しているもののメソッド名が何らかの方法で誤ってdidDeselectになっているかもしれないかチェックしてください。私が見つけるのに約2時間かかった...

533
CGee

この問題を引き起こす可能性があるもう1つのことは、選択されていない選択の種類です。

UITableView selection kind

通常の選択ではSingle Selectionにする必要があります。notにする必要がありますNo Selection

480
Dennis Krut

もう1つの可能性は、UITapGestureRecognizerがここでそうであったように、イベントを食べている可能性があるということです。 https://stackoverflow.com/a/9248827/21407

私はこの原因を疑わなかった、なぜならテーブルセルはまだタップが通り抜けているかのように青を強調表示するからである。

285
bugloaf

すべての良い答えですが、もう1つ注意が必要です...

(特にプログラムでUITableViewを作成する場合)

TableViewが[tableView setAllowsSelection:YES];を設定するか、それをNOに設定する行を削除することによって、選択に応答できることを確認してください。

149
Old McStopher

問題がUITapGestureRecognizerで発生した場合は、これを修正できます。

  • ストーリーボード内:

enter image description here

Objective-Cを含むコードで:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)]; 
[self.view addGestureRecognizer:tap];

[tap setCancelsTouchesInView:NO];

Swiftを含むコードで:

let tap = UITapGestureRecognizer(target: self, action:Selector("dismissKeyboard"))
view.addGestureRecognizer(tap)

tap.cancelsTouchesInView = false

私はこの状況で二つのことに遭遇しました。

  1. UITableViewDelegateプロトコルを実装するのを忘れたか、クラスとテーブルビューの間に委任アウトレットがありません。

  2. あなたはあなたの列の中にUIViewを持っているかもしれません。 UIButtonまたは同様のものを言います。

63
gilm

私は同じ問題を抱えています。そして見つけるのは困難でした。しかし、私のコードのどこかにこれがありました:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    return nil;
}

それはreturn indexPathでなければなりません、そうでなければ-tableView:didSelectRowAtIndexPath:は呼び出されていません。

44
JackPearse

UITableViewの上にgestureRecognizerを追加した場合、didSelectRowAtIndexPathは呼び出されません。

そのため、特定のビューでタッチを避けるためにgestureRecognizerデリゲートメソッドを使用する必要があります。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if ([touch.view isDescendantOfView:YourTable]) {
        return NO;
    }
    return YES;
}
37
Vinu David Jose

私は自分のコードを見ていない数ヶ月後に私が必要ではなかったいくつかの要件のために私が次の方法を実行することを忘れていた問題に遭遇しました

- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath  *)indexPath{
    return NO;
}

行を選択させるためには、行に対してYESを返すべきです。

28
cpt.neverm1nd

これらのオプションを選択しなければなりません

enter image description here

しかし、クリック時にUITableViewを強調表示しないようにする場合は、UITableViewCellプロパティを変更する必要があります。

以下のようにSelectionにNoneオプションを選択してください

enter image description here

24
Mohsin Qureshi

キーボードを消してdidSelectRowAtIndexPath:が呼び出されないようにするために、テーブルビューにUITapGestureRecognizerを付けました。誰かに役立つことを願っています。

20
Groot

私は同じ問題を抱えていました、

その理由はUITapGestureRecognizerの使用でした。他の場所をタップするとキーボードが消えるようにしたかったのです。私はこれがすべてのタップアクションをオーバーライドすることに気付きました、それがdidSelectRowAtIndexPath関数が呼び出されなかった理由です。

UITapGestureRecognizerに関連する行をコメントすると、うまくいきます。さらに、タップされたものがUITableViewCellであるかどうかUITapGestureRecognizer selectorの機能をチェックインすることができます。

19
Jeyhun Karimov

あなたが私と同じ問題を抱えている場合:どうやら、このメソッドはあなたのtableViewが編集モードになっている場合は呼び出されません。 permitSelectionDuringEditingをtrueに設定する必要があります。

この質問を介して: 編集時に、 `UITableView`はdidSelectRowAtIndexPath ??を呼び出さない

19
spiralstairs

Xcode 6.4の場合、Swift 1.2。選択 "tag"はIBで変更されました。どうやって、そしてなぜわからない。 「単一選択」に設定すると、テーブルビューのセルが再び選択可能になりました。 enter image description here

11
MB_iOSDeveloper

私の場合、didSelctRowAtIndexPathを呼び出さないのは、tableViewのSelectionプロパティでnonesingle selectionに設定したためです。

enter image description here

11
Naveed Ahmad

次のようにviewDidLoadメソッドでデータソースとデリゲートを設定することを忘れないでください。

[self.tableView setDelegate:self];

[self.tableView setDataSource:self];
10
Carlos

別の答えが受け入れられたとしても、私はこの問題を観察する人々のためのもう一つの可能​​な問題と解決策を追加するつもりです:

自動参照カウント(ARC)をオンにしている場合は、ビューの委任先としてコントローラーを割り当てた後でも、ARCがコントローラーを削除しているためにビューのメッセージがコントローラーに届いていないことがあります。明らかに、UITableViewのデリゲートポインタはARCの参照としてカウントされないため、それが唯一の参照である場合、コントローラは割り当て解除されます。コントローラにdeallocメソッドを実装し、そこでブレークポイントまたはNSLog呼び出しを設定することによって、これが発生しているかどうかを確認できます。

解決策は、もう必要ないと確信できるまで、他の場所で強力な参照を使用してコントローラを追跡することです。

10

私の問題は上記のどれでもありませんでした。そしてそれで足りない。しかし、私はそれが誰かに役立つ場合のためにここにそれをリストすると思いました。

私は私の "ベース"コントローラであるtableViewControllerを持っていて、それからこのコントローラのサブクラスを作ります。私はすべてのコードを "base"クラスのtableView:didSelectRowAtIndexPathルーチンに書いていました。デフォルトでこのルーチンが(何もしないコードがないにもかかわらず)私のすべてのサブクラスでも作成されたことを完全に忘れています。だから私が自分のアプリを実行したとき、それはコードのサブクラスバージョンを実行し、何もしなかった、そして私を悲しませた。だから、もちろん、一度サブクラスからルーチンを削除したら、それはmt "base"クラスのルーチンを使用していて、私は仕事をしている。

知っている。笑わないで。しかし、多分これは私が失った時間を誰かに節約するでしょう...

9
Steve

これに私の2セントを与えます。

カスタムのUITableViewCellを使用していて、セル全体をカバーするボタンがあったので、タッチが発生したときにはボタンは選択され、セルは選択されませんでした。

ボタンを削除するか、私の場合はボタンのUser Interation Enableをfalseに設定します。これでセルが選択されたことになります。

8
gmogames

これを読んでも、それでも問題は解決しません。

カスタムセル​​があります。チェックボックス "ser Interaction Enabled"は無効になっています。だから、私はそれをスイッチを入れるだけです。がんばろう。

8
HotJard

私はこれを持っていただけで、私がメソッドを追加しようとするときにオートコンプリートに注意を払わず、実際にはtableView:didDeselectRowAtIndexPathの代わりにtableView:didSelectRowAtIndexPath::を実装することになったためです。

7
user486646

私は古いことを知っていて問題は解決されましたが、同様の問題がありました。問題は私のカスタムUITableViewCellにあると思いました、しかし解決策は全く違っていました。ほとんどWindowsのように:)

5
Lukasz

テーブルビューが編集モード([tableView setEditing:YES animated:NO];など)になっている場合は、tableView.allowsSelectionDuringEditing = YES;を設定する必要があります。

5
yvetterowe

tableView:didSelectRowAtIndexPathではなくtableView:didDeSelectRowAtIndexPathを実装したことを確認してください

これは私に数回以上の機会に得られます!

5

私の場合、解決策は以下の関数でNOをYESに変更することでした。

iOS 9以降

- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
4
HonkyHonk

これらの答えのどれも私のために働きませんでした。約1時間後、私は非常に卑劣なことを考え出しました。

別のテーブルビューのセル内にテーブルビューがあります。私は、とりわけ、内側のテーブルビューを含む包含ビューを作成することにしました。このビューをcontentViewと呼び、xibにフックしました。

UITableViewCellにはすでにcontentViewがあり、それを使って奇妙なことをしていることがわかりました。プロパティの名前をmainContentViewに変更し、この名前を変更したプロパティにビューを再接続すると、問題は自動的に解決しました。

4
xytor

私の場合は、ロード時にTableViewSuperViewの高さを動的に計算します。計算の誤りにより、TableViewSuperViewの外側に位置していました。 TableViewは正しく描画されましたが、すべての対話が無効になりました(そしてdidSelectRowAtIndexPathは呼び出されませんでした)。 TableViewが「アクセス可能」ではないことを視覚的に示すものがないため、検出が非常に困難です。

4
GK100

あなたがしたかもしれないもう一つの間違い(私がしたように):あなたがセルにセグエを設定した場合、didSelectRowAtIndexPathは呼ばれません。代わりにビューコントローラで自分のセグエを設定する必要があります。

4
juanignaciosl

この記事にはいくつかの素晴らしい手がかりと答えがあります(おそらく私がこれまでに見た中で最高の議論の1つです!)ここで手がかりが私の問題を突き止めるのに役立ちました。他の記事と似ていた問題。しかし、私がそれを発見した方法は少し異なっていたので、他の人がそれに遭遇した場合に備えて共有したいと思いました。

私の問題は、コードでは、スーパークラスが非表示ではなく透明なフルスクリーンの「エラービュー」を追加していたことです。しかし、それはテーブルビューの上にあり、 "user action"がYESに設定されているので、それはテーブルビューに対する私のタッチを傍受していました。

私はXcodeのかっこいい「Debug View Hierarchy」ボタンを使ってこれを診断しました。これは私がしたこと、そしてどうやって問題を診断したのかを説明する注釈付きのスクリーンショットです。

コードでは、私は単にしなければならなかった:

errorMessageView.setUserInteractionEnabled = NO;
// or
errorMessageView.hidden = YES;

Debug View Hierarchy

3
DustinB

さて、私がこの問題に遭遇した時にここで更新しました、そして私の問題はここで発見されたものとわずかに異なっていました。

私はIBを見て、自分のデリゲートが設定されているのを見ましたが、それはファイルの所有者ではなくVIEWに間違って設定されていました。

誰かに役立つことを願っています

3
tbone

ストーリーボードのUITableViewプロパティに注意してください。私の場合は、didSelectRowAtIndexPathメソッドを実行できないストーリーボードのコンボボックスを "Selection:Single Selection"として選択していました。

3
Diego Maye

カスタムセルがある場合は、そのセルのXibで(またはコードで)UserInteractionEnabledを設定することを忘れないでください。

2
giuseppe

私の場合は、この問題を抱えているセルは1つだけでした。セルに読み取り専用モードのUITextViewアウトレットが含まれていました。タップする前に読み取り専用でしたが。タップすると、キーボードが上がりました。それはまだ相互作用を無効にする必要があることがわかった。

cell.content.scrollEnabled = NO;
cell.content.editable = NO;
cell.content.userInteractionEnabled = NO;
cell.content.delegate = nil;

[cell.content resignFirstResponder];

2
Imju

クリックしているセルが強調表示されていても関数がまだ呼び出されていない場合は、関数のシグネチャをもう一度確認してください。これは次のようになります。

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
2
Jeb_is_a_mess

これはおそらく私の場合だけでしたが、私はいくつかのファイルをバックアップから再ロードしていて、これを含むものがうまくいっていませんでした。フルクリーン(プロダクト>クリーンまたはShift + Command + K)を実行した後にそれは働いた。おそらく、プリコンパイル済みヘッダーで何かがおかしくなっているのでしょう。たぶんそれはあなたにとって問題ではないです、しかしそれは一撃の価値があります。

2
shim

あなたのviewControllerが以下のメソッドを持っているか確認してください。

- (BOOL) tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
    return NO;
}

"NO"を返した場合、didSelectRowは呼び出されません。

2
Srinath Mithra

私の場合、問題はUITableViewCellサブクラスがあり、タッチで派手なアニメーションを処理するためにtouchesBegan:withEvent:touchesEnded:withEventの2つのメソッドを実装していました。しかし、[super touchesBegan:touches withEvent:event];メソッドと[super touchesEnded:touches withEvent:event];を追加して、セルのタッチを親に知らせることも忘れていました。

したがって、コードを次のように変更すると、私の問題が解決しました:

-(void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
    [super touchesBegan:touches withEvent:event];
    //blah blah blah
}

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    [super touchesEnded:touches withEvent:event];
    //rest of the code
}
2
alternatiph

-heightForRowAtIndexPathが0を返さないかどうかを確認してください。

2
shyamsundar1988

私は断続的にこの問題を抱えていました。セルに触れると選択されることがあります。時々それはtouchイベントを受け取らないでしょう。

私は、ios 8で導入された自己サイズ調整セルと呼ばれる機能を使用しています。私はこれに遭遇しました ブログ記事 それはそれを指摘しています:

テーブルビューが最初に表示されたとき、セルのサイズが正しくないことがあります。ただし、テーブルビューをスクロールすると、新しいセルは正しい行の高さで表示されます。この問題を回避するには、ビューが表示された後に強制的にリロードを実行します。

override func viewDidAppear(animated: Bool) {
    tableView.reloadData()
}

これで問題は解決しました。テーブルビューが正しくレンダリングされていても、タッチ処理(特にUITableViewのhitTest)が上記のバグの影響を受けているようでした。

1
benvolioT

私はちょうどこの問題を抱えていましたが、それはすぐには起こりませんでした。いくつかのセルを選択した後、彼らはdidSelectItemAtIndexPathの呼び出しを停止します。問題は、コレクションビューのallowsMultipleSelectionがTRUEに設定されていることです。セルの選択が解除されることはなかったため、これ以降の呼び出しでdidSelectItemAtIndexPathを呼び出すことはできませんでした。

1
Mark Bridges

もう一つの狂った可能性:私はiPhone 5Sで私のアプリを実行していました、そして私は使用しました:

- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

私はいつも過去にやったように。

しかし、私は私のコンパイラの警告を十分に詳しく見ていなかった...それは私が上記の行を次のように変えるべきだと言った:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

64ビット互換! 拳を振る

あなたがあなたの髪を引き抜き始める場合に備えて見張りをしてください。

1
karlbecker_com

私はいくつかのカスタマイズされたテーブルコードに埋め込まれたcell.userInteractionEnabledへの呼び出しがありました。

愚かな、それでもほとんどのバグではありませんか?

1
HalR

私は前の答えをすべて繰り返しましたが、どれも助けにはなりませんでした。少し試行錯誤した後、私は別の解決策を見つけました。セル全体をカバーするUIImageViewを(背景として)持っていました。デフォルトでは、UIImageViewはユーザインタラクションを無効にしています。 imageviewsのユーザーインタラクションデリゲートメソッドを有効にすることで、-didSelectRowAtIndexPath:が再度呼び出されました。例えば。

cell.imgView.userInteractionEnabled = YES;
1
Yannick Winters

私は自分でこの問題を抱えていました。私はビューの骨をIBで構築しただけで(ビューとテーブルビューだけ)、デリゲートは設定されませんでした。私はそれをFile's Ownerに接続しました、そしてそれは魅力のように働きました。 ::保存する::

1
indigosplinter

もう1つの考えられる原因は、UITableViewUIScrollViewに埋め込まれていることです。誤って通常のビューではなくスクロールビューをコントローラのルートビューとして使用していたため、今日この問題が発生しました。

1
Taum

私はコメントできません、ここに書いてください。私の場合はdidSelectRowは機能しましたが、didDeselectRowは機能しませんでした。 delegatedataSourcetableViewを設定し、これで私のケースは解決しました。

0
Hot'n'Young

私の場合、問題はメソッドをプライベートとして宣言することでした。

これはうまくいきませんでした。

private func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

これはうまくいった:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
0

必ずメインスレッドでreloadDataを呼び出してください。ある種の非同期メソッド(たとえば、ある種のネットワーク要求)からそのメソッドを呼び出している場合、Table Viewは正しく応答したり応答しなかったりします(場合によっては、アプリケーションがクラッシュすることさえあります)。

呼び出しが他のメソッドブロックで行われている場合(念のためわからない場合)、メインスレッドコードブロックを使用してreloadData呼び出しを実行します。

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
    [tableView reloadData];
}];
0
Supertecnoboff

私はdidSelectメソッドをnot取得する別の方法を見つけました。ある時点で、おそらくfunc宣言自体のエラー中に、XCodeは@nonobjcを自分のメソッドに追加することを提案しました。

@nonobjc func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

これは文句なしにコンパイルを続けますが、あなたはuiアクションによって呼び出されることは決してないでしょう。

「それは私の2セントです。私は自分の変化を取り戻したいのです」

0
Dilapidus
  1. @interface ExampleViewController () <UITableViewDelegate, UITableViewDataSource>を追加

  2. ストーリーボードで代表団を作る

enter image description here

  1. コードを追加

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
       NSString *cellText = cell.textLabel.text;
    }
    
0
dip

UITapGestureRecognizerを確認してください。私の場合、tableviewが配置されたビューにtapgestureが追加されました。これは、didselectのようなUITableviewのユーザーインタラクションを食べています。ビューのタップジェスチャを無効にした後、didselectデリゲートがトリガーされました。

0
Prasad.Jakka

私はすべての答えを読み、そしてそれらに強く同意します。しかし、私の場合はまったく違います。私はsegueの新しいdetailViewControllerをStoryBoardの私のtableCellに直接リンクしていましたが、これが原因でした。だから私は自分のセルからそのセグエを取り除き、それをUITableViewController自身とリンクさせなければなりませんでした。さて、以下のコードを書くことによってそれは機能します、

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        // Do any operation
        performSegue(withIdentifier: "DetailSegue", sender: self)
    }

この解決法が誰かに役立つことを願っています!

0
Sasi M

この選択は単一選択であり、編集中は編集を選択できないようにし、テーブルビューで編集する場合はuttableviewcellプロパティの設定を変更します。識別子はRidで、セクションはnoneです。

0
ATIQ UR REHMAN

誰かがこの答えを見るのに十分遠くまでスクロールしたかどうかはわかりませんが、これはこの問題に関する最も一般的な質問であり、答えはそこにはありませんでしたので追加します。

Xcode 9/Swift 4では、すべてのObjective-Cメソッドは@objcとマークされるべきです。コンパイラはどこに適用すべきかを認識するのに合理的な仕事をしますが、継承はわかりません。例えば:

class Delegate: NSObject, UITableViewDelegate {
}

class SuperDelegate: Delegate {
    override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { return indexPath }
}

これによって警告、クラッシュ、ビルドエラーが発生することはありません。しかし、あなたの行は@objcを追加するまで呼び出されません。

@objc class SuperDelegate: Delegate {
    override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { return indexPath }
}
0
Departamento B

ブレークポイントを適用した後に行を選択しても制御ができないという問題がありました。問題は視野に入っていた。タブジェスチャを表示から削除しました。それからそれはうまく働いた

0
user2110847

私の場合、ちょっとしたミスをしたのですが、

tableView.isUserInteractionEnabled = false

そのはず:

tableView.isUserInteractionEnabled = true
0
Vinayak Pal