Tiene un reloadData para un UITableView animar al cambiar de

Tengo un UITableView que tiene dos modos. Cuando se cambia entre los modos tengo un diferente número de secciones y de las células por la sección. Idealmente, debería hacer algo de fresco animación cuando la tabla crece o se encoge.

Aquí está el código que he intentado, pero no hace nada:

CGContextRef context = UIGraphicsGetCurrentContext(); 
[UIView beginAnimations:nil context:context]; 
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 
[UIView setAnimationDuration:0.5]; 

[self.tableView reloadData];
[UIView commitAnimations];

Alguna idea sobre cómo podría hacer esto?

InformationsquelleAutor | 2009-01-07

15 Kommentare

  1. 395

    En realidad, es muy simple:

    [_tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];

    De la documentación:

    De llamar a este método hace que la vista de tabla para pedir su origen de datos para
    las nuevas células de las secciones especificadas. La vista de tabla anima el
    la inserción de nuevas células en la que anima a las viejas células.

    • Y simplemente la mejor respuesta en esta página!
    • Esto no es del todo correcto, porque sólo cargar la primera sección. Si la tabla tiene varias secciones, esto no va a funcionar
    • Es posible que usted obtenga una excepción si los datos no ha cambiado.. Ver a mi respuesta
    • si quieres tener más o todas las secciones de su formato tableview de recarga, todo lo que tienes que hacer es extender su NSIndexSet con toda la sección de índices, que necesita ser refrescada así
    • Por favor, puedes mostrar esto en swift?
    • Swift versión: _tableView.reloadSections(NSIndexSet(index: 0), withRowAnimation: .Fade) en particular, sin embargo, no sólo la actualización de la Sección 0, que es el predeterminado, sección primera.

  2. 243

    Puede que desee utilizar:

    Objective-C

    [UIView transitionWithView: self.tableView
                      duration: 0.35f
                       options: UIViewAnimationOptionTransitionCrossDissolve
                    animations: ^(void)
     {
          [self.tableView reloadData];
     }
                    completion: nil];

    Swift

    UIView.transitionWithView(tableView,
                              duration: 0.35,
                              options: .TransitionCrossDissolve,
                              animations:
    { () -> Void in
        self.tableView.reloadData()
    },
                              completion: nil);

    Swift 3

    UIView.transition(with: tableView,
                      duration: 0.35,
                      options: .transitionCrossDissolve,
                      animations: { self.tableView.reloadData() }) //left out the unnecessary syntax in the completion block and the optional completion parameter

    Sin problemas. 😀

    También puede utilizar cualquiera de los UIViewAnimationOptionTransitions desea para enfriador de efectos:

    • TransitionNone
    • TransitionFlipFromLeft
    • TransitionFlipFromRight
    • TransitionCurlUp
    • TransitionCurlDown
    • TransitionCrossDissolve
    • TransitionFlipFromTop
    • TransitionFlipFromBottom
    • Esto es útil si el inicio/final de su formato tableview va a ser muy diferente (y sería complejo para calcular las secciones y las filas para agregar/quitar), pero la varita algo menos chocante que la no-animación de recarga.
    • Esto no es tan agradable una animación como recargar el formato tableview utilizando el construido en los métodos, pero a diferencia de la mayor clasificación de los métodos mencionados aquí, esto funciona cuando se tienen varias secciones.
    • Wow después de probar todo el resto, este es definitivamente perfecto para mí
    • la mayor nominal respuesta de trabajar con múltiples secciones 🙂 – [_tableView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, sectionCount)] withRowAnimation:UITableViewRowAnimationFade];
    • No funciona si el estado final tiene más/menos las secciones que el estado inicial. Luego tendrías que realizar un seguimiento manual de las secciones que tengo agregados o eliminados, lo cual es bastante complicado.
    • forma sencilla y rápida para implementar el propósito general de la animación, si no hay una necesidad real para la personalización, entonces este debería ser utilizado.
    • Esta es una solución fácil! Cero Alboroto!! Para swift UIView.transitionWithView(formato tableview, duración: 0.35 opciones: .TransitionCrossDissolve, animaciones: { () -> Void en auto.formato tableview.reloadData() }, finalización: nil)
    • Gracias bro, he añadido su aplicación a la respuesta.
    • Definitivamente la mejor respuesta. La recarga de las secciones es tan molesto sobre todo cuando las secciones de recarga no son continuos o usted tiene que eliminar una sección en el centro para que la sección de los números para volver a cargar el cambio
    • A mí me funciona bien, incluso cuando no son más o menos las secciones que en el estado anterior. Muy fácil solución!
    • esto funcionó mejor que la recarga de la sección (solución)

  3. 72

    Tenga más libertad en el uso de CATransition clase.

    No se limita a la decoloración, pero que no puede hacer movimientos así..


    Por ejemplo:

    (no te olvides de importación QuartzCore)

    CATransition *transition = [CATransition animation];
    transition.type = kCATransitionPush;
    transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    transition.fillMode = kCAFillModeForwards;
    transition.duration = 0.5;
    transition.subtype = kCATransitionFromBottom;
    
    [[self.tableView layer] addAnimation:transition forKey:@"UITableViewReloadDataAnimationKey"];

    Cambiar el type para que coincidan con sus necesidades, como kCATransitionFade etc.

    Aplicación en Swift:

    let transition = CATransition()
    transition.type = kCATransitionPush
    transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    transition.fillMode = kCAFillModeForwards
    transition.duration = 0.5
    transition.subtype = kCATransitionFromTop
    self.tableView.layer.addAnimation(transition, forKey: "UITableViewReloadDataAnimationKey")
    //Update your data source here
    self.tableView.reloadData()

    De referencia para CATransition

    Swift 5:

    let transition = CATransition()
    transition.type = CATransitionType.push
    transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
    transition.fillMode = CAMediaTimingFillMode.forwards
    transition.duration = 0.5
    transition.subtype = CATransitionSubtype.fromTop
    self.tableView.layer.add(transition, forKey: "UITableViewReloadDataAnimationKey")
    //Update your data source here
    self.tableView.reloadData()
    • Mucho mejor método
    • esto anima a la tabla como un todo, en lugar de solo las filas/secciones.
    • Todavía responde a la pregunta. Una pregunta «Cómo recargar una única fila» tiene una respuesta diferente, tales como la aplicación de la animación a la layer propiedad de un UITableViewCell.
    • Me esperaba una tabla para animar los distintos filas (como se hace referencia en la pregunta), pero este método empuja a todos los de la mesa de una vez. Tal vez me estoy perdiendo algo?
    • hmm no se supone que debe hacerlo. No puede hacer sólo la mitad de la tabla como QuartzCore modifica la vista directamente. Usted puede intentar conseguir que las células de la vista de tabla y, a continuación, la aplicación de esta animación para cada a pesar de que (aunque seguro que no iba a funcionar)
    • Me pueden ayudar a implementar esta solución? ¿Puedo ejecutar este bloque de código sólo una vez a la instalación de la animación? ¿Cómo puedo activar la animación en el decir, [Mitabla ReloadData]?
    • hmm no recuerdo ahora mismo, pero prueba a poner esto en tu viewDidLoad. Cualquier posterior de la tabla de recarga debe utilizar la animación.. Si eso no funciona, trate de correr justo antes de refrescante ur de datos (por ejemplo, haga clic con el botón). Espero que esto ayude! Si te gusta el chat, correo electrónico [email protected] gracias 🙂
    • trabajó como un encanto con kCATransitionFade Gracias! 🙂
    • Excelente solución dude…..by su modo de dar una impactante animación con el formato tableview….Bueno!!!..:)

  4. 60

    Creo que usted puede simplemente actualizar su estructura de datos, entonces:

    [tableView beginUpdates];
    [tableView deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:YES];
    [tableView insertSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:YES];
    [tableView endUpdates];

    También, el «withRowAnimation» no es exactamente un valor booleano, sino un estilo de animación:

    UITableViewRowAnimationFade,
    UITableViewRowAnimationRight,
    UITableViewRowAnimationLeft,
    UITableViewRowAnimationTop,
    UITableViewRowAnimationBottom,
    UITableViewRowAnimationNone,
    UITableViewRowAnimationMiddle
    • Este fue super simple y trabajó mucho para mí
    • Excelente , Gracias por compartir este fragmento de código….
    • Cosas simples, pero tan fácil para ir directamente a StackOverflow y obtener el fragmento de código que usted necesita, de arrastre docs. . Gracias!
  5. 24

    Todas estas respuestas se supone que está utilizando un UITableView con sólo 1 sección.

    Con precisión manejar situaciones donde usted tiene más de 1 sección uso:

    NSRange range = NSMakeRange(0, myTableView.numberOfSections);
    NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:range];
    [myTableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];

    (Nota: usted debe asegurarse de que usted tiene más de 0 secciones!)

    Otra cosa a tener en cuenta es que puede ejecutar en un NSInternalInconsistencyException si intenta actualizar simultáneamente el origen de datos, con este código. Si este es el caso, puede utilizar la lógica similar a este:

    int sectionNumber = 0; //Note that your section may be different
    
    int nextIndex = [currentItems count]; //starting index of newly added items
    
    [myTableView beginUpdates];
    
    for (NSObject *item in itemsToAdd) {
        //Add the item to the data source
        [currentItems addObject:item];
    
        //Add the item to the table view
        NSIndexPath *path = [NSIndexPath indexPathForRow:nextIndex++ inSection:sectionNumber];
        [myTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:path] withRowAnimation:UITableViewRowAnimationAutomatic];
    }
    
    [myTableView endUpdates];
    • Buen punto sobre la sección de cálculos, pero yo sólo tenía una sección y el código tenía un off-by-one de error. He tenido que cambiar la primera línea de su código para NSRange rango = NSMakeRange(0, myTableView.numberOfSections);
  6. 17

    La forma de abordar esto es para indicar el formato tableview para quitar y agregar filas y secciones con el

    insertRowsAtIndexPaths:withRowAnimation:,
    deleteRowsAtIndexPaths:withRowAnimation:,
    insertSections:withRowAnimation: y
    deleteSections:withRowAnimation:

    métodos de UITableView. Cuando se llama a estos métodos, la mesa se moverá en el/los artículos que usted pidió, a continuación, llamar reloadData en sí por lo que puede actualizar el estado después de esta animación. Esta parte es importante, ya que si se animan a todo lo que es, pero no cambian los datos devueltos por la tabla del origen de datos, las filas se aparece de nuevo después de que finalice la animación.

    Así, su flujo de aplicación sería:

    [self setTableIsInSecondState:YES];

    [myTable deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:YES]];

    Tan largo como su tabla de origen de datos, métodos de devolver la correcta nuevo conjunto de secciones y filas comprobando [self tableIsInSecondState] (o lo que sea), de esta manera se logra el efecto que estás buscando.

  7. 16

    Que no puedo comentar sobre la respuesta, pero una rápida aplicación sería:

    self.tableView.reloadSections([0], with: UITableViewRowAnimation.fade)

    usted podría incluir tantas secciones como desee actualizar en el primer argumento para reloadSections.

    Otras animaciones disponibles a partir de la documentación:
    https://developer.apple.com/reference/uikit/uitableviewrowanimation

    fade
    La inserta o elimina la fila o filas que se desvanecen dentro o fuera de la vista de tabla.

    derecho
    La inserción de fila o filas de la diapositiva de la derecha; el borrado de la fila o filas de la diapositiva a la derecha.

    izquierda
    La inserción de fila o filas de la diapositiva de la izquierda; el borrado de la fila o filas de diapositivas a la izquierda.

    superior
    La inserción de fila o filas de diapositivas desde la parte superior; el borrado de la fila o filas deslice hacia la parte superior.

    inferior
    La inserción de fila o filas de diapositivas en la parte inferior; el borrado de la fila o filas deslice hacia la parte inferior.

    caso de que ninguno
    El insertar o eliminar filas utilizar el valor predeterminado animaciones.

    medio
    La tabla de la vista de los intentos de mantener las viejas y las nuevas células centrado en el espacio que hizo o va a ocupar. Disponible en iPhone 3.2.

    automático
    La vista de tabla se elige un adecuado estilo de animación para usted. (Introducido en iOS 5.0.)

    • Para Swift 4.2: auto.formato tableview.reloadSections([0], con: UITableView.RowAnimation.fade)
  8. 10

    Swift 4 versión para @dmarnel respuesta:

    tableView.reloadSections(IndexSet(integer: 0), with: .automatic)
  9. 9

    Rápida Implementación:

    let range = NSMakeRange(0, self.tableView!.numberOfSections())
    let indexSet = NSIndexSet(indexesInRange: range)
    self.tableView!.reloadSections(indexSet, withRowAnimation: UITableViewRowAnimation.Automatic)
  10. 1

    En mi caso, yo quería agregar más 10 filas en el formato tableview (para un «ver más resultados» tipo de funcionalidad), y yo hice lo siguiente:

      NSInteger tempNumber = self.numberOfRows;
      self.numberOfRows += 10;
      NSMutableArray *arrayOfIndexPaths = [[NSMutableArray alloc] init];
      for (NSInteger i = tempNumber; i < self.numberOfRows; i++) {
        [arrayOfIndexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
      }
      [self.tableView beginUpdates];
      [self.tableView insertRowsAtIndexPaths:arrayOfIndexPaths withRowAnimation:UITableViewRowAnimationTop];
      [self.tableView endUpdates];

    En la mayoría de los casos, en lugar de «auto.numberOfRows», se suele utilizar el recuento de la matriz de objetos para el formato tableview. Así que para asegurarse de que esta solución funciona bien para usted, «arrayOfIndexPaths» debe ser preciso matriz del índice de caminos de las filas que se inserta. Si la fila existe para cualquiera de este índice de rutas de acceso, el código puede fallar, por lo que debe utilizar el método de «reloadRowsAtIndexPaths:withRowAnimation:» para aquellos índice pathds para evitar estrellarse

  11. 1

    Si quieres añadir tus propias animaciones personalizadas para UITableView celdas, utilice

    [theTableView reloadData];
    [theTableView layoutSubviews];
    NSArray* visibleViews = [theTableView visibleCells];

    para obtener un conjunto de celdas visibles. A continuación, agregue cualquier animación personalizada para cada celda.

    Echa un vistazo a este gist he publicado una suave personalizado de la célula de animación.
    https://gist.github.com/floprr/1b7a58e4a18449d962bd

  12. 1

    Animación sin reloadData() en Swift puede ser hecho como este (de la versión 2.2):

    tableview.beginUpdates()
    var indexPathsToDeleteForAnimation: [NSIndexPath] = []
    var numOfCellsToRemove = ArrayOfItemsToRemove ?? 0
    
    //Do your work here
    while numOfCellsToRemove > 0 {
        //...or here, if you need to add/remove the same amount of objects to/from somewhere
        indexPathsToDeleteForAnimation.append(NSIndexPath(forRow: selectedCellIndex+numOfCellsToRemove, inSection: 0))
        numOfCellsToRemove -= 1
    }
    tableview.deleteRowsAtIndexPaths(indexPathsToDeleteForAnimation, withRowAnimation: UITableViewRowAnimation.Right)
    tableview.endUpdates()

    en caso de que usted necesita llamar a reloadData() después de que termina la animación, usted puede abrazar los cambios en CATransaction como este:

    CATransaction.begin()
    CATransaction.setCompletionBlock({() in self.tableview.reloadData() })
    tableview.beginUpdates()
    var indexPathsToDeleteForAnimation: [NSIndexPath] = []
    var numOfCellsToRemove = ArrayOfItemsToRemove.count ?? 0
    
    //Do your work here
    while numOfCellsToRemove > 0 {
         //...or here, if you need to add/remove the same amount of objects to/from somewhere
         indexPathsToDeleteForAnimation.append(NSIndexPath(forRow: selectedCellIndex+numOfCellsToRemove, inSection: 0))
         numOfCellsToRemove -= 1
    }
    tableview.deleteRowsAtIndexPaths(indexPathsToDeleteForAnimation, withRowAnimation: UITableViewRowAnimation.Right)
    tableview.endUpdates()
    CATransaction.commit()

    La lógica se muestra para el caso de que al eliminar filas, pero la misma idea funciona también para agregar filas. También puede cambiar la animación a UITableViewRowAnimation.Izquierda para hacer bonito, o elegir de la lista de otras animaciones disponibles.

  13. 1
    CATransition *animation = [CATransition animation];
    animation.duration = .3;
    [animation setType:kCATransitionPush];
    [animation setSubtype:kCATransitionFromLeft];
    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    [animation setDuration:.3];
    
    [[_elementTableView layer] addAnimation:animation forKey:@"UITableViewReloadDataAnimationKey"];
    
    [tableView reloadData];
    • ¿Por qué establecer la duración .3 dos veces?
  14. 1

    A volver a cargar todas las secciones, no solo uno con duración personalizado.

    Usuario duration parámetro de UIView.animate para establecer la duración personalizado.

    UIView.animate(withDuration: 0.4, animations: { [weak self] in
        guard let `self` = self else { return }
        let indexSet = IndexSet(integersIn: 0..<self.tableView.numberOfSections)
        self.tableView.reloadSections(indexSet, with: UITableView.RowAnimation.fade)
    })

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea