8

我目前正在创建一个自定义网格视图,这意味着我正在创建一个与UITableView. 我想要做的一件事是单元格和网格视图的通信。

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

有几种可能的情况,但我不确定苹果正在使用哪一种,因为标题UITableViewUITableViewCell揭示了这一点(或者我是否忽略了某些东西)。

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

4

5 回答 5

1

现在删除按钮可能是一个糟糕的例子,因为 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

MyCustomCell.m

@synthesize delegate = _delegate;
@synthesize indexPath = _indexPath;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) 
    {
    /* Create a button and make it call to a method in THIS class called deleteButtonTapped */
    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    button.frame = CGRectMake(5, 5, 25, 25);
    [button addTarget:self action:@selector(deleteButtonTapped:) forControlEvents:UIControlEventTouchUpInside];

    }
    return self;
}

/**
 * This is the method that is called when the button is clicked.
 * All it does is call to the delegate. (Whatever class we assigned to the 'delegate' property)
 */
- (void)deleteButtonTapped:(id)sender
{
    [self.delegate didTapDeleteButton:self];
}

您的 TableView 的数据源看起来像这样。

我的数据源.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

我的数据源.m

//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];

}

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

于 2012-06-12T06:13:31.327 回答
0

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

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

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

于 2012-06-12T00:41:05.110 回答
0

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

于 2012-05-30T10:58:17.397 回答
0

您可以使用类别

您在单独的类别中声明您的私有方法,并将其放置在单独的文件中。在要使用这些私有方法的类的实现文件中,以私有类别导入该文件,并使用私有方法。因此,使用它们的类的 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
}
于 2012-06-11T09:08:28.790 回答
0

我不确定是否需要私人沟通渠道。

表格视图通过调整表格视图单元格的大小并在开放空间中创建新视图来强制删除与给定单元格相邻的视图。

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

于 2012-06-05T12:33:59.383 回答