2012-02-24 18 views
12

Recientemente comencé a programar para el iPhone y estoy creando una aplicación que se conecta a una base de datos y obtiene un conjunto de nombres de fila y los muestra. Cuando se selecciona, el color de fondo de las filas cambia, es decir, puede hacer selecciones múltiples y todas serán de diferentes colores. Por lo tanto, estoy recuperando el XML del servidor sin problemas y he creado un UITableView para mostrar las celdas. Sin embargo, no tengo idea de cómo agregar las celdas en la tabla. Eché un vistazo al insertRowsAtIndexPaths, pero no estoy seguro de cómo usarlo. Según tengo entendido, insertRowsAtIndexPaths toma dos parámetros:Agregar celdas mediante programación a UITableView

Un NSArray que contiene en qué fila se supone que está la celda y en qué sección. El problema con esto es que mi aplicación tendrá un número dinámico de filas. ¿Cómo podría crear NSArray si no sé cuántas filas tendré? ¿Puedo usar NSMutableArray?

El segundo parámetro que toma es una animación, eso es bastante sencillo.

Otro problema que estoy teniendo es ¿dónde realmente creo las células? ¿Cómo pasas las celdas a la vista de tabla?

He intentado leer la documentación, pero simplemente no parece muy claro. Aquí está el código que tengo en estos momentos dentro del método loadView del controlador de vista:

//Before this I get the XML from the server so I am ready to populate 
//cells and add them to the table view 
NSArray *cells = [NSArray arrayWithObjects: 
        [NSIndexPath indexPathForRow:0 inSection:0], 
        [NSIndexPath indexPathForRow:1 inSection:0], 
        [NSIndexPath indexPathForRow:2 inSection:0], 
        [NSIndexPath indexPathForRow:3 inSection:0], 
        [NSIndexPath indexPathForRow:4 inSection:0], 
        [NSIndexPath indexPathForRow:5 inSection:0], 
        [NSIndexPath indexPathForRow:6 inSection:0], 
        [NSIndexPath indexPathForRow:7 inSection:0], 
        [NSIndexPath indexPathForRow:8 inSection:0], 
        [NSIndexPath indexPathForRow:9 inSection:0], 
        [NSIndexPath indexPathForRow:10 inSection:0], 
        [NSIndexPath indexPathForRow:11 inSection:0], 
        [NSIndexPath indexPathForRow:12 inSection:0], 
        nil]; 
[eventTypesTable beginUpdates]; 
[eventTypesTable insertRowsAtIndexPaths:cells withRowAnimation:UITableViewRowAnimationNone]; 
[eventTypesTable endUpdates]; 

Respuesta

18

Creo que se está acercando a esto desde la dirección equivocada. UITableViews no funcionan como está esperando. insertRowsAtIndexPaths es para insertar nuevas filas en una tabla, en lugar de llenarlas en la primera instancia.

UITableViews funciona llamando a un número de métodos de delegado que le permiten presentar sus datos a la vista de tabla como sea necesario. El marco se ocupa entonces del trabajo pesado para rellenar celdas, manejar desplazamiento y tocar eventos, etc.

Le recomiendo que empiece leyendo un tutorial como este: http://www.iosdevnotes.com/2011/10/uitableview-tutorial/, que me parece bastante minucioso. Explica cómo configurar su fuente de datos para la tabla y cómo puede configurar la manera en que UITableView presenta sus datos.

¡Buena suerte!

+0

Gracias, veo yo estaba completamente confundido acerca de cómo eso funcionó. He logrado generar las celdas correctamente ahora, pero tengo un problema. Estoy recuperando 12 filas de la base de datos, sin embargo, la pantalla solo se ajusta a 7. Una vez que la pantalla está llena y en el simulador si intento desplazarme hacia abajo obtengo un error en 'NSString * sEventType = [[eventTypes valueForKeyPath: @" name .text "] objectAtIndex: indexPath.row];' dentro del método 'cellForRowAtIndexPath'. ¿Hay algo que este olvidando? Al igual que tengo que agregar un controlador de desplazamiento o algo? Una vez más, ¡gracias por la pronta y útil respuesta! – KerrM

+7

El enlace está roto. Esta es la razón por la que al menos debe publicar un código de muestra en lugar de depender de enlaces externos. El enlace –

+0

está roto, pero puede encontrar el contenido de esta url aquí: http://web.archive.org/web/20150928131750/http://www.iosdevnotes.com/2011/10/uitableview-tutorial/ – Upsilon42

16

No es necesario utilizar insertRowsAtIndexPaths.

Comprobar: UITableViewDataSource Protocol Reference y UITableView Class Reference

La magia sucede entre estos tres métodos (métodos de protocolo UITableViewDataSource):

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; 

Usted sólo tiene que rellenar una matriz. Sí, puede ser un NSMutableArray.

Usted puede llenar la matriz en - (void)viewDidLoad, por ejemplo:

yourItemsArray = [[NSMutableArray alloc] initWithObjects:@"item 01", @"item 02", @"item 03", nil]; 

Y ellos utilizar los métodos de fuente de datos como este:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    // Return the number of sections. 
    // If You have only one(1) section, return 1, otherwise you must handle sections 
    return 1; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    // Return the number of rows in the section. 
    return [yourItemsArray count]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
    } 

    // Configure the cell... 
    cell.textLabel.text = [NSString stringWithFormat:[yourItemsArray objectAtIndex:indexPath.row]]; 

    return cell; 
} 

Al igual que estas células se creará automáticamente.

Si Usted Chage la matriz, sólo tiene que llamar:

[self.tableView reloadData]; 
+0

Gracias para su respuesta, me gustaría poder seleccionar más de una respuesta como aceptada. – KerrM

+3

Está bien, hay diferentes enfoques para el mismo problema. Y si está empezando a aprender, debe tomar los tutoriales para comprender cómo funcionan las cosas, no solo el código. Pero ambos realmente ayudan – Frade

+0

Sí, imagino que habría. Me he encontrado con otro problema, espero que puedas ayudarme. Estoy recuperando 12 filas de la base de datos; sin embargo, la pantalla solo se ajusta a 7. Una vez que la pantalla está llena y en el simulador, si intento desplazarme hacia abajo obtengo un error en NSString * sEventType = [[eventTypes valueForKeyPath: @ "name.text"] objectAtIndex: indexPath.row]; dentro del método cellForRowAtIndexPath. Es casi como si ese método dejara de funcionar una vez que llega al final de la pantalla. ¿Esto es algo que he hecho mal? – KerrM

2
//######## Adding new section programmatically to UITableView ############ 

    @interface MyViewController : UIViewController<UITableViewDataSource,UITableViewDelegate> 
    { 
     IBOutlet UITableView *tblView; 
     int noOfSection; 
    } 
    -(IBAction)switchStateChanged:(id)sender; 
    @end 



    @implementation MyViewController 
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{ 
     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
     if (self) { 
      // Custom initialization 
     } 
     return self; 
    } 
    - (void)viewDidLoad{ 
     [super viewDidLoad]; 

     noOfSection = 2; 
    } 
    - (void)viewDidUnload{ 
     [super viewDidUnload]; 
    } 
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{ 
     if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { 

      return YES; 
     } 

     return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 
    } 
    #pragma mark - TableView Delegate Methods 
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ 
     return noOfSection; 
    } 
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 

     return 1; 
    } 
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 
     if(indexPath.section == 2){ 
      return 200; 
     } 
     return 50; 
    } 

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 

     static NSString *CellIdentifier = @"Cell"; 

     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
     if (cell == nil) { 
      cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 

      UISwitch *switchBtn = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 20, 10)]; 
      cell.accessoryView = switchBtn; 

      [switchBtn addTarget:self action:@selector(switchStateChanged:) forControlEvents:UIControlEventValueChanged]; 
      cell.textLabel.font = [UIFont systemFontOfSize:14]; 
      cell.detailTextLabel.font = [UIFont systemFontOfSize:11]; 
      cell.textLabel.numberOfLines = 2; 
      cell.detailTextLabel.numberOfLines = 2; 
     } 



     if(indexPath.section == 0){ 
      cell.textLabel.text = @"Cell-1 Text"; 
      cell.detailTextLabel.text = @"Cell-1 Detail text"; 
     } 
     else if(indexPath.section == 1){ 
      cell.textLabel.text = @"Cell-2 Text"; 
     } 
     else { // new added section code is here... 
      cell.textLabel.text = @"New Added section"; 
     } 
     [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; 
     return cell; 
    } 
    -(IBAction)switchStateChanged:(id)sender{ 
     UISwitch *switchState = sender; 

     if(switchState.isOn == YES){ 
      NSLog(@"ON"); 
      NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:2]; 
      [self insertNewSectionWithIndexPath:indexPath]; 
     } 
     else { 
      NSLog(@"OFF"); 
      [self removeSectionWithIndexPath:[NSIndexPath indexPathForRow:0 inSection:2]]; 
     } 
    } 
    -(void)insertNewSectionWithIndexPath:(NSIndexPath *)indexPath{ 


     noOfSection = 3; 
     [tblView insertSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationFade]; 
    } 
    -(void)removeSectionWithIndexPath:(NSIndexPath *)indexPath{ 
     noOfSection = 2; 
     [tblView deleteSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationFade]; 
    } 
    @end 
Cuestiones relacionadas