UITableView mixing content in landscape - ios

I've been banging my head against the wall whole day now. I have UITableViewController which has two sections: first on is optional, depending if the is data to show; second is always and has 5 cells. All cells have UILabel and UITextField (field has sometime picker or datepicker, depending on data). When I change orientation to landscape whole table is going crazy and is mixing fields texts between rows and also between sections while scrolling. I've read it has something to do with reusing cells, but nothing helped so far. Even if I keep new data model for storing fields content it still gets misplaced...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
SearchCell *cell = (SearchCell*)[tableView dequeueReusableCellWithIdentifier:#"SearchCell" forIndexPath:indexPath];
cell.valueField.delegate = self;
if (_attributesArray && indexPath.section == 0) {
cell.titleLabel.text = _attributesArray[indexPath.row][#"name"];
cell.valueField.text = _attributesArray[indexPath.row][#"value"];
switch ([_attributesArray[indexPath.row][#"type"] intValue]) {
case ATTR_INT:{
cell.valueField.keyboardType = UIKeyboardTypeNumberPad;
}
break;
case ATTR_DEC:{
cell.valueField.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
}
break;
case ATTR_DATE:{
cell.valueField.inputView = self.datePicker;
}
break;
case ATTR_TEXT:{
cell.valueField.keyboardType = UIKeyboardTypeDefault;
}
break;
case ATTR_BOOL:{
// cell.valueField.inputView = self.choicePicker;
}
break;
}
}else{
switch (indexPath.row) {
case 0:{
cell.titleLabel.text = #"Name/Link";
cell.valueField.keyboardType = UIKeyboardTypeDefault;
}
break;
case 1:{
cell.titleLabel.text = #"Full text";
cell.valueField.keyboardType = UIKeyboardTypeDefault;
}
break;
case 2:{
cell.titleLabel.text = #"Uploaded before";
cell.valueField.inputView = self.datePicker;
}
break;
case 3:{
cell.titleLabel.text = #"Uploaded after";
cell.valueField.inputView = self.datePicker;
}
break;
case 4:{
cell.titleLabel.text = #"Document type";
// cell.valueField.inputView = self.choicePicker;
}
break;
}
}
return cell;
}
It's very annoying issue, thanks in advance
UPDATE
I tried this, but no luck so far. I put labels and fields values in two arrays of dictionaries, for two sections. It's mixing now textfields values in both portrait and landscape orientations...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
SearchCell *cell;
if (_attributesArray && indexPath.section == 0) {
cell = (SearchCell*)[tableView dequeueReusableCellWithIdentifier:#"Attribute" forIndexPath:indexPath];
if (cell == nil) {
cell = [[SearchCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Attribute"];
}
cell.titleLabel.text = _attributesArray[indexPath.row][#"name"];
cell.valueField.text = _attributesArray[indexPath.row][#"value"];
cell.valueField.delegate = self;
}else{
cell = (SearchCell*)[tableView dequeueReusableCellWithIdentifier:#"Property" forIndexPath:indexPath];
if (cell == nil) {
cell = [[SearchCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Property"];
}
cell.titleLabel.text = _propertiesArray[indexPath.row][#"name"];
cell.valueField.text = _propertiesArray[indexPath.row][#"value"];
cell.valueField.delegate = self;
}
return cell;
}

Maybe a better way to go about this is to have 2 custom cells and assign 2 different identifiers to it?
static NSString *oneTypeIdentifier = #"nonFeaturedCells";
static NSString *anotherTypeIdentifier = #"FeaturedCells";
and when you do create the cells to...
SomeCell *cell = [tableView dequeueReusableCellWithIdentifier:oneTypeIdentifier];
if(cell==nil)
{
cell=[[SomeCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:oneTypeIdentifier];
}

Related

Custom UITableViewCell not visible, My first custom cell is visible others are not

*There are so many same questions available and I have seen almost all to solve this issue but couldn't get correct answer.
I have to add some custom tableview cells in a UITableView, So I have created custom cells and register them in the viewDidLoad function.
typedef enum {
rProduct,
rAddMoreItem,
rItem,
rBill,
rApplyCoupon,
rGrandTotal,
rBottomInfo,
rNumerOfRows
} SectionType;
[myTableView registerNib:[UINib nibWithNibName:[FPMCartTableViewCell tableViewIdentifier] bundle:nil]
forCellReuseIdentifier:[FPMCartTableViewCell tableViewIdentifier]];
[myTableView registerNib:[UINib nibWithNibName:[FPMAddMoreItemsTableViewCell tableViewIdentifier] bundle:nil]
forCellReuseIdentifier:[FPMAddMoreItemsTableViewCell tableViewIdentifier]];
[myTableView registerNib:[UINib nibWithNibName:[FPMItemTableViewCell tableViewIdentifier] bundle:nil]
forCellReuseIdentifier:[FPMItemTableViewCell tableViewIdentifier]];
[myTableView registerNib:[UINib nibWithNibName:[FPMApplyCouponTableViewCell tableViewIdentifier] bundle:nil]
forCellReuseIdentifier:[FPMApplyCouponTableViewCell tableViewIdentifier]];
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
int noOfRows = 0;
switch (section) {
case rProduct:
noOfRows = 2;
break;
case rAddMoreItem:
noOfRows = 1;
break;
case rItem:
noOfRows = 3;
break;
case rBill:
noOfRows = 1;
break;
case rApplyCoupon:
noOfRows = 1;
break;
case rGrandTotal:
noOfRows = 1;
break;
case rBottomInfo:
noOfRows = 1;
break;
}
return noOfRows;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return rNumerOfRows;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 100;
}
And added in the cellForRowAtIndexPath method :
{
UITableViewCell *cell;
switch (indexPath.section) {
case rProduct:
{
NSString *identifer = [FPMCartTableViewCell tableViewIdentifier];
FPMCartTableViewCell *cell1 = (FPMCartTableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifer];
if (!cell1)
{
cell1 = [[FPMCartTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifer];
}
[self configureCell:cell1 forIndexPath:indexPath];
cell = cell1;
}
break;
case rAddMoreItem:
{
NSString *identifer = [FPMAddMoreItemsTableViewCell tableViewIdentifier];
FPMAddMoreItemsTableViewCell *cell2 = (FPMAddMoreItemsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifer];
if (!cell2)
{
cell2 = [[FPMAddMoreItemsTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifer];
}
cell2.backgroundColor = [UIColor redColor];
cell = cell2;
}
break;
case rItem:
{
NSString *identifer = [FPMItemTableViewCell tableViewIdentifier];
FPMItemTableViewCell *cell1 = (FPMItemTableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifer];
if (!cell1)
{
cell1 = [[FPMItemTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifer];
}
cell = cell1;
}
break;
case rBill:
{
NSString *identifer = [FPMItemTableViewCell tableViewIdentifier];
FPMItemTableViewCell *cell1 = (FPMItemTableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifer];
if (!cell1)
{
cell1 = [[FPMItemTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifer];
}
cell = cell1;
}
break;
case rApplyCoupon:
{
NSString *identifer = [FPMApplyCouponTableViewCell tableViewIdentifier];
FPMApplyCouponTableViewCell *cell1 = (FPMApplyCouponTableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifer];
if (!cell1)
{
cell1 = [[FPMApplyCouponTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifer];
}
cell = cell1;
}
break;
case rGrandTotal:
{
NSString *identifer = [FPMItemTableViewCell tableViewIdentifier];
FPMItemTableViewCell *cell1 = (FPMItemTableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifer];
if (!cell1)
{
cell1 = [[FPMItemTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifer];
}
cell = cell1;
}
break;
case rBottomInfo:
{
if(!cell){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
cell.textLabel.text = #"Select Delivery and payment options in next step";
}
break;
}
[cell setHidden:NO];
return cell;
}
But only first cell is visible and last cell which one is simple one not othetrs.
I have tried to log but it comes hidded = true by default
(lldb) po cell
<FPMApplyCouponTableViewCell: 0x7f97ec067e00; baseClass = UITableViewCell; frame = (0 402; 375 100); hidden = YES; autoresize = W; layer = <CALayer: 0x600000238be0>>
Its working now I have just did a minor change in each cell alloc line.
if (!cell1)
{
cell1 = [[FPMCartTableViewCell alloc] init];
}
and its working thanks for your efforts.

How to add a button in each row of a dynamic table?

I am re-using an Objective-C code where there is a dynamic tableView that display bluetooth devices in the area.
I would like to add a button on each row of this tableView that would trigger an action and display a content at the bottom of the screen.
The current and interesting part of code is
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyIdentifier"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MyIdentifier"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
CLBeacon *beacon = (CLBeacon*)[self.beacons objectAtIndex:indexPath.row];
NSString *proximityLabel = #"";
switch (beacon.proximity) {
case CLProximityFar:
proximityLabel = #"Far";
break;
case CLProximityNear:
proximityLabel = #"Near";
break;
case CLProximityImmediate:
proximityLabel = #"Immediate";
break;
case CLProximityUnknown:
proximityLabel = #"Unknown";
break;
}
cell.textLabel.text = proximityLabel;
NSString *detailLabel = [NSString stringWithFormat:#"Major: %d, Minor: %d, RSSI: %d, UUID: %#",
beacon.major.intValue, beacon.minor.intValue, (int)beacon.rssi, beacon.proximityUUID.UUIDString];
cell.detailTextLabel.text = detailLabel;
return cell;
}
I am wondering what would be the best way to do it, and where to insert the button in this code.
I am not familiar with Objective-C dev and looking for all kind of example/illustration for this problem.
You can add your button in your cell's init part, that is
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MyIdentifier"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// create your button and add it to your cell
UIButton *button = ....
[cell.contentView addSubview:button];
}

Adding static content into UITableViewCell

I am using a UIViewController instead of a UITableViewcontroller and am having trouble understand the concept of adding static content into a table. I've programmatically done dynamic content before but never static content.
Here is what I have designed in IB:
All of this content is inside of a "Content View' inside of a TableCell.
I've set my datasource and delegates, I only have one section and one cell returned. Here is my code for the cells. Typically I would use an array to populate this but I have no idea how to do so with static content in IB. How do I add the objects from the picture, most importantly how do I preserve the location of each object? I hope I don't have to type in manual x, y coordinates.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
return cell;
}
EDIT: Static cells works fine in a UITableViewController....is there any way to make it work with the UIViewController or will I have to switch it all over?
You have to use UITableViewController for static cells.
This is my workaround usign UIViewController.
- (UITableViewCell *)tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellIdentifier];
}
NSString * titol = [NSString new];
NSString * valor = [NSString new];
NSDictionary * el_contacte = [contactes objectAtIndex:(indexPath.row)];
switch (indexPath.row) {
case 0:
titol = #"Nombre";
valor = [el_contacte valueForKey:#"nombre_contacto"];
break;
case 1:
titol = #"Teléfono";
valor = [el_contacte valueForKey:#"telefono"];
break;
case 2:
titol = #"Extensión";
valor = [el_contacte valueForKey:#"extension"];
break;
case 3:
titol = #"Móvil";
valor = [el_contacte valueForKey:#"movil"];
break;
case 4:
titol = #"Fax";
valor = [el_contacte valueForKey:#"fax"];
break;
case 5:
titol = #"email";
valor = [el_contacte valueForKey:#"email"];
break;
default:
break;
}
cell.textLabel.text = titol;
cell.detailTextLabel.text = valor;
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
NSString * retornar = [NSString new];
switch (section) {
case 0:
retornar = #"Datos del cliente";
break;
case 1:
retornar = #"Contacto";
break;
case 3:
retornar = #"Personas";
break;
default:
break;
}
return retornar;
}
Yes, you can do it in a UIViewController, but you would still be using dynamic cells, but in a static way. By that, I mean you set up all your cell's subviews in the storyboard, putting any text you want in your labels, and images in any image views, etc. Then in cellForRowAtIndexPath, you just dequeue the cell and return it without doing anything else. If you have multiple cells with different content, then you need to create different dynamic prototypes, each with its own identifier. In cellForRowAtIndexPath use an if-else block to test which indexPathRow is passed in, and dequeue the correct cell type that you want at that location.

Why is my textFieldDidEndEditing tag not working?

Good day!
I have a UITableView and two cells with its corresponding UITextField. I created the UITextField via for loop:
- (UITextField *)createInformationTextField:(NSString *)createInformationTextField createInformationPlaceholder:(NSString *)createInformationPlaceholder
{
for (int i = 0; i < 2; i++) {
informationTextField = [[UITextField alloc] initWithFrame:CGRectMake(120, 12, 170, 30)];
informationTextField.autocapitalizationType = UITextAutocapitalizationTypeWords;
informationTextField.autocorrectionType = UITextAutocorrectionTypeNo;
informationTextField.placeholder = createInformationPlaceholder;
informationTextField.text = createInformationTextField;
informationTextField.adjustsFontSizeToFitWidth = YES;
informationTextField.clearButtonMode = UITextFieldViewModeAlways;
informationTextField.tag = i;
}
return informationTextField;
}
My cellForRowAtIndexPath:
- (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];
}
NSString *name;
NSString *address;
switch (indexPath.section) {
case 0:
cell.selectionStyle = UITableViewCellSelectionStyleNone;
switch (indexPath.row) {
case 0:
informationTextField = [self createInformationTextField:name createInformationPlaceholder:[NSString stringWithFormat:#"%d", informationTextField.tag]];
cell.textLabel.text = #"Name";
[cell addSubview:informationTextField];
break;
case 1:
informationTextField = [self createInformationTextField:address createInformationPlaceholder:[NSString stringWithFormat:#"%d", informationTextField.tag]];
cell.textLabel.text = #"Address";
[cell addSubview:informationTextField];
break;
default:
break;
}
break;
case 1:
switch (indexPath.row) {
case 0:
cell.textLabel.text = #"State";
break;
default:
break;
}
break;
default:
break;
}
informationTextField.delegate = self;
return cell;
}
I set the UITableView placeholder to display its corresponding tag, and its working fine.
Screenshot:
The problem is in my textFieldDidEndEditing:
- (void)textFieldDidEndEditing:(UITextField *)textField
{
switch (textField.tag) {
case 0:
NSLog(#"Name Field. The tag is %d", textField.tag);
break;
case 1:
NSLog(#"Address Field. The tag is %d", textField.tag);
break;
default:
break;
}
}
I tried to output its tag again after a user inputs something in the UITextField, but this is what I see
2013-06-06 17:36:53.050 UITableUITextField[20387:c07] Address Field. The tag is 1
2013-06-06 17:36:55.636 UITableUITextField[20387:c07] Address Field. The tag is 1
Apple's Documentation
You are calling createInformationTextField method to create textfield. I think you are invoking this method from each cell. So when you are calling this method, it enters to the for loop, and after two loops, it return the textfield with tag 1 returns for every cell. thats why you are getting tag 1 for every textfield. Try to call the below method from your cellForRowAtIndexPath: method
- (UITextField *)createInformationTextField:(NSString *)createInformationTextField createInformationPlaceholder:(NSString *)createInformationPlaceholder index:(NSIndexPath*)indexPath
{
UITextField *informationTextField = [[UITextField alloc] initWithFrame:CGRectMake(120, 12, 170, 30)];
informationTextField.autocapitalizationType = UITextAutocapitalizationTypeWords;
informationTextField.autocorrectionType = UITextAutocorrectionTypeNo;
informationTextField.placeholder = createInformationPlaceholder;
informationTextField.text = createInformationTextField;
informationTextField.adjustsFontSizeToFitWidth = YES;
informationTextField.clearButtonMode = UITextFieldViewModeAlways;
informationTextField.tag = indexPath.row;
return informationTextField;
}
set your tag to your text field in your for loop like this.
nameTxtFld.tag = 0;
addressTxtFld.tag = 1;

Why does this button on my UITableView cell repaint itself?

I have a button on my tableview cell.
But after scrolling the buttons look like this:
It looks like there is sometimes one button above the other.
How can I solve this problem?
That's my code for the button in cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
Chapter *chapter = nil ;
UITableViewCell *cell = nil;
NSUInteger row = [indexPath row];
switch (indexPath.section) {
case 0:
chapter = [[einfuerung objectAtIndex:row]retain];
break;
case 1:
chapter = [[vertiefung objectAtIndex:row]retain];
break;
case 2:
chapter = [[spezial objectAtIndex:row]retain];
break;
}
if ([self filesFromFolderWithChapter:chapter] > 1)
{
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:SimpleTableIdentifier] autorelease];
}
}
else {
static NSString *ButtonTableIdentifier = #"ButtonTableIdentifier";
cell = [tableView dequeueReusableCellWithIdentifier: ButtonTableIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ButtonTableIdentifier] autorelease];
}
}
NSString *firstString;
NSString *lastString;
switch (indexPath.section) {
case 0:
chapter = [[einfuerung objectAtIndex:row]retain];
[dataInstance extractFromString: [chapter title]: &firstString: &lastString];
cell.textLabel.text = firstString;
cell.detailTextLabel.text = lastString;
cell.backgroundColor = [UIColor whiteColor];
break;
case 1:
chapter = [[vertiefung objectAtIndex:row]retain];
[dataInstance extractFromString: [chapter title]: &firstString: &lastString];
cell.textLabel.text = firstString;
cell.detailTextLabel.text = lastString;
cell.backgroundColor = [UIColor whiteColor];
break;
case 2:
chapter = [[spezial objectAtIndex:row]retain];
[dataInstance extractFromString: [chapter title]: &firstString: &lastString];
cell.textLabel.text = firstString;
cell.detailTextLabel.text = lastString;
cell.backgroundColor = [UIColor whiteColor];
break;
}
if ([self filesFromFolderWithChapter:chapter] > 1)
{
//VersionButton *button = [VersionButton buttonWithType:UIButtonTypeRoundedRect];
VersionButton *button = [[VersionButton alloc]initWithFrame:CGRectMake(500, 15, 150, 30) andTitle:#"ältere Versionen"];
button.chapter = chapter;
[button addTarget:self action:#selector(versionTapped:)
forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button];
[button release];
}
[chapter release];
return cell;
}
First of all it would be helpful to see your entire cellForRowAtIndexPath function.
It looks like you are not accounting for cell reuse correctly. You should only add a button to your cell if you are creating a cell from scratch and not if a cell is being reused. If a cell is being reused you should have a way to access the button it already has and make any changes necessary to it.
are you calling setNeedsDisplay somewhere else that would cause it to call the drawRect?

Resources