私はタブビュー内にテーブルビューを持つiOSアプリを書いています。私のUITableViewController
では、-tableView:didSelectRowAtIndexPath:
を実装しましたが、実行時に行を選択してもメソッドが呼び出されません。テーブルビューが生成されているので、私は私のコントローラ内の他のtableViewメソッドが呼び出されていることを知っています。
これを実現するために私が失敗したかもしれないという考えを誰かが持っていますか?
UITableViewDelegate
は自動的に設定されるはずですが、おそらくそのクラスはそのテーブルビューのUITableViewController
ではないようです。
あなたがデリゲートを他のクラスにリセットした可能性はありますか?
念のために、誰かが私と同じ愚かなミスをしました。
あなたがdidSelect
であることを期待しているもののメソッド名が何らかの方法で誤ってdidDeselect
になっているかもしれないかチェックしてください。私が見つけるのに約2時間かかった...
この問題を引き起こす可能性があるもう1つのことは、選択されていない選択の種類です。
通常の選択ではSingle Selection
にする必要があります。notにする必要がありますNo Selection
。
もう1つの可能性は、UITapGestureRecognizerがここでそうであったように、イベントを食べている可能性があるということです。 https://stackoverflow.com/a/9248827/21407
私はこの原因を疑わなかった、なぜならテーブルセルはまだタップが通り抜けているかのように青を強調表示するからである。
すべての良い答えですが、もう1つ注意が必要です...
(特にプログラムでUITableViewを作成する場合)
TableViewが[tableView setAllowsSelection:YES];
を設定するか、それをNO
に設定する行を削除することによって、選択に応答できることを確認してください。
問題がUITapGestureRecognizer
で発生した場合は、これを修正できます。
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
私はこの状況で二つのことに遭遇しました。
UITableViewDelegateプロトコルを実装するのを忘れたか、クラスとテーブルビューの間に委任アウトレットがありません。
あなたはあなたの列の中にUIViewを持っているかもしれません。 UIButtonまたは同様のものを言います。
私は同じ問題を抱えています。そして見つけるのは困難でした。しかし、私のコードのどこかにこれがありました:
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
return nil;
}
それはreturn indexPath
でなければなりません、そうでなければ-tableView:didSelectRowAtIndexPath:
は呼び出されていません。
UITableViewの上にgestureRecognizerを追加した場合、didSelectRowAtIndexPath
は呼び出されません。
そのため、特定のビューでタッチを避けるためにgestureRecognizerデリゲートメソッドを使用する必要があります。
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isDescendantOfView:YourTable]) {
return NO;
}
return YES;
}
私は自分のコードを見ていない数ヶ月後に私が必要ではなかったいくつかの要件のために私が次の方法を実行することを忘れていた問題に遭遇しました
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath{
return NO;
}
行を選択させるためには、行に対してYESを返すべきです。
キーボードを消してdidSelectRowAtIndexPath:
が呼び出されないようにするために、テーブルビューにUITapGestureRecognizer
を付けました。誰かに役立つことを願っています。
私は同じ問題を抱えていました、
その理由はUITapGestureRecognizer
の使用でした。他の場所をタップするとキーボードが消えるようにしたかったのです。私はこれがすべてのタップアクションをオーバーライドすることに気付きました、それがdidSelectRowAtIndexPath
関数が呼び出されなかった理由です。
UITapGestureRecognizer
に関連する行をコメントすると、うまくいきます。さらに、タップされたものがUITableViewCell
であるかどうかUITapGestureRecognizer selector
の機能をチェックインすることができます。
あなたが私と同じ問題を抱えている場合:どうやら、このメソッドはあなたのtableViewが編集モードになっている場合は呼び出されません。 permitSelectionDuringEditingをtrueに設定する必要があります。
この質問を介して: 編集時に、 `UITableView`はdidSelectRowAtIndexPath ??を呼び出さない
次のようにviewDidLoadメソッドでデータソースとデリゲートを設定することを忘れないでください。
[self.tableView setDelegate:self];
[self.tableView setDataSource:self];
別の答えが受け入れられたとしても、私はこの問題を観察する人々のためのもう一つの可能な問題と解決策を追加するつもりです:
自動参照カウント(ARC)をオンにしている場合は、ビューの委任先としてコントローラーを割り当てた後でも、ARCがコントローラーを削除しているためにビューのメッセージがコントローラーに届いていないことがあります。明らかに、UITableViewのデリゲートポインタはARCの参照としてカウントされないため、それが唯一の参照である場合、コントローラは割り当て解除されます。コントローラにdeallocメソッドを実装し、そこでブレークポイントまたはNSLog呼び出しを設定することによって、これが発生しているかどうかを確認できます。
解決策は、もう必要ないと確信できるまで、他の場所で強力な参照を使用してコントローラを追跡することです。
私の問題は上記のどれでもありませんでした。そしてそれで足りない。しかし、私はそれが誰かに役立つ場合のためにここにそれをリストすると思いました。
私は私の "ベース"コントローラであるtableViewController
を持っていて、それからこのコントローラのサブクラスを作ります。私はすべてのコードを "base"クラスのtableView:didSelectRowAtIndexPath
ルーチンに書いていました。デフォルトでこのルーチンが(何もしないコードがないにもかかわらず)私のすべてのサブクラスでも作成されたことを完全に忘れています。だから私が自分のアプリを実行したとき、それはコードのサブクラスバージョンを実行し、何もしなかった、そして私を悲しませた。だから、もちろん、一度サブクラスからルーチンを削除したら、それはmt "base"クラスのルーチンを使用していて、私は仕事をしている。
知っている。笑わないで。しかし、多分これは私が失った時間を誰かに節約するでしょう...
これに私の2セントを与えます。
カスタムのUITableViewCellを使用していて、セル全体をカバーするボタンがあったので、タッチが発生したときにはボタンは選択され、セルは選択されませんでした。
ボタンを削除するか、私の場合はボタンのUser Interation Enableをfalseに設定します。これでセルが選択されたことになります。
これを読んでも、それでも問題は解決しません。
カスタムセルがあります。チェックボックス "ser Interaction Enabled"は無効になっています。だから、私はそれをスイッチを入れるだけです。がんばろう。
私はこれを持っていただけで、私がメソッドを追加しようとするときにオートコンプリートに注意を払わず、実際にはtableView:didDeselectRowAtIndexPath
の代わりにtableView:didSelectRowAtIndexPath:
:を実装することになったためです。
私は古いことを知っていて問題は解決されましたが、同様の問題がありました。問題は私のカスタムUITableViewCellにあると思いました、しかし解決策は全く違っていました。ほとんどWindowsのように:)
テーブルビューが編集モード([tableView setEditing:YES animated:NO];
など)になっている場合は、tableView.allowsSelectionDuringEditing = YES;
を設定する必要があります。
tableView:didSelectRowAtIndexPath
ではなくtableView:didDeSelectRowAtIndexPath
を実装したことを確認してください
これは私に数回以上の機会に得られます!
私の場合、解決策は以下の関数でNOをYESに変更することでした。
iOS 9以降
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
これらの答えのどれも私のために働きませんでした。約1時間後、私は非常に卑劣なことを考え出しました。
別のテーブルビューのセル内にテーブルビューがあります。私は、とりわけ、内側のテーブルビューを含む包含ビューを作成することにしました。このビューをcontentViewと呼び、xibにフックしました。
UITableViewCellにはすでにcontentViewがあり、それを使って奇妙なことをしていることがわかりました。プロパティの名前をmainContentViewに変更し、この名前を変更したプロパティにビューを再接続すると、問題は自動的に解決しました。
私の場合は、ロード時にTableView
のSuperView
の高さを動的に計算します。計算の誤りにより、TableView
はSuperView
の外側に位置していました。 TableView
は正しく描画されましたが、すべての対話が無効になりました(そしてdidSelectRowAtIndexPath
は呼び出されませんでした)。 TableView
が「アクセス可能」ではないことを視覚的に示すものがないため、検出が非常に困難です。
あなたがしたかもしれないもう一つの間違い(私がしたように):あなたがセルにセグエを設定した場合、didSelectRowAtIndexPath
は呼ばれません。代わりにビューコントローラで自分のセグエを設定する必要があります。
この記事にはいくつかの素晴らしい手がかりと答えがあります(おそらく私がこれまでに見た中で最高の議論の1つです!)ここで手がかりが私の問題を突き止めるのに役立ちました。他の記事と似ていた問題。しかし、私がそれを発見した方法は少し異なっていたので、他の人がそれに遭遇した場合に備えて共有したいと思いました。
私の問題は、コードでは、スーパークラスが非表示ではなく透明なフルスクリーンの「エラービュー」を追加していたことです。しかし、それはテーブルビューの上にあり、 "user action"がYESに設定されているので、それはテーブルビューに対する私のタッチを傍受していました。
私はXcodeのかっこいい「Debug View Hierarchy」ボタンを使ってこれを診断しました。これは私がしたこと、そしてどうやって問題を診断したのかを説明する注釈付きのスクリーンショットです。
コードでは、私は単にしなければならなかった:
errorMessageView.setUserInteractionEnabled = NO;
// or
errorMessageView.hidden = YES;
さて、私がこの問題に遭遇した時にここで更新しました、そして私の問題はここで発見されたものとわずかに異なっていました。
私はIBを見て、自分のデリゲートが設定されているのを見ましたが、それはファイルの所有者ではなくVIEWに間違って設定されていました。
誰かに役立つことを願っています
ストーリーボードのUITableView
プロパティに注意してください。私の場合は、didSelectRowAtIndexPath
メソッドを実行できないストーリーボードのコンボボックスを "Selection:Single Selection"として選択していました。
カスタムセルがある場合は、そのセルのXibで(またはコードで)UserInteractionEnabledを設定することを忘れないでください。
私の場合は、この問題を抱えているセルは1つだけでした。セルに読み取り専用モードのUITextViewアウトレットが含まれていました。タップする前に読み取り専用でしたが。タップすると、キーボードが上がりました。それはまだ相互作用を無効にする必要があることがわかった。
cell.content.scrollEnabled = NO;
cell.content.editable = NO;
cell.content.userInteractionEnabled = NO;
cell.content.delegate = nil;
[cell.content resignFirstResponder];
クリックしているセルが強調表示されていても関数がまだ呼び出されていない場合は、関数のシグネチャをもう一度確認してください。これは次のようになります。
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
これはおそらく私の場合だけでしたが、私はいくつかのファイルをバックアップから再ロードしていて、これを含むものがうまくいっていませんでした。フルクリーン(プロダクト>クリーンまたはShift + Command + K)を実行した後にそれは働いた。おそらく、プリコンパイル済みヘッダーで何かがおかしくなっているのでしょう。たぶんそれはあなたにとって問題ではないです、しかしそれは一撃の価値があります。
あなたのviewController
が以下のメソッドを持っているか確認してください。
- (BOOL) tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
"NO"を返した場合、didSelectRowは呼び出されません。
私の場合、問題は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
}
-heightForRowAtIndexPathが0を返さないかどうかを確認してください。
私は断続的にこの問題を抱えていました。セルに触れると選択されることがあります。時々それはtouchイベントを受け取らないでしょう。
私は、ios 8で導入された自己サイズ調整セルと呼ばれる機能を使用しています。私はこれに遭遇しました ブログ記事 それはそれを指摘しています:
テーブルビューが最初に表示されたとき、セルのサイズが正しくないことがあります。ただし、テーブルビューをスクロールすると、新しいセルは正しい行の高さで表示されます。この問題を回避するには、ビューが表示された後に強制的にリロードを実行します。
override func viewDidAppear(animated: Bool) {
tableView.reloadData()
}
これで問題は解決しました。テーブルビューが正しくレンダリングされていても、タッチ処理(特にUITableViewのhitTest)が上記のバグの影響を受けているようでした。
私はちょうどこの問題を抱えていましたが、それはすぐには起こりませんでした。いくつかのセルを選択した後、彼らはdidSelectItemAtIndexPath
の呼び出しを停止します。問題は、コレクションビューのallowsMultipleSelection
がTRUEに設定されていることです。セルの選択が解除されることはなかったため、これ以降の呼び出しでdidSelectItemAtIndexPath
を呼び出すことはできませんでした。
もう一つの狂った可能性:私はiPhone 5Sで私のアプリを実行していました、そして私は使用しました:
- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
私はいつも過去にやったように。
しかし、私は私のコンパイラの警告を十分に詳しく見ていなかった...それは私が上記の行を次のように変えるべきだと言った:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
64ビット互換! 拳を振る
あなたがあなたの髪を引き抜き始める場合に備えて見張りをしてください。
私はいくつかのカスタマイズされたテーブルコードに埋め込まれたcell.userInteractionEnabledへの呼び出しがありました。
愚かな、それでもほとんどのバグではありませんか?
私は前の答えをすべて繰り返しましたが、どれも助けにはなりませんでした。少し試行錯誤した後、私は別の解決策を見つけました。セル全体をカバーするUIImageViewを(背景として)持っていました。デフォルトでは、UIImageViewはユーザインタラクションを無効にしています。 imageviewsのユーザーインタラクションデリゲートメソッドを有効にすることで、-didSelectRowAtIndexPath:が再度呼び出されました。例えば。
cell.imgView.userInteractionEnabled = YES;
私は自分でこの問題を抱えていました。私はビューの骨をIBで構築しただけで(ビューとテーブルビューだけ)、デリゲートは設定されませんでした。私はそれをFile's Ownerに接続しました、そしてそれは魅力のように働きました。 ::保存する::
もう1つの考えられる原因は、UITableView
がUIScrollView
に埋め込まれていることです。誤って通常のビューではなくスクロールビューをコントローラのルートビューとして使用していたため、今日この問題が発生しました。
私はコメントできません、ここに書いてください。私の場合はdidSelectRow
は機能しましたが、didDeselectRow
は機能しませんでした。 delegate
にdataSource
とtableView
を設定し、これで私のケースは解決しました。
私の場合、問題はメソッドをプライベートとして宣言することでした。
これはうまくいきませんでした。
private func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
これはうまくいった:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
必ずメインスレッドでreloadData
を呼び出してください。ある種の非同期メソッド(たとえば、ある種のネットワーク要求)からそのメソッドを呼び出している場合、Table Viewは正しく応答したり応答しなかったりします(場合によっては、アプリケーションがクラッシュすることさえあります)。
呼び出しが他のメソッドブロックで行われている場合(念のためわからない場合)、メインスレッドコードブロックを使用してreloadData
呼び出しを実行します。
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[tableView reloadData];
}];
私はdidSelect
メソッドをnot取得する別の方法を見つけました。ある時点で、おそらくfunc宣言自体のエラー中に、XCodeは@nonobjcを自分のメソッドに追加することを提案しました。
@nonobjc func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
これは文句なしにコンパイルを続けますが、あなたはuiアクションによって呼び出されることは決してないでしょう。
「それは私の2セントです。私は自分の変化を取り戻したいのです」
@interface ExampleViewController () <UITableViewDelegate, UITableViewDataSource>
を追加
ストーリーボードで代表団を作る
コードを追加
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellText = cell.textLabel.text;
}
UITapGestureRecognizerを確認してください。私の場合、tableviewが配置されたビューにtapgestureが追加されました。これは、didselectのようなUITableviewのユーザーインタラクションを食べています。ビューのタップジェスチャを無効にした後、didselectデリゲートがトリガーされました。
私はすべての答えを読み、そしてそれらに強く同意します。しかし、私の場合はまったく違います。私は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)
}
この解決法が誰かに役立つことを願っています!
この選択は単一選択であり、編集中は編集を選択できないようにし、テーブルビューで編集する場合はuttableviewcellプロパティの設定を変更します。識別子はRidで、セクションはnoneです。
誰かがこの答えを見るのに十分遠くまでスクロールしたかどうかはわかりませんが、これはこの問題に関する最も一般的な質問であり、答えはそこにはありませんでしたので追加します。
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 }
}
ブレークポイントを適用した後に行を選択しても制御ができないという問題がありました。問題は視野に入っていた。タブジェスチャを表示から削除しました。それからそれはうまく働いた
私の場合、ちょっとしたミスをしたのですが、
tableView.isUserInteractionEnabled = false
そのはず:
tableView.isUserInteractionEnabled = true