¿Cómo pasar datos a la vista de detalles después de haberlos seleccionado en una vista de tabla?

Tengo un UITableViewController que tiene datos rellenos de un NSMutableArray llamado userList. Cuando se selecciona un usuario específico, va a una vista de detalle y actualiza el título en el NavBar, pero no pasará los datos para actualizar un UILabel en UIView.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:NO]; //Attempt at a singleton to pass the data DetailView *details = [[DetailView alloc] init]; details.userNameLbl = [userList objectAtIndex:indexPath.row]; DetailView *detailVC = [[DetailView alloc] initWithNibName:nil bundle:nil]; //This line doesn't pass the data detailVC.userNameLbl.text = [userList objectAtIndex:indexPath.row]; //This line does update the title in the NavBar detailVC.navigationItem.title = [userList objectAtIndex:indexPath.row]; [self.navigationController pushViewController:detailVC animated:YES]; [details release]; [detailVC release]; } 

¿Debo intentar empujar los datos desde la vista de la tabla a la vista de detalle, o hacer que la vista de detalles intente extraer los datos de la vista de la tabla?

DetailView.h tiene la siguiente línea que, de hecho, está conectada en IB.

 IBOutlet UILabel *userNameLbl 

El userNamelbl no se instancia hasta que la vista se cargue desde el file nib. Esto no ocurre inmediatamente en la initialization, pero habrá sucedido en el momento en que se llama a viewDidLoad .

Por lo tanto, debe declarar una propiedad en DetailView para almacenar su título y luego asignar ese valor a userNamelbl.text en el método viewDidLoad .

Por ejemplo, en su tabla viewController:

 DetailView *detailVC = [[DetailView alloc] initWithNibName:nil bundle:nil]; detailVC.userName = [userList objectAtIndex: indexPath.row]; 

y en su detalle viewController:

 - (void) viewDidLoad { [super viewDidLoad]; self.userNameLbl.text = self.userName; } 

La propiedad navigationItem viewController se crea cuando se inicializa viewController, por lo que puede asignar inmediatamente a navigationItem.title .


Código SWIFT

 let detailVC = DetailView(nibName: nil, bundle: nil) detailVC.userName = userList.objectAtIndex(indexPath.row) as? NSString 

y

 class DetailView: UIViewController { @IBOutlet var userNameLbl: UILabel var userName:NSString? override func viewDidLoad() { super.viewDidLoad() self.userNameLbl.text = self.userName } } 

¿Estás mezclando UIViews y UIViewControllers ? Debería tener una class DetailViewController que henetworkinga de UIViewController o alguna sublca (como UITableViewController ); DetailViewController.h files DetailViewController.m y DetailViewController.h para declarar y definir su class. Debería tener una punta correspondiente que defina la UIView que carga UIViewController ; Tendrá un file DetailView.xib .

No puede asignar el valor a la UILabel directamente porque UIView no se ha cargado en el momento en que necesita asignar el valor del nombre de usuario.

Para hacer lo que desea, debe declarar una propiedad pública ( userName ) para "empujar" el valor en el controller de vista detallada desde el controller maestro. Una vez que se carga la vista de detalle, puede asignar el valor de la propiedad a la label y a la barra de navigation.

En su controller de vista maestra ( UITableViewController ):

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:NO]; DetailViewController *detailVC = [[DetailView alloc] initWithNibName:@"DetailView" bundle:nil]; detailVC.userName = [userList objectAtIndex:indexPath.row]; [self.navigationController pushViewController:detailVC animated:YES]; [detailVC release]; } 

En su controller de vista de detalle:

DetailViewController.h

 @property (retain) NSString* userName; @property (nonatomic, retain) IBOutlet UILabel *userNameLbl; 

DetailViewController.m

 @synthesize userName; @synthesize userNameLbl; -(void) viewDidLoad { [super viewDidLoad]; self.userNameLbl.text = self.userName; self.navigationItem.title = self.userName; } 

Es de suponer que su DetailView requiere que los datos de su fila seleccionada funcionen.

Si es así, diría que el enfoque "correcto" sería crear un método de init personalizado que pasó en los datos que requería. Por ejemplo:

 [[DetailView alloc] initWithTitle:(NSString *)title text:(NSString *)text] 

No hay nada inherentemente malo en su enfoque, pero pasar los datos que el controller de vista requiere en su creación es arquitectónicamente mejor (en mi opinión, ¡estoy seguro de que alguien no estará de acuerdo!). Por ejemplo, piense en un controller de vista de tabla: pasa el estilo de vista de tabla en el método init , no lo configura más adelante. Lo mismo para un UIImageView : tiene un método initWithImage que le permite configurar la image en la creación.