Ios UITableViewCell如何与其UITableView通信?

Ios UITableViewCell如何与其UITableView通信?,ios,uitableview,tableview,delegation,Ios,Uitableview,Tableview,Delegation,我目前正在创建一个自定义网格视图,这意味着我正在创建一个与UITableView有很多共同点的类。我想做的一件事是单元和网格视图的通信 因此,我想知道表视图单元格如何与其表视图对话。例如,单元格如何通知表视图其删除按钮已点击,并且需要从表视图中删除单元格 有几种可能的情况,但我不确定苹果正在使用哪种情况,因为UITableView或UITableViewCell的标题揭示了这一点(或者我忽略了什么) 最终,目标是让计算单元和网格视图私下通信,也就是说,不公开任何公共方法或协议(如果可能的话)。U

我目前正在创建一个自定义网格视图,这意味着我正在创建一个与
UITableView
有很多共同点的类。我想做的一件事是单元和网格视图的通信

因此,我想知道表视图单元格如何与其表视图对话。例如,单元格如何通知表视图其删除按钮已点击,并且需要从表视图中删除单元格

有几种可能的情况,但我不确定苹果正在使用哪种情况,因为
UITableView
UITableViewCell
的标题揭示了这一点(或者我忽略了什么)


最终,目标是让计算单元和网格视图私下通信,也就是说,不公开任何公共方法或协议(如果可能的话)。

UITableViewCell
项是
UITableView
的子视图。因此,您可以使用它在单元格和tableView之间进行通信。反过来,
UITableView
让委托和数据源与其控制器通信。这可能会有所帮助。

我不确定是否需要专用通信通道

“表视图”通过调整“表视图”单元的大小并在开放空间中创建新视图,在给定单元附近强制使用“删除”视图

强制删除视图使用表视图、索引路径和表视图委托进行实例化。delete视图处理触摸并向table view委托发送一条消息,包括table view和index path。“表视图”代理执行从数据源中删除条目、设置单元格删除动画和刷新表视图的工作。刷新后,表格视图将根据数据源重新绘制所有可见单元格。

您可以使用

在单独的类别中声明私有方法,并将其放置到单独的文件中。在要使用这些私有方法的类的实现文件中,可以使用私有类别导入此文件,并使用私有方法。因此使用它们的类的public.h保持不变

例如:

MyGridViewCell.h:

@interface MyGridViewCell : UIView
// ...
@end
MyGridViewCell.m:

@implementation MyGridViewCell : UIView
// ...
@end
现在,私有方法类别界面:

MyGridViewCellPrivate.h:

@interface MyGridViewCell (Private)

- (void) privateMethod1;

@end
和执行:

MyGridViewCellPrivate.m:

@implementation MyGridViewCell (Private)

- (void) privateMethod1
{
    // ...
}

@end
标题与之前相同:

MyGridView.h:

@interface MyGridView : UIView

- (void) publicMethod1;

@end
但实现可以使用私有API:

MyGridView.m:

#import "MyGridViewCell.h"
#import "MyGridViewCellPrivate.h"

- (void) publicMethod1
{
    // Use privateMethod1
}

您可以让自定义单元视图具有网格视图类型的私有属性。将这些单元格添加到GridView时,请将该属性更新到GridView

我有我的自定义网格,并这样做


另一种方法是在网格中使用一个方法来传递单元格,然后返回索引。UITableView也有这些方法。这样,当按下单元格中的按钮时,您所要做的就是获取单元格并将其传递给网格,网格将返回索引。使用该索引,您可以访问数据…

现在,删除按钮可能是一个糟糕的示例,因为iOS有一个内置方法,允许您删除行并通知数据源,该方法称为:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
但是,为了理解,如果要向tableview单元格中添加按钮并让其执行标准iOS库中没有的操作,则需要在单元格中创建一个委托,并将tableview的数据源文件设置为委托

基本上,您可以像这样将UITableViewCell子类化

MyCustomCell.h

@protocol MyCustomCellDelegate;
@interface MyCustomCell : UITableViewCell
@property (nonatomic, unsafe_unretained) id <MyCustomCellDelegate> delegate; //Holds a reference to our tableView class so we can call to it. 
@property (nonatomic, retain) NSIndexPath *indexPath; //Holds the indexPath of the cell so we know what cell had their delete button pressed
@end

/* Every class that has <MyCustomCellDelegate> in their .h must have these methods in them */
@protocol MyCustomCellDelegate <NSObject>
- (void)didTapDeleteButton:(MyCustomCell *)cell;
@end
TableView的数据源如下所示

MyDataSource.h

/* We conform to the delegate. Which basically means "Hey you know those methods that we defined in that @protocol I've got them and you can safely call to them" */
@interface MyDataSource : UIViewController <MyCustomCellDelegate, UITableViewDelegate, UITableViewDataSource>
 @property (nonatomic,retain) NSArray *tableData;//We will pretend this is the table data
 @property (nonatomic,retain) UITableView *tableView;// We will pretend this is the tableview

@end

基本上,长话短说。对于gridview,您只需创建一个委托方法,告诉用户某个按钮被按下

谢谢你的回答。从UITableViewCell到UITableView的引用不是真正的问题。我的问题涉及单元格和表视图之间的通信,以及如何保持这种通信的私密性。我的观点是,控制器将决定如何处理按钮点击。因此它可能是
[[(UITableView*)self.superview委托]执行选择器:@selector(someButtonPressedInCell:)with object:self]
KKGridView(在GitHub:)是一个与UITableView有许多相似之处的经典实现,也是一组复杂的内部方法,您可以从中获得灵感。AQGridView()也是基于UITableView结构的实现。但据我所知,两个对象之间的通信不可能保持私有(我可能错了!)。您能更详细地解释一下这种方法吗?
/* We conform to the delegate. Which basically means "Hey you know those methods that we defined in that @protocol I've got them and you can safely call to them" */
@interface MyDataSource : UIViewController <MyCustomCellDelegate, UITableViewDelegate, UITableViewDataSource>
 @property (nonatomic,retain) NSArray *tableData;//We will pretend this is the table data
 @property (nonatomic,retain) UITableView *tableView;// We will pretend this is the tableview

@end
//We will pretend we synthesized and initialized the properties
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier: @"MyCustomCell"];
    if (!cell) 
        cell = [[DownloadQueueCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: @"MyCustomCell"];
    cell.delegate = self;      // Make sure we set the cell delegate property to this file so that it calls to this file when the button is pressed.
    cell.indexPath = indexPath;// Set the indexPath for later use so we know what row had it's button pressed.
    return cell;
}


- (void)didTapDeleteButton:(MyCustomCell *)cell;
{

   // From here we would likely call to the apple API to Delete a row cleanly and animated
   // However, since this example is ignoring the fact that they exist
   // We will remove the object from the tableData array and reload the data
   [self.tableData removeObjectAtIndexPath:cell.indexPath];
   [self.tableView reloadData];

}