スーパービューのビューコントローラーへの参照を取得する方法はありますか?過去数か月の間にこれが必要になった例がいくつかありましたが、その方法がわかりませんでした。つまり、カスタムセルにカスタムボタンがあり、現在のセルを制御するテーブルビューコントローラーの参照を取得したい場合、そのためのコードスニペットはありますか?それとも、より良いデザインパターンを使用して解決する必要があるのでしょうか。
ありがとう!
スーパービューのビューコントローラーへの参照を取得する方法はありますか?過去数か月の間にこれが必要になった例がいくつかありましたが、その方法がわかりませんでした。つまり、カスタムセルにカスタムボタンがあり、現在のセルを制御するテーブルビューコントローラーの参照を取得したい場合、そのためのコードスニペットはありますか?それとも、より良いデザインパターンを使用して解決する必要があるのでしょうか。
ありがとう!
ボタンは、できればそのスーパービュービューコントローラについて知らないようにする必要があります。
ただし、ボタンが実際に詳細を知らないオブジェクトにメッセージを送信する必要がある場合は、委任を使用して、必要なメッセージをボタンの委任に送信できます。
MyButtonDelegateプロトコルを作成し、そのプロトコルに準拠するすべての人が実装する必要のあるメソッド(コールバック)を定義します。オプションのメソッドを使用することもできます。
次に、ボタンにプロパティを追加し@property (weak) id<MyButtonDelegate>
て、プロトコルに準拠している限り、あらゆる種類のクラスをデリゲートとして設定できるようにします。
これで、View ControllerはMyButtonDelegateプロトコルを実装し、それ自体をデリゲートとして設定できます。ビューコントローラに関する知識を必要とするコードの部分は、デリゲートメソッド(または複数のメソッド)で実装する必要があります。
これで、ビューはプロトコルメッセージをデリゲートに送信でき(誰が何であるかを知らなくても)、デリゲートはそのボタンに適切なものに送信できます。このように、使用場所に依存しないため、同じボタンを再利用できます。
私が考えていたこの質問をしたとき、ボタンが付いたカスタムセルがある状況で、TableViewControllerはどのセルのボタンがタップされたかをどのように知ることができますか。最近、「iOSレシピ」という本を読んで、私は解決策を得ました:
-(IBAction)cellButtonTapped:(id)sender
{
NSLog(@"%s", __FUNCTION__);
UIButton *button = sender;
//Convert the tapped point to the tableView coordinate system
CGPoint correctedPoint = [button convertPoint:button.bounds.origin toView:self.tableView];
//Get the cell at that point
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:correctedPoint];
NSLog(@"Button tapped in row %d", indexPath.row);
}
もう1つの解決策は、もう少し壊れやすい(単純ですが)次のとおりです。
- (IBAction)cellButtonTapped:(id)sender
{
// Go get the enclosing cell manually
UITableViewCell *parentCell = [[sender superview] superview];
NSIndexPath *pathForButton = [self.tableView indexPathForCell:parentCell];
}
そして、最も再利用可能な方法は、このメソッドをUITableViewのカテゴリに追加することです。
- (NSIndexPath *)prp_indexPathForRowContainingView:(UIView *)view
{
CGPoint correctedPoint = [view convertPoint:view.bounds.origin toView:self];
return [self indexPathForRowAtPoint:correctedPoint];
}
次に、UITableViewControllerクラスで、次を使用します。
- (IBAction)cellButtonTapped:(id)sender
{
NSIndexPath *pathForButton = [self.tableView indexPathForRowContainingView:sender];
}
ビューコントローラのスーパービューがどのクラスであるかがわかっている場合は、サブビュー配列を繰り返し処理して、スーパークラスのタイプチェックを行うことができます。
例えば。
UIView *view;
for(tempView in self.subviews) {
if([tempView isKindOfClass:[SuperViewController class] ])
{
// you got the reference, do waht you want
}
}