Load all cells in a UITableView before scrolling

I have a UITableView with 8 cells (sections) in total, in which 6 of them contain textFields as subzones and of 2 that contain one and the other text. Now I have a problem, since we are all that when only the view appears, the visible cells are loading. Therefore, when my application loads, I can view 5 cells, the first 4 of which contain text fields and the 5th cell with a button. I can see that the number of arrays is 4 when I showed it through the console input, i.e.

there are 4 objects in the array 

Now after scrolling through the table view, I can notice the following:

 there are 6 objects in the array 

So what is going on? If I want to save the data entered in the table view, or say “change” to make changes to the existing data, I have to scroll through the table view and enter the values ​​in the last cell too. So it cannot always be with the user, because we cannot expect that he / she will scroll through the table view and enter the full view / table cell entries. No matter what changes he makes, they just do it, this ..!

Moreover, I have a selection view as an input view for the last cell containing the text field, like subview.Hence in my picker view chose the row method. I ran into a crash issue with the last cell / section (textField as a subview) containing the view picker here - this is my code snippet for the method:

 -(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,ie one for editing text using key board,one with date picker,one with general picker etc... 

It is interesting why several times after selecting values ​​from the picker view (the cell of the last section), a crash occurs several times, and several times it works normally. Sometimes it crashes in the above line, commented out in case 107 , several times in the main pool of autoadvertising. Some temporary thread as below:

enter image description here

So, is there a way that we can load all cells at once so that all text fields are added to the array before scrolling. There can be no problems, I believe

A more detailed EDITED CODE for understanding:

 - (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; } 

I made several attempts to find out what exactly is going wrong, and I checked a few questions here and there . But could not find effective / appr. answer or what solves my problem.

So, someone, please help me with valuable suggestions or sample code snippets.

Thanks to everyone in advance :)

+7
source share
4 answers

It would be reasonable that there will be many problems related to the way you build the form (which actually takes place), what I did myself when I need to build such a form is to use the standard view with all the controls , no matter how it is, and have this form in the scroll view and set its size for the content with the size of the view in it. allowing you more control over how you want this shape to look. and I don’t think I saw an application using tableview to write a form.

you can use the interface builder to create your form (just trick Xcode and make the main view and scroll vew big enough for you to see everything on the builder and then resize it to the appropriate size when you are done)

+4
source

It sounds like you're better off not using the table view at all, but use scroll instead. If you really have a fixed number of things that you are going to display, you can simply lay them out as scrolling views (instead of table cells), and your code will become much simpler.

If what you want to see in the table view is just the look, you can simply use a background image that looks the way you want and overlay views and controls on that background. You should be able to do all this in Interface Builder.

If you take this approach, now the code in your view controller will be exactly what you need to handle text input and button clicks, and you don’t need to worry about the table view delegate or data source.

+1
source

Although it seems that it has already been decided what can be done as a "dirty hack", it is to make the entire table scroll to the bottom before performing any operation. Something like [myTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; Thus, it will be forced to load all of the UITableCellView. Remember that this is not the preferred method, but may work if you need to make minimal code changes.

+1
source

What happens is that the UITableView loads only the visible cells, and the cellForRowAtIndexPath: callback is called all the time that the UITableView scrolls. But let me get it straight. Why do you need a UITableView to create a form? And, as I see it, you load one cell into a section ... And you only initialize the cell. What you gotta do. Subclass UITableViewCell and create your objects there.

then call like this:

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

Then you can call exactly the controller that you want. And you have to control the behavior of your UITableView whenever it scrolls. eg:

 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; 

About the collector. It probably only works after scrolling through the entire table, since it refers to a text filter that will only be added to the array after the corresponding cell becomes visible.

Nothing to do. But follow this and you should be fine. First, a subclass of UITableViewCell. You can create controls yourself or using xib. This will give you more control over the cells themselves. About the collector, instead of creating an array with controls, create it with the values ​​that it should have. Once someone has typed something, save it using UITextFieldDelegate. Hope this helps.

EDIT:

You must create a subclass of UITableViewCell. On Xcode, create a new file. Choose objective-c class. On the next screen, in the field subclass, select UITableViewCell and name your cell accordingly. This will create a class that will override the initWithStyle:reuseIdentifier: method. Inside this method you must put your init code.

like this:

 #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
source

All Articles