iOS : crash on textfield input while calling store function

147 views Asked by At

although I did get some help, I cannot find a fix so easily just from tips as I am very new at this, this in an app that's a few years old and I'm trying to make it work by nowadays' standards, while it is not my primary area, it is currently my task.

I have a form that saves the datas put in it, but it crashes at the very first input, no matter the textfield I choose to start with, I get the error from this line :

 [self saveValue:cell.textInput.text forRow:path.row atSection:path.section];

error :

[UITableViewWrapperView textInput]: unrecognized selector sent to instance 0x106958c00

context :

-(void)textFieldDidChange:(NSNotification *)notif {

atelierFormInputCell *cell = (atelierFormInputCell*) [[[(UITextField*)notif.object superview] superview] superview] ;
NSIndexPath *path = [form indexPathForCell:cell];
[self saveValue:cell.textInput.text forRow:path.row atSection:path.section];
}

saveValue function :

-(BOOL)saveValue:(NSString *)value forRow:(NSInteger) row atSection:(NSInteger) section {

switch (section) {
    case 0:
        switch (row) {
            case 0:
                car.marque = value;
                break;
            case 1:
                car.modele = value;
                break;
            case 2:
                car.mise_en_circul = value;
                break;
            case 3:
                car.immatriculation = value;
                break;
            case 4:
                car.num_serie = value;
                break;
        }
        break;
    case 1:
        switch (row) {
            case 0:
                car.code_clef = value;
                break;
            case 1:
                car.code_autoradio = value;
                break;
            case 2:
                car.taille_pneu_avant = value;
                break;
            case 3:
                car.taille_pneu_arriere = value;
                break;
            case 4:
                car.pression_pneu_avant = value;
                break;
            case 5:
                car.pression_pneu_arriere = value;
                break;
        }
        break;
    case 2:
        switch (row) {
            case 0:
                car.type_huile = value;
                break;
        }
        break;
    case 3:
        switch (row) {
            case 0:
                car.date_achat = value;
                break;
            case 1:
                car.km_init = value;
                break;
        }
        break;
    case 4:
        switch (row) {
            case 0:
                car.nom_assurance = value;
                break;
            case 1:
                car.num_assurance = value;
                break;
        }
        break;
    case 5:
        switch (row) {
            case 0:
                if ([car.choix_last_entretien isEqualToString:@"date"]) car.date_last_entretien = value;
                else car.km_last_entretien = value;
                break;
            case 1:
                if ([car.choix_next_entretien isEqualToString:@"date"]) car.date_next_entretien = value;
                else car.km_next_entretien = value;

                break;
            case 2:
                car.date_last_ct = value;
                break;
            case 3:
                car.date_next_ct = value;
                break;
        }
        break;
    case 6:
        switch (row) {
            case 0:
                car.notes = value;
                break;
        }
        break;
}
return YES;

}

from suggestions I have tried changing :

 atelierFormInputCell *cell = (atelierFormInputCell*) [[[(UITextField*)notif.object superview] superview] superview] ;

to

atelierFormInputCell *cell =(atelierFormInputCell *) [(UITextField*)notif superview];

but it crashes at the same point, giving me this error : [NSConcreteNotification superview]: unrecognized selector sent to instance 0x1702580f0

for line :

 atelierFormInputCell *cell =(atelierFormInputCell *) [(UITextField*)notif superview];

so I do not know if it's a progress or worse.

Update with atelierFormInputCell files

atelierFormInputCell.h :

 @interface atelierFormInputCell : UITableViewCell {
UILabel *label;
UITextField *textInput;
NSUInteger row;
}

atelierFormInputCell.m :

 @implementation atelierFormInputCell
 @synthesize label, textInput, row;

 - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
 {
     self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
    UIColor *gris = [UIColor colorWithRed:108/255.0 green:116/255.0 blue:120/255.0 alpha:1.0];
    UIColor *black = [UIColor blackColor];
    UIColor *transparent = [UIColor clearColor];

    label = [[UILabel alloc]init];
    label.textAlignment = UITextAlignmentLeft;
    label.font = [UIFont fontWithName:@"FontType-Normal" size:14.0];
    label.backgroundColor = transparent;
    label.textColor = gris;
    label.numberOfLines = 1;



    textInput = [[UITextField alloc] init];
    textInput.borderStyle = UITextBorderStyleNone;
    textInput.textAlignment = UITextAlignmentRight;
    textInput.backgroundColor = transparent;
    textInput.font = [UIFont fontWithName:@"FontType-Normal" size:14.0];
    textInput.backgroundColor = transparent;
    textInput.textColor = black;
    textInput.returnKeyType = UIReturnKeyDone;

    [self.contentView addSubview:label];
    [self.contentView addSubview:textInput];

    self.selectionStyle = UITableViewCellSelectionStyleNone;
     }
     return self;
     }
1

There are 1 answers

2
dirtydanee On BEST ANSWER

The reason above is the perfect example, why we should never hard code the view hierarchy in our application. The view hierarchy can be changed from os version to os version, therefore the whole approach should be just forgotten completely. I understand this is not your code, but just as a tip in the future, try always avoid situations like this in the future. Using the delegate pattern would be awesome for example.

I have written a method for you, what should find, if there is a atelierFormInputCell in the view hierarchy.

- (atelierFormInputCell*)findCell:(UIView*)fromView {
    UIView *view = fromView;
    do {
        if ([view isKindOfClass:[atelierFormInputCell class]]) {
            NSLog(@"found");
            return (atelierFormInputCell*)view;
        } else {
            view = view.superview;
        }
    } while(view != nil);
    NSLog(@"not found");
    return nil;
}

This is a dynamic approach, looking for the superviews of a given object, and checking if they are the searched type or not. If it is, it returns the cell, if not, it will return nil.

So, instead of this line

atelierFormInputCell *cell = (atelierFormInputCell*) [[[(UITextField*)notif.object superview] superview] superview] ;

Add the function in your viewController, and call it the following way

 atelierFormInputCell *cell = [self findCell:(UIView*)notif.object];

please let me know if it solves your problem, if not, i will edit my answer.