Question

I'm developing a dinamic app in objective-C which parses from a webServer an XML and specifies to my tableView controller how many and which controls (labels, textfields... should print, like a formulary)

enter image description here

The thing is... if my screen can't show all the controls, I use the scroll to navigate through all my scene, til then everything is okay but... When I do that, all my controls (labels, textfields) dissapear!!!Leaving all my tableviewcells empty!!!

enter image description here

If I release the scroll and gets back to original position (on top), all my controls are printed again, but all the information inside textfields is gone.

enter image description here

I guess it is because of a memory thing (weak memory), how can I store all my controls with (strong) like a property to keep them alive

Note: I can't control the amount and type of controls that my webService sends throught the XML...

this is how I do so far:

@property (nonatomic, strong)   NSMutableArray  *controlsArray;
@property (nonatomic, strong)   UITableView     *myTableView;

- (void)viewDidLoad
{
    [super viewDidLoad];

    if ([[UIDevice currentDevice].model hasPrefix:@"iPhone"]){
        locationXLabel     = 20;
        locationXControl   = 150;
        widthLabel         = 130;
    }
    if ([[UIDevice currentDevice].model hasPrefix:@"iPad"]){
        locationXLabel     = 65;
        locationXControl   = 250;
        widthLabel         = 190;
    }
    locationYLabel     = 10;
    locationYControl   = 15;

    //WebService for printing controls
    if (!parBusResponseWebServ) parBusResponseWebServ = [[ParBusResponseWS alloc]imprimePantallaBusqueda];


    while ([parBusResponseWebServ transacWebServCompleto] == Nil) {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }

    //if webservice loads incomplete sends this message and exit
    if ([[parBusResponseWebServ transacWebServCompleto] isEqualToString:@"FALSE"] ||
        [[parBusResponseWebServ controlsList] count] <= 0) {
        parBusResponseWebServ = Nil;
        return;
    }


    self.controlsArray = [[NSMutableArray alloc]init];

    self.title = @"Búsqueda";


    if (!functions) functions = [[Functions alloc]init];

    [self createTableView];
}


-(void)createTableView{
    //this instance, creates, sets as a delegate and displays tableview
    self.myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)style:UITableViewStyleGrouped];
    self.myTableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;

    self.myTableView.backgroundView             = nil;
    self.myTableView.backgroundColor            = UIColorFromRGB(tableViewBackgroundColor);
    self.myTableView.separatorColor             = UIColorFromRGB(tableViewSeparatorColor);
    self.myTableView.separatorStyle             = UITableViewCellSeparatorStyleSingleLineEtched;

    self.myTableView.delegate                   = self;
    self.myTableView.dataSource                 = self;
    [self.view addSubview:self.myTableView];
}



//Sets and returns the contents that will have each row of the table
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    NSString        *cellIdentifier = [NSString stringWithFormat:@"s%i-r%i", indexPath.section, indexPath.row];
    UITableViewCell *cell           = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;



        switch (indexPath.section) {
            case 0:
            {
                switch (indexPath.row) {
                    case 0:{
                        for (int i = 0; i < [parBusResponseWebServ.controlsList count]; i++) {

                            if ([[[parBusResponseWebServ.controlsList objectAtIndex:i]tipoControl] isEqualToString:@"TX"]) {

                                UILabel *label = [functions createLabel:[[parBusResponseWebServ.controlsList objectAtIndex:i] textoControl]
                                                              locationX:locationXLabel
                                                              locationY:locationYLabel
                                                             labelWidth:widthLabel
                                                            labelHeight:30
                                                            numLabelTag:tagControls
                                                        labelAdjustment:UIViewAutoresizingFlexibleRightMargin];

                                tagControls    += 1;

                                UITextField *textfield = [functions createTextField:@" "
                                                                          locationX:locationXControl
                                                                          locationY:locationYControl
                                                                    textFieldlWidth:150
                                                                    textFieldHeight:30
                                                                       keyboardType:UIKeyboardTypeDefault
                                                                    placeholderText:[[[parBusResponseWebServ.controlsList objectAtIndex:i]requerido] isEqualToString:@"TRUE"] ? @"Requerido***" : @"Introduce Texto"
                                                                    numTextFieldTag:tagControls
                                                                textFieldAdjustment:UIViewAutoresizingFlexibleWidth];

                                tagControls  += 1;

                                [cell addSubview:label];
                                [cell addSubview:textfield];

                                [self.controlsArray addObject:textfield];

                                locationYControl   += 45;
                                locationYLabel     += 45;
                            }

                            if ([[[parBusResponseWebServ.controlsList objectAtIndex:i]tipoControl] isEqualToString:@"CB"]) {

                                UILabel *label  = [functions createLabel:[[parBusResponseWebServ.controlsList objectAtIndex:i] textoControl] locationX:locationXLabel locationY:locationYLabel labelWidth:widthLabel labelHeight:30 numLabelTag:tagControls labelAdjustment:UIViewAutoresizingFlexibleRightMargin];

                                tagControls += 1;

                                UITextField *campotexto = [functions createTextField:@" "
                                                                           locationX:locationXControl
                                                                           locationY:locationYControl
                                                                     textFieldlWidth:120
                                                                     textFieldHeight:30
                                                                        keyboardType:UIKeyboardTypeDefault
                                                                     placeholderText:@"Seleccione"
                                                                     numTextFieldTag:tagControls
                                                                 textFieldAdjustment:UIViewAutoresizingFlexibleWidth];


                                tagControls += 1;

                                UIButton *button =[functions createButton:@" "
                                                                locationX:270
                                                                locationY:locationYLabel
                                                              buttonWidth:30
                                                             buttonHeight:30
                                                               buttonType:UIButtonTypeDetailDisclosure
                                                             numButtonTag:tagControls
                                                         buttonAdjustment:UIViewAutoresizingFlexibleLeftMargin];


                                [button addTarget:self action:@selector(action) forControlEvents:(UIControlEvents)UIControlEventTouchUpInside];

                                [cell addSubview:label];
                                [cell addSubview:campotexto];
                                [cell addSubview:button];

                                [self.controlsArray addObject:campotexto];

                                locationYControl   += 45;
                                locationYLabel     += 45;
                            }


                            if ([[[parBusResponseWebServ.controlsList objectAtIndex:i]tipoControl] isEqualToString:@"TA"]){

                                locationYControl     += 30;

                                UILabel *label = [functions createLabel:[[parBusResponseWebServ.controlsList objectAtIndex:i] textoControl]
                                                              locationX:locationXLabel
                                                              locationY:locationYLabel
                                                             labelWidth:widthLabel
                                                            labelHeight:30
                                                            numLabelTag:tagControls
                                                        labelAdjustment:UIViewAutoresizingFlexibleRightMargin];


                                tagControls    += 1;

                                UITextView *textView = [functions createTextArea:@" "
                                                                       locationX:locationXLabel
                                                                       locationY:locationYControl
                                                                  textViewlWidth:280
                                                                  textViewHeight:70
                                                                    keyboardType:UIKeyboardTypeDefault
                                                                  numTextViewTag:tagControls
                                                              textViewAdjustment:UIViewAutoresizingFlexibleRightMargin];

                                tagControls  += 1;

                                [cell addSubview:label];
                                [cell addSubview:textView];

                                [self.controlsArray addObject:textView];

                                locationYControl   += 135;
                                locationYLabel     += 130;
                            }
                        }
                    }
                        break;

                    default:
                        break;
                }
                break;

            default:
                break;
            }
        }
    }
    return cell;
}
Was it helpful?

Solution

This most likely happens because your switch is only creating the views for index path (0,0), other index paths are not created...

also you are using cells wrong 1 cell identifier per row, per section? this is not reusing any cell at all (it's not bad but it could be better, arrange by type, etc)

Okay I got it... what happens is that you are only creating elements for the first cell... for the very first cell only (section 0,row 0) you create EVERY CONTROL, and add them as subviews with some offset (that so happens is equal to the label height) this is WRONG.

At the very moment the first row is no longer visible, all your controls disappear (remember they are created for the first row only (they look like they are on other cells but thats because you are pasting them out of the cells bounds...)

What you should be doing is.

YourClass *object = [parBusResponseWebServ.controlsList objectAtIndex:indexPath.row];

//With this object you can create the text
if ([[object tipoControl] isEqualToString:@"TX"]) {

                            UILabel *label = [functions createLabel:[object textoControl]
                                                          locationX:locationXLabel
                                                          locationY:locationYLabel
                                                         labelWidth:widthLabel
                                                        labelHeight:30
                                                        numLabelTag:tagControls
                                                    labelAdjustment:UIViewAutoresizingFlexibleRightMargin];

                            UITextField *textfield = [functions createTextField:@" "
                                                                      locationX:locationXControl
                                                                      locationY:locationYControl
                                                                textFieldlWidth:150
                                                                textFieldHeight:30
                                                                   keyboardType:UIKeyboardTypeDefault
                                                                placeholderText:[[object requerido] isEqualToString:@"TRUE"] ? @"Requerido***" : @"Introduce Texto"
                                                                numTextFieldTag:tagControls
                                                            textFieldAdjustment:UIViewAutoresizingFlexibleWidth];

                            tagControls  += 1;

                            [cell addSubview:label];
                            [cell addSubview:textfield];

                            [self.controlsArray addObject:textfield];

                        }

Or something like that... also if i can persuade you of this kind of programming... you should not be using labels but the ones that are already on the cell

/*Prior to anything, create a NSMutableDictionary to hold the textfields that you are creating*/
self.textFieldDictionary = [[NSMutableDictionary alloc]init];

On cellForRow

//Use only one reuse identifier (much quicker and less memory intensive)
static NSString *reuseIdentifier = @"cell";
UITableViewCell *cell = tableView dequeue....

if(!cell) {
   cell = [UITableViewCell alloc]initWithStyle:....

}


//Remove any other textfield
for (UIView *view in cell.contentView.subviews)
   [view removeFromSuperview];

cell.textLabel.text = [object textoControl];

/*Recover previously created TEXTFIELD*/
NSString *key = [[NSNumber numberWithInt:indexPath.row]stringValue];
UITextField *textField = [self.textFieldDictionary objectForKey:key];

if(!textField){
   textField = /*Create textfield*/
   [self.textFieldDictionary setObject:textField forKey:key]
}

[cell.contentView addSubview:textField]

return cell;

This way you put an element PER row, not all elemnts on a single row (in which case if the row dissapears so will the other elements)

I gave the best answer i can give you... and i hope you use indexPath.. it's your friend (or worst enemy)

OTHER TIPS

Because that's totally different from my previous answer. I add a new one.

Would you have a look at GTScrollViewController. It may fit your requirement. It supports dynamically add UIView to your ViewController. But you still need to test it whether it causes memory issue. Please let me know your result.

Do you use ARC? You would define a NSMutableArray with strong, and add all dynamic control objects to this array.

gonna put the answer I developed thanks to Heavy_Bullets

//Sets and returns the contents that will have each row of the table
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {


    static NSString *cellIdentifier = @"cell";

    UITableViewCell *cell           = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    UIcontrols *object              = [parBusResponseWebServ.controlsList objectAtIndex:indexPath.row];


    if(!cell)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;

        if ([[object tipoControl] isEqualToString:@"TX"]) {//Control: TextField
            UILabel *label = [functions createLabel:[object textoControl]
                                          locationX:locationXLabel
                                          locationY:locationYLabel
                                         labelWidth:widthLabel
                                        labelHeight:30
                                        numLabelTag:tagControls
                                    labelAdjustment:UIViewAutoresizingFlexibleRightMargin];

            UITextField *textfield = [functions createTextField:@" "
                                                      locationX:locationXControl
                                                      locationY:locationYControl
                                                textFieldlWidth:150
                                                textFieldHeight:30
                                                   keyboardType:UIKeyboardTypeDefault
                                                placeholderText:[[object requerido] isEqualToString:@"TRUE"] ? @"Requerido***" : @"Introduce Texto"
                                                numTextFieldTag:tagControls
                                            textFieldAdjustment:UIViewAutoresizingFlexibleWidth];

            tagControls  += 1;

            [cell addSubview:label];
            [cell addSubview:textfield];

            textfield.delegate = self;

            if (!dictionaryControl) dictionaryControl   = [[NSMutableDictionary alloc]init];

            [dictionaryControl setObject:textfield                  forKey:@"control"];
            [dictionaryControl setObject:@"TextField"               forKey:@"controlType"];
            [dictionaryControl setObject:[object longitudDato]      forKey:@"controlLenght"];
            [dictionaryControl setObject:[object textoValidacion]   forKey:@"controlValidation"];

            if (!self.textFieldArray)   self.textFieldArray = [[NSMutableArray alloc]init];
            [self.textFieldArray addObject:dictionaryControl];

            dictionaryControl = nil;
        }

        if ([[object tipoControl] isEqualToString:@"CB"]) {//Control: Combo

            UILabel *label  = [functions createLabel:[object textoControl]
                                           locationX:locationXLabel
                                           locationY:locationYLabel
                                          labelWidth:widthLabel
                                         labelHeight:30
                                         numLabelTag:tagControls
                                     labelAdjustment:UIViewAutoresizingFlexibleRightMargin];

            tagControls += 1;

            UITextField *textField = [functions createTextField:@""
                                                       locationX:locationXControl
                                                       locationY:locationYControl
                                                 textFieldlWidth:120
                                                 textFieldHeight:30
                                                    keyboardType:UIKeyboardTypeDefault
                                                 placeholderText:@"Seleccione"
                                                 numTextFieldTag:tagControls
                                             textFieldAdjustment:UIViewAutoresizingFlexibleWidth];
            [textField setEnabled:FALSE];
            [textField setDelegate:self];


            tagControls += 1;

            UIButton *button =[functions createButton:@""
                                            locationX:270
                                            locationY:locationYLabel
                                          buttonWidth:30
                                         buttonHeight:30
                                           buttonType:UIButtonTypeDetailDisclosure
                                         numButtonTag:tagControls
                                     buttonAdjustment:UIViewAutoresizingFlexibleLeftMargin];


            [button addTarget:self action:@selector(action) forControlEvents:(UIControlEvents)UIControlEventTouchUpInside];


            [cell addSubview:label];
            [cell addSubview:textField];
            [cell addSubview:button];

            if (!dictionaryControl) dictionaryControl   = [[NSMutableDictionary alloc]init];

            [dictionaryControl setObject:textField                  forKey:@"control"];
            [dictionaryControl setObject:@"Combo"                   forKey:@"controlType"];
            [dictionaryControl setObject:[object longitudDato]      forKey:@"controlLenght"];
            [dictionaryControl setObject:[object textoValidacion]   forKey:@"controlValidation"];

            if (!self.textFieldArray)   self.textFieldArray = [[NSMutableArray alloc]init];
            [self.comboArray addObject:dictionaryControl];

            locationYControl   += 45;
            locationYLabel     += 45;
        }

        if ([[object tipoControl] isEqualToString:@"TA"]) { //Control: TextArea

            locationYControl     += 30;

            UILabel *label = [functions createLabel:[object textoControl]
                                          locationX:locationXLabel
                                          locationY:locationYLabel
                                         labelWidth:widthLabel
                                        labelHeight:30
                                        numLabelTag:tagControls
                                    labelAdjustment:UIViewAutoresizingFlexibleRightMargin];


            tagControls    += 1;

            UITextView *textView = [functions createTextArea:@""
                                                   locationX:locationXLabel
                                                   locationY:locationYControl
                                              textViewlWidth:280
                                              textViewHeight:70
                                                keyboardType:UIKeyboardTypeDefault
                                              numTextViewTag:tagControls
                                          textViewAdjustment:UIViewAutoresizingFlexibleRightMargin];
            [textView setDelegate:self];

            tagControls  += 1;

            [cell addSubview:label];
            [cell addSubview:textView];


            if (!dictionaryControl) dictionaryControl   = [[NSMutableDictionary alloc]init];

            [dictionaryControl setObject:textView                   forKey:@"control"];
            [dictionaryControl setObject:@"textArea"                forKey:@"controlType"];
            [dictionaryControl setObject:[object longitudDato]      forKey:@"controlLenght"];
            [dictionaryControl setObject:[object textoValidacion]   forKey:@"controlValidation"];

            if (!self.textAreaArray)   self.textAreaArray = [[NSMutableArray alloc]init];
            [self.textAreaArray addObject:dictionaryControl];

            locationYControl   += 135;
            locationYLabel     += 130;
        }
    }

    return cell;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top