2010-09-19 17 views
53

Tengo un nivel superior UIViewController que contiene un UITableView. El nivel superior UIViewController instancia un NavigationController, y empuja otro UIViewController en el NavigationController. ES DECIR. empujamos hacia una nueva y segunda vista Esta segunda vista tiene el botón "Atrás" habitual en la esquina superior izquierda para permitirle navegar de nuevo a la vista de nivel superior.¿Volver a cargar UITableView cuando navegas hacia atrás?

Es posible, al navegar de nuevo a la vista de nivel superior desde la segunda vista, volver a dibujar UITableView en la vista de nivel superior, utilizando datos generados en la segunda vista, llamando al cellForRowAtIndexPath en el nivel superior y, si es así, ¿cómo hace uno esto?

Respuesta

105

Todo lo que necesita hacer es esto (en su UIViewController que tiene una UITableView). No tiene que preocuparse por lo que sucede a nivel celular en este momento.

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 
    [self.tableView reloadData]; // to reload selected cell 
} 

Basta con añadir el código anterior para su controlador, y verá que lo correcto sucede cuando usted se vuelve de su segundo punto de vista. La llamada al reloadData le dice a la vista de tabla que necesita actualizar sus celdas de su modelo, y todo lo demás sigue muy bien.

+1

i utilizado este método, pero tuvo que mover el código de mi didViewLoad a viewWillAppear ya que donde tanto la cocción de la carga inicial. Para mí fue un problema mayor porque necesito descargar los detalles del nuevo elemento de un servicio web – PowerMan2015

5

Puede implementar los métodos de UINavigationControllerDelegate y crear la lógica para la actualización al abrir los controladores de vista.

Otra forma de hacerlo sería implementando en su controlador de vista de tabla alguna lógica en viewWillAppear, para actualizar en función de los datos del controlador de vista emergente.

Si necesita enviar datos del segundo controlador de vista al primer controlador de vista, recuerde que su segundo controlador de vista "no" sabe la existencia del controlador de vista anterior. Debería ser transparente para eso. Debe implementar algún protocolo para que el segundo controlador de vista envíe datos al primer controlador de vista. Sería una tercera opción para este problema, ya que su primer controlador de vista sería el delegado y el segundo controlador de vista estaría enviando información al delegado, podría estar preparando su vista de tabla (primer controlador de vista) para volver a cargar, en función del datos recibidos

10

Si sólo desea volver a cargar la célula que fue seleccionado, anular viewWillAppear: en su subclase personalizada de UITableViewController así:

- (void)viewWillAppear:(BOOL)animated 
{ 
    NSIndexPath *selectedRowIndexPath = [self.tableView indexPathForSelectedRow]; 
    [super viewWillAppear:animated]; // clears selection 
    if (selectedRowIndexPath) { 
     [self.tableView reloadRowsAtIndexPaths:@[selectedRowIndexPath] withRowAnimation:UITableViewRowAnimationNone]; 
    } 
} 

NOTA: Si se asume que ha dejado clearsSelectionOnViewWillAppear conjunto de YES (por defecto), debe obtener la ruta de índice de la fila seleccionada antes de llamar al super, lo que borra la selección.

Además, el solution of @ZoranSimic para simplemente llamar a [self.tablView reloadData] es aceptable ya que es menos código y sigue siendo eficiente.

Por último, tal vez la mejor manera de mantener las células de su vista tabla en sincronía con los objetos del modelo que representan es hacer como NSFetchedResultsController y el uso de la observación de clave-valor (MVA) y/o NSNotification informar a su controlador de vista de tabla cuando el modelo los objetos han cambiado para que pueda volver a cargar las celdas correspondientes. El controlador de vista de tabla podría comenzar a observar los cambios en sus objetos de modelo en viewDidLoad y terminar observando en dealloc (y en cualquier lugar que manually unload self.view).

6

Además de la answer of Zoran Simic aquí el código Swift:

override func viewWillAppear(animated: Bool) { 
    super.viewWillAppear(animated) 
    tableView.reloadData() 
} 
+0

Tenga cuidado de no obtener datos de 'viewDidLoad()' cuando quiera volver a cargar datos desde 'viewWillAppear()'. –

1

Tal vez puede ayudar ahora.

Para Swift 2+

En el método de viewDidAppear:

Si desea volver a cargar toda la tabla:

tableView.reloadData() 

Si desea volver a cargar sólo la celda seleccionada.

let index = tableView.indexPathForSelectedRow 
if (index != nil){ 
    self.tableView.reloadRowsAtIndexPaths([index], withRowAnimation: UITableViewRowAnimation.Automatic) 
} 
2

viewWillAppear es llamado cada vez que la vista parece incluir la primera vez. Aquí está mi solución para recargar la vista sólo cuando se desplaza hacia atrás

puedo crear una variable en .h file de mi ViewController para comprobar que se trata de la primera vez que voy a este ViewController o cuando navego hacia atrás

@property (nonatomic) BOOL isViewExist; 

Después de que en viewWillAppear

-(void)viewWillAppear:(BOOL)animated{ 
    if(!self.isViewExist){ 
     self.isViewExist = YES; // check it is the first time you go to this ViewController -> don't reload anything 
    }else{ 
     [self.tableView reloadData]; // to reload the tableview data 
     // or your can refresh anything in your ViewController as you want 
    } 
} 

esperanza esta ayuda

-1

Actualización de Swift 3

let index = tableView.indexPathForSelectedRow 
    if (index != nil){ 
     self.tableView.reloadRows(at: [index!], with: UITableViewRowAnimation.automatic) 
    } 
+0

_in - anula func viewDidLoad() o ??? _ - comentando en nombre del usuario que no puede comentar – Tushar

Cuestiones relacionadas