如何从单元格的单元格中调用父视图控制器中的方法?

时间:2021-11-01 11:57:08

The structure of my app currently looks like this: Collection View Controller -> Generic Cell with table view inside of it -> individual cells.

我的应用程序的结构目前看起来像这样:集合视图控制器 - >通用单元格,其中包含表视图 - >单个单元格。

I would like to call a method in the collection view controller from one of the individual cells. So far I have implemented a delegate in the individual cell but if I can't seem to set my delegate in the collection view controller because I don't have an instance of it.

我想从一个单独的单元格中调用集合视图控制器中的方法。到目前为止,我已经在单个单元格中实现了委托,但是如果我似乎无法在集合视图控制器中设置我的委托,因为我没有它的实例。

Furthermore, I have several cells inside the table view that are required to access the methods in the collection view controller.

此外,我在表视图中有几个单元格,这些单元格是访问集合视图控制器中的方法所必需的。

2 个解决方案

#1


1  

The responder chain can help.

响应者链可以提供帮助。

The view can query the responder chain for the first target that can accept a message. Suppose the message is -fooBar, then the view can query the target using the method -[UIResponder targetForAction:sender:]

视图可以向响应者链查询可以接受消息的第一个目标。假设消息是-fooBar,那么视图可以使用方法查询目标 - [UIResponder targetForAction:sender:]

// find the first responder in the hierarchy that will respond to -fooBar
id target = [self targetForAction:@selector(fooBar) sender:self];

// message that target
[target fooBar];

Note that this communication is controlled by this method:

请注意,此通信由此方法控制:

(BOOL)canPerformAction:(SEL)action 
            withSender:(id)sender;

This default implementation of this method returns YES if the responder class implements the requested action and calls the next responder if it does not.

如果响应者类实现所请求的操作,则此方法的此默认实现返回YES,如果不执行,则调用下一个响应者。

By default, the first object that responds to that message will become the target so you may want to override the canPerformAction:withSender: if needed for some views or view controllers.

默认情况下,响应该消息的第一个对象将成为目标,因此您可能希望覆盖canPerformAction:withSender:如果需要某些视图或视图控制器。

#2


0  

For that you can do like that :

为此你可以这样做:

In Collection View Controller -> .h file

在集合视图控制器 - > .h文件中

@interface CollectionViewController : UICollectionViewController<ColectionCellDelegate>

@end

In Collection View Controller -> .m file

在集合视图控制器 - > .m文件中

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return [self.collectionData count];
}

// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    CollectionCell *cell = (CollectionCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"CollectionCell" forIndexPath:indexPath];
    cell.cellData = [self.collectionData objectAtIndex:indexPath.row];
    cell.delegate = self;
    return cell;
}

-(void)tableCellDidSelect:(UITableViewCell *)cell{
    NSLog(@"Tap %@",cell.textLabel.text);
    DetailViewController *detailVC = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
    detailVC.label.text = cell.textLabel.text;
    [self.navigationController pushViewController:detailVC animated:YES];
}

In CollectionCell.h

在CollectionCell.h中

@class CollectionCell;
@protocol ColectionCellDelegate
-(void)tableCellDidSelect:(UITableViewCell *)cell;
@end

@interface CollectionCell : UICollectionViewCell<UITableViewDataSource,UITableViewDelegate>
@property(strong,nonatomic) NSMutableArray *cellData;
@property(weak,nonatomic) id<ColectionCellDelegate> delegate;
@end

In CollectionCell.m

在CollectionCell.m中

@implementation CollectionCell

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        self.cellData = [[NSMutableArray alloc] init];
    }
    return self;
}
-(void) awakeFromNib{
    [super awakeFromNib];
    self.cellData = [[NSMutableArray alloc] init];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [self.cellData count];
}

// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *CellIdentifier = @"TableCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }
    cell.textLabel.text = [self.cellData objectAtIndex:indexPath.row];

    return cell;
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    [[self delegate] tableCellDidSelect:cell];
}

#1


1  

The responder chain can help.

响应者链可以提供帮助。

The view can query the responder chain for the first target that can accept a message. Suppose the message is -fooBar, then the view can query the target using the method -[UIResponder targetForAction:sender:]

视图可以向响应者链查询可以接受消息的第一个目标。假设消息是-fooBar,那么视图可以使用方法查询目标 - [UIResponder targetForAction:sender:]

// find the first responder in the hierarchy that will respond to -fooBar
id target = [self targetForAction:@selector(fooBar) sender:self];

// message that target
[target fooBar];

Note that this communication is controlled by this method:

请注意,此通信由此方法控制:

(BOOL)canPerformAction:(SEL)action 
            withSender:(id)sender;

This default implementation of this method returns YES if the responder class implements the requested action and calls the next responder if it does not.

如果响应者类实现所请求的操作,则此方法的此默认实现返回YES,如果不执行,则调用下一个响应者。

By default, the first object that responds to that message will become the target so you may want to override the canPerformAction:withSender: if needed for some views or view controllers.

默认情况下,响应该消息的第一个对象将成为目标,因此您可能希望覆盖canPerformAction:withSender:如果需要某些视图或视图控制器。

#2


0  

For that you can do like that :

为此你可以这样做:

In Collection View Controller -> .h file

在集合视图控制器 - > .h文件中

@interface CollectionViewController : UICollectionViewController<ColectionCellDelegate>

@end

In Collection View Controller -> .m file

在集合视图控制器 - > .m文件中

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return [self.collectionData count];
}

// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    CollectionCell *cell = (CollectionCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"CollectionCell" forIndexPath:indexPath];
    cell.cellData = [self.collectionData objectAtIndex:indexPath.row];
    cell.delegate = self;
    return cell;
}

-(void)tableCellDidSelect:(UITableViewCell *)cell{
    NSLog(@"Tap %@",cell.textLabel.text);
    DetailViewController *detailVC = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
    detailVC.label.text = cell.textLabel.text;
    [self.navigationController pushViewController:detailVC animated:YES];
}

In CollectionCell.h

在CollectionCell.h中

@class CollectionCell;
@protocol ColectionCellDelegate
-(void)tableCellDidSelect:(UITableViewCell *)cell;
@end

@interface CollectionCell : UICollectionViewCell<UITableViewDataSource,UITableViewDelegate>
@property(strong,nonatomic) NSMutableArray *cellData;
@property(weak,nonatomic) id<ColectionCellDelegate> delegate;
@end

In CollectionCell.m

在CollectionCell.m中

@implementation CollectionCell

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        self.cellData = [[NSMutableArray alloc] init];
    }
    return self;
}
-(void) awakeFromNib{
    [super awakeFromNib];
    self.cellData = [[NSMutableArray alloc] init];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [self.cellData count];
}

// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *CellIdentifier = @"TableCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }
    cell.textLabel.text = [self.cellData objectAtIndex:indexPath.row];

    return cell;
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    [[self delegate] tableCellDidSelect:cell];
}