Cómo llamar a heightForRowAtIndexPath desde una función

Estoy tratando de lograr el siguiente efecto:

  1. User taps once on cell
  2. Cell expands if contracted, or contracts if expanded.

So far I have a working function that listens for single taps:

- (void)handleSingleTap:(UITapGestureRecognizer *)gestureRecognizer {
    CGPoint p = [gestureRecognizer locationInView:self.tableView];

    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p];
    if(indexPath != nil) {
        [self.tableView beginUpdates];
        *Call heightForRowAtIndexPath here?*
        [self.tableView endUpdates];
    }
}

Y mi heightForRowAtIndexPath:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"runs");
    return 64;
}

As far as I've been able to figure out with help from different sites online, I have to call the function somehow between the [self.tableView beginUpdates] y [self.tableView endUpdates]. But how do I do this? I'm not that familiar with Xcode or Objective C, so a good explanation would be appreciated!

Gracias de antemano.

Alejandro.

preguntado el 12 de febrero de 14 a las 07:02

2 Respuestas

Tu no llamas tableView:heightForRowAtIndexPath: yourself. The tableView will call it. The tableView will call the method after you have send endUpdates to it. You have to return a different value from tableView:heightForRowAtIndexPath: después de handleSingleTap: fue llamado.

You can do this by saving the expanded indexPath in a property (or instance variable), and returning a different value in tableView:heightForRowAtIndexPath: if the requested indexPath matches the saved expanded indexPath.

p.ej

@property (strong, nonatomic) NSIndexPath *expandedIndexPath;

- (void)handleSingleTap:(UITapGestureRecognizer *)gestureRecognizer {
    CGPoint p = [gestureRecognizer locationInView:self.tableView];

    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p];
    if(indexPath != nil) {
        self.expandedIndexPath = indexPath;
        [self.tableView beginUpdates];
        [self.tableView endUpdates];
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"runs");
    if (self.expandedIndexPath && [indexPath isEqual:self.expandedIndexPath]) {
        // expanded cell
        return 200;
    }
    else {
        return 64;
}

Respondido 12 Feb 14, 07:02

Thanks for the extremely quick response Matthias! (I don't know if this is a problem, but): When I launch the app, "runs" gets printed to the console 4 times. I would like this function to be called ONLY at a single tap. In addition, there are other places where I use the beginUpdates y endUpdates too, for example for deleting and rearranging cells. Is it gonna be a problem? Is this a good solution? Are there better solutions? Again, thanks :) - Aleksander

tableView:heightForRowAtIndexPath: IS called for every cell in your tableView, that's how tableViews work. That is not a problem, it's expected behavior. Remove the log. - Matías Bauch

Si llamas [self.tableView reloadRowsAtIndexPaths:@[yourIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; then hight for row will be called appropriately.
If you call the method above, then no need for [self.tableView beginUpdate], [self.tableView endUpdate]

Respondido 12 Feb 14, 07:02

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.