¿Cómo se comunica UITableViewCell con su UITableView?

Actualmente estoy creando una vista de cuadrícula personalizada, lo que significa que estoy creando una class que tiene mucho en común con UITableView . Una de las cosas que quiero corregir es la comunicación de las celdas y la vista de cuadrícula.

Por lo tanto, me preguntaba cómo una celda de vista de tabla habla con su vista de tabla. Por ejemplo, ¿cómo la célula notifica a la vista de tabla que se ha tocado el button de eliminar y que la celda debe eliminarse de la vista de tabla?

Hay varios escenarios posibles, pero no estoy seguro de cuál Apple está utilizando, ya que los encabezados de UITableView o UITableViewCell revelan (o estoy pasando por alto algo).

En última instancia, el objective es permitir que la celda y la vista de cuadrícula se comuniquen en privado, es decir, sin exponer ningún método o protocolo público (si esto es posible).

Ahora, un button de eliminar podría ser un mal ejemplo porque iOS tiene un método incorporado que le permite eliminar filas y notificar a su fuente de datos llamada:

 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 

Sin embargo, para comprender si desea agregar un button a su celda de tabla y hacer que realice una acción que no está en la biblioteca de iOS estándar, crearía un delegado en su celda y configuraría el file de fuente de datos de su tabla como delegado .

Básicamente, subclara UITableViewCell como para

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

El origen de datos de su TableView se vería así.

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 

MyDataSource.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]; } 

Básicamente, larga historia corta. Para su cuadrícula, simplemente crearía un método de delegado que le dice al usuario que se presionó un button determinado.

UITableViewCell elementos UITableViewCell son subviews de UITableView . Por lo que podría usarlo para comunicarse entre celdas y tableView. A su vez, UITableView tiene el delegado y la UITableView datos para comunicarse con su controller. Esto podría ayudar.

No estoy seguro de que se necesite un canal de comunicación privado.

La vista de la tabla impone una vista de eliminación adyacente a una celda determinada cambiando el tamaño de la celda de vista de la tabla y creando una nueva vista en el espacio abierto.

La vista de eliminación impuesta se ejemplifica con la vista de tabla, la ruta de índice y el delegado de vista de tabla. La vista Eliminar maneja el tacto y envía un post al delegado de la vista de la tabla que incluye la vista de la tabla y la ruta del índice. El delegado de vista de tabla realiza el trabajo de eliminar la input de la fuente de datos, animando la eliminación de la celda y actualizando la vista de la tabla. Al actualizar, la vista de tabla vuelve a dibujar todas las celdas visibles de acuerdo con la fuente de datos.

No estoy seguro de si esto es lo que estás buscando, pero echa un vistazo a esta pregunta: Extiende un protocolo de forma privada usando una categoría en el objective c

Puede hacer que sus UIViews personalizadas de celdas tengan una propiedad privada del tipo de su Vista de cuadrícula. Cuando agregue estas celdas a GridView, actualice esa propiedad a gridView.

Tengo mi cuadrícula personalizada y lo hago de esta manera.

Otra forma es tener un método en su cuadrícula para pasar una celda, y eso le devolverá el índice. UITableView también tiene esos methods. De esta manera, cuando se presiona un button en una celda, todo lo que tienes que hacer es get la celda y pasarla a la grilla, que devolverá un índice. Con ese índice, accedes a los datos …

Puede usar categorías .

Usted declara sus methods privados en una categoría separada y los coloca en el file separado. En el file de implementación de class que desea usar estos methods privados, usted importa este file con una categoría privada y usa los methods privados. Entonces, el .h público de la class que los usa se deja intacto.

Ejemplo:

MyGridViewCell.h:

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

MyGridViewCell.m:

 @implementation MyGridViewCell : UIView // ... @end 

Ahora la interfaz de categoría de methods privados:

MyGridViewCellPrivate.h:

 @interface MyGridViewCell (Private) - (void) privateMethod1; @end 

E implementación:

MyGridViewCellPrivate.m:

 @implementation MyGridViewCell (Private) - (void) privateMethod1 { // ... } @end 

Encabezado sigue siendo el mismo que antes:

MyGridView.h:

 @interface MyGridView : UIView - (void) publicMethod1; @end 

Pero la implementación puede usar la API privada:

MyGridView.m:

 #import "MyGridViewCell.h" #import "MyGridViewCellPrivate.h" - (void) publicMethod1 { // Use privateMethod1 }