2012-02-23 19 views
7

Tengo un UITableView con 8 celdas (secciones) en total en las cuales 6 de ellas contienen textFields como subvistas y de 2 que contienen un botón y la otra que contiene texto. Ahora tengo un problema aquí, ya que todos sabemos que cuando la vista aparece solo, las celdas visibles se cargan. Así que cuando mi aplicación se carga, puedo ver 5 celdas, los primeros 4 campos de texto que contienen y la quinta celda con el botón.I puede ver el número de matriz es 4 cuando i exhibidas a través de la tala en la consola es decirCargue todas las celdas en UITableView antes de desplazarse

there are 4 objects in the array 

Ahora, después de desplazar la vista de tabla, puedo observar lo siguiente:

there are 6 objects in the array 

Entonces, lo que está sucediendo es Si debo guardar los datos ingresados ​​en la vista de tabla, o decir editar para hacer cambios a los datos existentes, me veo obligado a desplazar la vista de tabla e introducir los valores en la última celda también. ese no puede ser el caso siempre con el usuario porque no podemos esperar que se desplace la vista de tabla e ingrese las entradas completas de celda de vista de formulario/tabla. Lo que sea que cambie lo haga y simplemente haga clic en hecho/guarde lo ¡siempre lo es ...!

Más de Tengo una vista del selector como vista de entrada para la última celda que contiene el campo de texto como subvista. Por mi selección seleccioné el método de fila Estoy enfrentando un problema de falla con la última celda/sección (campo de texto como subvista) que contiene Ver selector aquí está mi fragmento de código para el método:

-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 
{ 

    switch (tagValues) 
    { 

     case 105: 
     { 
      self.textField = [self.fields objectAtIndex:3]; 
      self.textField.text = [self.reminder objectAtIndex:row]; 
     } 
      break; 

     case 107: 
     { 
      //Crash occurring in this case,sometimes its working wonder why 
      self.textField = [self.fields objectAtIndex:5]; 
      self.textField.text = [self.group objectAtIndex:row]; 
     } 
      break; 

    } 

} 

**Note**:I am using the same textField for adding as subview to all 6 cells,but each one with unique tags and own purpose,i.e. one for editing text using key board,one with date picker,one with general picker etc... 

me pregunto por qué algunas veces después de seleccionar los valores de la vista selector (última celda de sección) falla algunas veces y algunas veces funciona fine.Some veces se estrella en el anterior línea comentada en caso 107, algunas veces en el grupo de autorrelease principal.Tiempo de tiempo como se muestra en el complemento a continuación:

enter image description here

Entonces, ¿hay alguna manera de que podemos cargar todas las celdas a la vez para que todos los campos de texto se añaden a la matriz antes de scrolling.There no puede haber ningún problema creo

editor de más detallada CÓDIGO para la comprensión:

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

    //NSString *identifier = @"UITableViewCell"; 

    NSString *cellIdentifierF = nil; 

    static NSString *firstCellIdentifier = @"FirstCell"; 
    static NSString *secondCellIdentifier = @"SecondCell"; 
    static NSString *thirdCellIdentifier = @"ThirdCell"; 
    static NSString *fourthCellIdentifier = @"FourthCell"; 
    static NSString *fifthCellIdentifier = @"FifthCell"; 
    static NSString *sixthCellIdentifier = @"SixthCell"; 
    static NSString *seventhCellIdentifier = @"SeventhCell"; 
    static NSString *eightCellIdentifier = @"EightCell"; 

    if(indexPath.section == 0 && indexPath.row == 0) 
    { 
     cellIdentifierF = firstCellIdentifier; 
    } 
    else if(indexPath.section == 1 && indexPath.row == 0) 
    { 
     cellIdentifierF = secondCellIdentifier; 
    } 
    else if(indexPath.section == 2 && indexPath.row == 0) 
    { 
     cellIdentifierF = thirdCellIdentifier; 
    } 
    else if(indexPath.section == 3 && indexPath.row == 0) 
    { 
     cellIdentifierF = fourthCellIdentifier; 
    } 
    else if(indexPath.section == 4 && indexPath.row == 0) 
    { 
     cellIdentifierF = fifthCellIdentifier; 
    } 
    else if(indexPath.section == 5 && indexPath.row == 0) 
    { 
     cellIdentifierF = sixthCellIdentifier; 
    } 
    else if(indexPath.section == 6 && indexPath.row == 0) 
    { 
     cellIdentifierF = seventhCellIdentifier; 
    } 
    else if(indexPath.section == 7 && indexPath.row == 0) 
    { 
     cellIdentifierF = eightCellIdentifier; 
    } 

    UITableViewCell *cell = (UITableViewCell *)[atableView dequeueReusableCellWithIdentifier:cellIdentifierF]; 

     atableView.backgroundColor = [UIColor clearColor]; 

     textField = [[[UITextField alloc]initWithFrame:CGRectMake(15, 12, 300, 24)]autorelease]; 
     textField.textColor = [UIColor whiteColor]; 
     textField.delegate = self; 
     tagValues = textField.tag; 

    switch (indexPath.section) 
    { 
     case 0: 
     { 
      if (cell == nil) 
      { 
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 
       cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"buttonbg-1.png"]]; 

       //Only add content to cell if it is new 
       if([cellIdentifierF isEqualToString: firstCellIdentifier]) 
       { 
        textField.placeholder = @"Enter name"; 
        [self.textField setValue:[UIColor purpleColor] 
            forKeyPath:@"_placeholderLabel.textColor"]; 
        textField.tag = 101; 
        textField.text = reminderInstance.Name; 
        textField.autocorrectionType = UITextAutocorrectionTypeNo; 
        NSLog(@"Value = %@",textField.text); 
        [cell.contentView addSubview:textField]; 
        [self.fields addObject:textField]; 
       } 
      } 
     } 
      break; 

     case 1: 
     { 
      if (cell == nil) 
      { 
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 
       cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"buttonbg-1.png"]]; 

       //Only add content to cell if it is new 
       if([cellIdentifierF isEqualToString: secondCellIdentifier]) 
       { 
        textField.tag = 102; 
        textField.text = reminderInstance.Event; 
        NSLog(@"Value = %@",textField.text); 
        [cell.contentView addSubview:textField]; 
        [self.fields addObject:textField]; 
       } 
      } 
     } 
      break; 

     case 2: 
     { 
      if (cell == nil) 
      { 
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 
       cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"buttonbg-1.png"]]; 

       //Only add content to cell if it is new 
       if([cellIdentifierF isEqualToString: thirdCellIdentifier]) 
       { 
        textField.placeholder = @"Click here to set date and time"; 
        [self.textField setValue:[UIColor purpleColor] 
            forKeyPath:@"_placeholderLabel.textColor"]; 
        textField.inputView = self.datePicker; 
        textField.text = reminderInstance.Date; 
        textField.tag = 103; 
        NSLog(@"Value = %@",textField.text); 
        [cell.contentView addSubview:textField]; 
        [self.fields addObject:textField]; 
       } 
      } 
     } 
      break; 

     case 3: 
     { 
      if (cell == nil) 
      { 
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 
       cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"buttonbg-1.png"]]; 

       //Only add content to cell if it is new 
       if([cellIdentifierF isEqualToString: fourthCellIdentifier]) 
       { 
        textField.tag = 105; 
        textField.text = reminderInstance.numDays; 
        textField.inputView = self.reminderPicker; 
        NSLog(@"Value = %@",textField.text); 
        [cell.contentView addSubview:textField]; 
        [self.fields addObject:textField]; 
       } 
      } 
     } 
      break; 

     case 4: 
     { 
      if (cell == nil) 
      { 
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 
       cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"buttonbg-1.png"]]; 

       //Only add content to cell if it is new 
       if([cellIdentifierF isEqualToString: fifthCellIdentifier]) 
       { 
        checkboxButton = [[[UIButton alloc] initWithFrame:CGRectMake(16,1,120, 44)]autorelease]; 
        [checkboxButton setImage:[UIImage imageNamed:@"ewee.png"] forState:UIControlStateNormal]; 
        [checkboxButton addTarget:self action:@selector(toggleButton:) forControlEvents:UIControlEventTouchUpInside]; 

        NSString *one = reminderInstance.selString; 
        NSNumber* i = [NSNumber numberWithInt:[one intValue]]; 
        BOOL isOn = [i boolValue]; 

        if(isOn) 
        { 
         [checkboxButton setImage:[UIImage imageNamed:@"checkarrow.png"] forState:UIControlStateNormal]; 
        } 
        else 
        { 
         [checkboxButton setImage:[UIImage imageNamed:@"ewee.png"] forState:UIControlStateNormal]; 
        }    
        NSLog(@"String Val = %@",one); 

      [checkboxButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft]; 
      [checkboxButton setImageEdgeInsets:UIEdgeInsetsMake(0.0, 0.0, 0.0, 0.0)]; 
      [cell addSubview:checkboxButton]; 
      UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(55, 10, 225, 24)]; 
      label.text = @"Every Year"; 
      label.textColor = [UIColor whiteColor]; 
      label.backgroundColor = [UIColor clearColor]; 
      [cell addSubview:label]; 
      cell.textLabel.textColor = [UIColor whiteColor]; 
      [label release]; 
       } 
      } 

     } 
      break; 

     case 5: 
     { 
      if (cell == nil) 
      { 
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 
       cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"buttonbg-1.png"]]; 

       //Only add content to cell if it is new 
       if([cellIdentifierF isEqualToString: sixthCellIdentifier]) 
       { 
        textField.placeholder = @"Enter the number here"; 
        [self.textField setValue:[UIColor purpleColor] 
            forKeyPath:@"_placeholderLabel.textColor"]; 
        textField.text = num; 
        textField.text = reminderInstance.number; 
        textField.tag = 106; 
        textField.userInteractionEnabled = YES; 
        textField.keyboardType = UIKeyboardTypeNumberPad; 
        NSLog(@"Value = %@",textField.text); 
        [cell.contentView addSubview:textField]; 
        [self.fields addObject:textField]; 
       } 
      } 
     } 
      break; 

     case 6: 
     { 
      if (cell == nil) 
      { 
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 
       cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"reminderbuttonxl.png"]]; 

       //Only add content to cell if it is new 
       if([cellIdentifierF isEqualToString: seventhCellIdentifier]) 
       { 
        cell.backgroundColor = [UIColor clearColor]; 
        textView.clipsToBounds = YES; 
        textView = [[UITextView alloc]initWithFrame: CGRectMake(-2, -3, 307, 154)]; 
        UIImageView *imgView = [[[UIImageView alloc]initWithFrame: textView.frame]autorelease]; 
        imgView.image = [UIImage imageNamed: @"buttonbg_text.png"]; 
        [textView addSubview: imgView]; 
        [textView sendSubviewToBack: imgView]; 
        textView.backgroundColor = [UIColor clearColor]; 
        textView.delegate = self; 
        textView.tag = 11; 
        tagValues = textView.tag; 
        textView.textColor = [UIColor purpleColor]; 
        [cell.contentView addSubview:textView]; 
        textView.text = @"Your birthday wishes/other reminder body here"; 
        NSLog(@"Value = %@",textView.text); 
       } 
      } 
     } 
      break; 

     case 7: 
     { 
      if (cell == nil) 
      { 
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 
       cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"buttonbg-1.png"]]; 

       //Only add content to cell if it is new 
       if([cellIdentifierF isEqualToString: eightCellIdentifier]) 
       { 
        textField.tag = 107; 
        textField.inputView = self.groupPicker; 
        tagValues = textField.tag; 
        textField.text = reminderInstance.remGroup; 
        NSLog(@"Value = %@",textField.text); 
        [cell.contentView addSubview:textField]; 
        [self.fields addObject:textField]; 
       } 
      } 
     } 
      break; 

     default: 
      break; 
    } 

    int size = [fields count]; 
    NSLog(@"there are %d objects in the array", size); 

    return cell; 
} 

yo he hecho varios intentos para averiguar lo que está pasando exactamente equivocado también comprobé algunas preguntas here y there .Pero no pude encontrar ninguna effic ient/appr. responder o eso resuelve mi problema.

Así que cualquier persona por favor ayúdame con sugerencias valiosas o ejemplos de fragmentos de código.

Gracias a todos de antemano :)

+0

No creo que sea posible cargar celdas que no son visibles. La tabla extraerá datos de la fuente de datos y solo cargará las celdas visibles.Las otras celdas se cargarán mientras se desplaza y se volverán visibles. –

+0

donde estás haciendo una nueva celda si no existe – fibnochi

+0

@BillBurgess Gracias Sr. Burgess que yo sepa también sabía lo que dijiste ... pero estoy enfrentando muchos problemas debido a esto porque sin hacer ningún cambio o tocar el último Después de desplazarme, no puedo actualizar datos también sin hacerlo. Indique también si el usuario ingresa a la vista de tabla, rellenada con los datos ingresados ​​en ese momento. Luego, diga si el usuario modifica casualmente las primeras 2 celdas y hace clic. Luego, considera los últimos valores de campo (invisibles) como nulos aunque haya valores. –

Respuesta

4

No tendría sentido que habrá una gran cantidad de problemas que vienen de la forma en que está construyendo la forma (que en realidad es el caso) lo que he estado haciendo yo cuando necesito construir un formulario de este tipo, uso una vista normal con todos los controles, sea lo que sea, y tengo ese formulario en una vista de desplazamiento y establezco su tamaño de contenido con el tamaño de la vista en él. eso le permitiría tener más control sobre cómo desea que se vea esa forma. y no creo que haya visto una aplicación usando una tabla vista para ingresar un formulario.

puede usar el constructor de interfaz para construir su formulario (solo haga trampa en Xcode y haga que la vista principal y la vista de desplazamiento sean lo suficientemente grandes para que pueda ver todo en el constructor y luego cambie el tamaño al tamaño apropiado cuando termine)

+0

Muchas gracias Sr.Ehab Amer, pero no estoy al tanto de cómo lograr lo que usted dijo.puede sugerirme una tutorial o código de muestra donde puedo tomarlo como referencia e implementarlo, gracias de antemano :) –

+2

+1 para señalar la verdadera causa del problema. – lawicko

+0

¿podría proporcionar más información sobre el formulario que está tratando de compilar? Trataré de dar paso a paso. Puede buscar "Tutoriales de Interface Builder" en google si aún no se siente cómodo con el constructor de interfaces. –

0

Lo que sucede es que UITableView carga solo las celdas visibles, y todo el tiempo que se desplaza UITableView, se llama a la devolución de llamada cellForRowAtIndexPath:. Pero déjame aclarar esto. ¿Por qué necesita una UITableView para crear un formulario? Y como puedo ver, estás cargando una celda por sección ... Y solo estás inicializando la celda. Qué deberías hacer Subclass UITableViewCell y crea tus objetos allí.

entonces llaman así:

cell = [[[MyCustomCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 

A continuación, puede llamar exactamente el controlador que desea. Y debe controlar el comportamiento de su UITableView cada vez que se desplaza. de esta manera:

case 7: 
     { 
      if (cell == nil) 
      { 
       cell = [[[MyCustomCellEigth alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifierF] autorelease]; 
       cell.backgroundColor = [[UIColor alloc]initWithPatternImage:[UIImage imageNamed:@"buttonbg-1.png"]]; 

       /*this should be done in the Custom Cell init method 
       if([cellIdentifierF isEqualToString: eightCellIdentifier]) 
       { 
        textField.tag = 107; 
        textField.inputView = self.groupPicker; 
        tagValues = textField.tag; 
        textField.text = reminderInstance.remGroup; 
        NSLog(@"Value = %@",textField.text); 
        [cell.contentView addSubview:textField]; 
        [self.fields addObject:textField]; 
       } 
       */ 
      } 
      else 
      { 
       //Control content 
       ((MyCustomCell*)cell).myTextField.text = @"SOME TEXT"; 
      } 
     } 
     break; 

Sobre el selector. Probablemente solo funcione una vez que haya desplazado toda la tabla, ya que hace referencia a un campo de texto que solo se agregará a la matriz una vez que la celda correspondiente se vuelva visible.

No hay mucho más que hacer. Pero sigue esto y deberías estar bien. Primero, Subclase UITableViewCell. Puede crear los controles usted mismo programáticamente o con un xib. Esto le dará más control sobre las celdas en sí. Acerca del selector, en lugar de crear una matriz con controles, créelo con los valores que debería tener. Una vez que alguien ha escrito algo, guárdelo utilizando UITextFieldDelegate. Espero que ayude.

EDIT:

Debe crear una subclase de la UITableViewCell. En Xcode, crea un nuevo archivo. Seleccione objetivo-c Clase. En la pantalla siguiente, en la subclase de campo de, seleccione UITableViewCell y nombre su celda en consecuencia. Esto creará una clase que anulará el método initWithStyle:reuseIdentifier:. Dentro de este método, debes poner tu código de inicio.

así:

#import <UIKit/UIKit.h> 

@interface MyCustomCellOne : UITableViewCell 
{ 
    UITextField *textField; 

} 
@end 

#import "MyCustomCellOne.h" 

@implementation MyCustomCellOne 

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
{ 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 
    if (self) { 
     // Initialization code 
        textField = [[UITextField alloc] initWithFrame:"YOUR FRAME"]; 
        textField.tag = 107; 
        textField.text = @"SOME TEXT"; 

        [self addSubview:textField];   
    } 
    return self; 
} 
+0

Gracias Raphael Ayres, pero no entendí completamente sobre "/ * esto debe hacerse en el método de inicio de célula personalizada" puede editar mi publicación en consecuencia, por favor, gracias :) –

+0

Cambié mi respuesta para mostrar cómo se crea una celda personalizada –

+0

Oh k Mr.Raphael, gracias por toda la preocupación, pero solo una pequeña duda, después de implementar el mismo fragmento de código en EDITAR parte de tu respuesta, el resto de la implementación anterior de la mía permanece igual excepto los cambios en el método init. .¿derecho? –

1

suena como que podría ser mejor no usar una vista de tabla en absoluto, pero usando una vista de desplazamiento en su lugar. Si realmente tiene una cantidad fija de cosas que va a mostrar, puede colocarlas en una vista de desplazamiento como vistas (en lugar de celdas de la tabla) y su código será mucho más simple.

Si lo que quiere fuera de la vista de tabla es solo la apariencia, puede simplemente usar una imagen de fondo que se ve como desea, y superponer las vistas y controles sobre ese fondo. Debería poder hacer todo esto en Interface Builder.

Si toma este enfoque, el código en su controlador de vista ahora será justo lo que necesita para manejar la entrada de texto y los botones, y no necesita preocuparse por un delegado de vista de tabla o fuente de datos.

+0

Oh, ya lo hice usando la vista de desplazamiento. Pero muchos han sugerido que es un mal enfoque de programación y dijo "Usar vista de tabla en su lugar ".He cambiado mi enfoque de codificación de UIScrollView a UITableView.So como dijiste implementaré el mismo y me pondré en contacto contigo, muchas gracias –

+0

Hola Mr.Mike No puedo entender la razón wh y mi vista de desplazamiento no está desplazándose. He implementado lo mismo que sugirió y también implementé el mismo código en este enlace: http: //www.roseindia.net/tutorial/iphone/tutorial/iphone/UIScrollView-Example-iPhone. html. Pero surgió el problema, cuando se buscaban preguntas con respecto a la misma ex: http: //stackoverflow.com/questions/3608949/iphone-uiscrollview-not-scrolling-when-adding-item-via-ib, lo que se sugirió fue establecer el tamaño del contenido, incluso entonces no pude lograr el desplazamiento. ¿Puede por favor sugerirme lo que está mal! –

1

Aunque parece que ya está resuelto, lo que podría haber sido un "truco sucio" es hacer que toda la tabla se desplace hasta el fondo antes de realizar cualquier operación. Algo así como [myTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; De esta manera se vería forzado a cargar todo el UITableCellView. Recuerde, esta no es la forma preferida, pero puede funcionar en caso de que se requiera un cambio mínimo de código.

Cuestiones relacionadas