Advertise here




Advertise here

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

UINib register problem

jsantojsanto Posts: 30New Users @
I really don´t understand what my problem is, i just can´t seem to registerNib in two different tableviews, i have this:

My first tableview:

- (void)viewDidLoad
{
[self.tableView registerNib:[UINib nibWithNibName:@CellOneDesign bundle:nil] forCellReuseIdentifier:@cellOne];
}
In my second tableview:

- (void)viewDidLoad
{
[self.tableView registerNib:[UINib nibWithNibName:@CellTwoDesign bundle:nil] forCellReuseIdentifier:@cellTwo];
}
Now imagine that i run my app and i go to my first tableview and insert a cell, it works great...but after that if i go to my second tableview(and try to insert also) i get the error below...and the same thing happens if i invert the procedure (insert in the second tableview first and then go to my first..i get error also):

Assertion failure in -[UITableView _configureCellForDisplay:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2380.17/UITableView.m:5471 2013-05-13 15:39:05.271 Structure[2442:11603] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'

Can anybody help me? I just can seem to understand what is going on..

Replies

  • BrianSlickBrianSlick Treadmill Desk Ninja Posts: 10,677Tutorial Authors, Registered Users @ @ @ @ @ @ @ @
    It's saying that you did not return a cell in cellForRow. Assuming that cellForRow is set up correctly, then my guess is that you missed the cell identifier in the xib for the second one. Without that, it can't retrieve the cell.
    Professional iOS App Development. Available for hire.
    BriTer Ideas LLC - WWW | Facebook | Twitter | LinkedIn

    BTIKit | BTICoreDataKit | SlickShopper 2 | Leave a PayPal donation
  • jsantojsanto Posts: 30New Users @
    Hello Brian

    Thanks for your reply...I think it is set up correctly because i can insert cells in both tableviews...but if i insert in the first one and then TRY to jump to the second one...it doesn´t work!!!...and vice-versa...it seems that i cannot use different UINIbs in different tableviews....but why?!...i already reviewed the identifiers and they are set up correctly...
  • BrianSlickBrianSlick Treadmill Desk Ninja Posts: 10,677Tutorial Authors, Registered Users @ @ @ @ @ @ @ @
    Yes you can use multiple xibs in different table views. You are doing something wrong. I can only speculate.
    Professional iOS App Development. Available for hire.
    BriTer Ideas LLC - WWW | Facebook | Twitter | LinkedIn

    BTIKit | BTICoreDataKit | SlickShopper 2 | Leave a PayPal donation
  • jsantojsanto Posts: 30New Users @
    Do you know if i have to set up something elsewhere, like in appDelegate? because this is very strange...i can insert in both tableviews, but inserting in one and then go to the other tableview fails?!?...can you please! just give me a hint?
  • BrianSlickBrianSlick Treadmill Desk Ninja Posts: 10,677Tutorial Authors, Registered Users @ @ @ @ @ @ @ @
    No, you don't need the app delegate for cells. I cannot give a hint because you have not provided enough information.
    Professional iOS App Development. Available for hire.
    BriTer Ideas LLC - WWW | Facebook | Twitter | LinkedIn

    BTIKit | BTICoreDataKit | SlickShopper 2 | Leave a PayPal donation
  • jsantojsanto Posts: 30New Users @
    edited May 2013
    Hello Brian, this is my code for tableview one:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    UITableViewCell *cell;
    cellSelected = [self.fetchedResultsController objectAtIndexPath:indexPath];

    static NSString *oneIdentifier = @cellOne;
    static NSString *twoIdentifier = @cellTwo;

    if ([cellSelected.nomeCellData isEqualToString:@Orange])
    {
    CellOne *cell = [tableView dequeueReusableCellWithIdentifier:oneIdentifier];
    if (cell == nil)
    {
    cell = [[CellOne alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:oneIdentifier];
    }

    cell.cellSelected = self.cellSelected;
    cell.nomeCell.text = cellSelected.nomeCellData;

    return cell;
    }

    if ([cellSelected.nomeCellData isEqualToString:@Banana])
    {
    CellTwo *cell = [tableView dequeueReusableCellWithIdentifier:twoIdentifier];
    if (cell == nil)
    {
    cell = [[CellTwo alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:twoIdentifier];
    }

    cell.cellSelected = self.cellSelected;
    cell.nomeCell.text = cellSelected.nomeCellData;

    return cell;
    }

    return cell;

    now in my tableview two:

    - (void)viewDidLoad
    {
    [self.tableView registerNib:[UINib nibWithNibName:@CellThreeDesign bundle:nil] forCellReuseIdentifier:@cellThree];
    }


    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    UITableViewCell *cell;
    cellSelected = [self.fetchedResultsController objectAtIndexPath:indexPath];

    static NSString *threeIdentifier = @cellThree;

    if ([cellSelected.nomeCellData isEqualToString:@Fork])
    {
    CellThree *cell = [tableView dequeueReusableCellWithIdentifier:threeIdentifier];
    if (cell == nil)
    {
    cell = [[CellThree alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:threeIdentifier];
    }

    cell.cellSelected = self.cellSelected;
    cell.nomeCell.text = cellSelected.nomeCellData;

    return cell;
    }
    return cell;


    In each tableview i have a + button wich presents a popover tableview, depending on the row selected, a cell will be inserted in the master tableview...but, like i said before...everything works...but i cannot navegate from one tableview to another after a row inserted....does it has to do with the fact that i´m using core data?

    thanks for you help.
  • BrianSlickBrianSlick Treadmill Desk Ninja Posts: 10,677Tutorial Authors, Registered Users @ @ @ @ @ @ @ @
    edited May 2013
    Oh boy, several potential issues here. First of all:
    UITableViewCell *cell;
    ...
    return cell;
    What value does 'cell' have if you never trigger any of your if/else conditions? You don't know, because you never initialized it. So when defining variables, and this is especially true for object variables, you should provide an initial value, like so:
    UITableViewCell *cell = nil;
    Now at least you know that you will return nil if nothing else causes the value to change.

    Next, look at your code:
    UITableViewCell *cell;
    if (#1)
    { }

    if (#2)
    { }

    return cell;
    Unless both of these situations are possible at the same time, these should always be if/else if. If your code matches #1, you will still evaluate #2 with your code. Since that probably doesn't make sense here, it should be 'else if'. That way #2 will only be evaluated if #1 fails. But on top of that, you do not have an 'else' case at all. So if #1 fails AND #2 fails, then nothing ever changes the value of 'cell', so you just return nil. Since you are not allowed to return nil from this method, or else you will crash as you have observed, you need to handle that possibility:
    if (#1)
    { }
    else if (#2)
    { }
    else
    { // Make you sure you return a cell anyway }
    Lastly, note what you are doing here:
    UITableViewCell *cell;
    if (#1)
    {
    CellFork *cell = ...
    }

    if (#2)
    {
    CellSpoon *cell = ...
    }
    You have the same variable name with 3 different classes. Not only is this confusing to read, it is confusing to predict. If you are going to use the same variable name, don't redeclare it. So this is one option:
    UITableViewCell *cell;
    if (#1)
    {
    cell = ...
    }

    if (#2)
    {
    cell = ...
    }
    This will have separate issues, but at least now you know you are dealing the same variable each time. Or, since you don't really have a need for the common variable, just use separate ones:
    UITableViewCell *cell;
    if (#1)
    {
    CellFork *cell1 = ...
    return cell1;
    }

    if (#2)
    {
    CellSpoon *cell2 = ...
    return cell2;
    }
    Don't know if any of these relate to your problem for sure, but they definitely are not helping your cause.
    Professional iOS App Development. Available for hire.
    BriTer Ideas LLC - WWW | Facebook | Twitter | LinkedIn

    BTIKit | BTICoreDataKit | SlickShopper 2 | Leave a PayPal donation
  • BrianSlickBrianSlick Treadmill Desk Ninja Posts: 10,677Tutorial Authors, Registered Users @ @ @ @ @ @ @ @
  • BrianSlickBrianSlick Treadmill Desk Ninja Posts: 10,677Tutorial Authors, Registered Users @ @ @ @ @ @ @ @
    edited May 2013
    Also:
    cellSelected = [self.fetchedResultsController objectAtIndexPath:indexPath];
    There is no reason for this to be an instance variable. It just confuses things. Also, calling it a "cellWhatever" is additionally confusing, since this isn't a cell, it is data. So it should be something like this:
    ClassName *rowData = [self.fetchedResultsController objectAtIndexPath:indexPath];
    And then remove the cellSelected variable from your .h file or .m file, wherever you declared it.
    Professional iOS App Development. Available for hire.
    BriTer Ideas LLC - WWW | Facebook | Twitter | LinkedIn

    BTIKit | BTICoreDataKit | SlickShopper 2 | Leave a PayPal donation
  • jsantojsanto Posts: 30New Users @
    Hello Brian

    Thank you very much for your help!, i´m working on those issues and when i get this right, i will place the answer here.

    Regards
  • jsantojsanto Posts: 30New Users @
    Hi

    I have managed to discover what my problem is, but until now i was not capable to resolve it...I´m going to use a generic example so that everyone can understand maybe there is someone with the same problem and hopefully give me a suggestion(i know it´s long but i think it´s better to be more specific than i was yesterday (sorry Brian))...by the way, it has nothing to do with UINib register and i´m sorry for the title:

    Let´s say that you have tableview A and B...both have a + button in the toolbar, and also working with core data(one entity with properties that can serve both tableviews). A is related to types of fruits and B is related to types os animals.

    Now you are in tableview A, and have pressed the + button and a small tableview appeared inside a popover with several rows("orange", "apple" etc)...What i am doing is, depending on the row you select, a custom cell is inserted in my master tableview and this applies to both A and B tableviews...so i have selected "orange" and this is the method for the insertion:

    - (void) setSelectedRowInsideTableview:(int)line //my method that detects which row was pressed in the popover tableview
    {
    CellSave *cellSelected = nil; //cellsave it´s my core data class
    if (line == 0)
    {
    cellSelected=[NSEntityDescription insertNewObjectForEntityForName:@CellSave inManagedObjectContext:self.contextFruits];
    cellSelected.nameCellData = @Orange;
    }
    }

    That property "nameCellData" is assign to a label of each inserted cell to work has a title(it´s also the way fechresults method is distinguishing sections)...now i have to work with my cellForRowMethod:

    CellSave *cellSelected = [self.fetchedResultsController objectAtIndexPath:indexPath];
    UITableViewCell *cell = nil;

    if ([cellSelected.nameCellData isEqualToString:@Orange])
    {
    CellOrange *cell = [tableView dequeueReusableCellWithIdentifier:@orange];
    if (cell == nil)
    {
    cell = [[CellOrange alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@orange;
    }
    cell.nameCell.text = cellSelected.nameCellData;
    }
    ...etc etc
    return cell;


    Ok...so now i have a custom cell of "type" orange with the title orange just like i want....but now i want to go to my tableview B and work with animals....so i try to navigate and this is when the system crashes....yesterday i didn´t know why but now i know it´s because tableview B is expecting a "orange" type of cell...and i confirm that by changing:

    [cellSelected.nameCellData isEqualToString:@Cat] in tableview B
    to
    [cellSelected.nameCellData isEqualToString:@Orange]

    And it worked!! but it´s wrong....i need to distinguish the data that is inserted between the tableviews...I thought about having more than one entity...but it should work like this anyway doesn´t?...so do i need to refresh or something like that?


    Thanks for you patience, i don´t know if i was specific enough or not but i think the idea is here...my datamodel should be able to differentiate between the 2 tableviews..

    Regards



  • BrianSlickBrianSlick Treadmill Desk Ninja Posts: 10,677Tutorial Authors, Registered Users @ @ @ @ @ @ @ @
    I don't follow that at all. Saying that your datamodel should differentiate between table views is backwards. Your data shouldn't care where it is used, and if it does you are doing something wrong. If you need to add information to your model, that's different. Perhaps a string property to differentiate between "Fruit" and "Animals". Then each table view will include that property as part of the predicate to determine which items to show.
    Professional iOS App Development. Available for hire.
    BriTer Ideas LLC - WWW | Facebook | Twitter | LinkedIn

    BTIKit | BTICoreDataKit | SlickShopper 2 | Leave a PayPal donation
  • BrianSlickBrianSlick Treadmill Desk Ninja Posts: 10,677Tutorial Authors, Registered Users @ @ @ @ @ @ @ @
    And you still aren't using code tags. PLEASE USE CODE TAGS.
    Professional iOS App Development. Available for hire.
    BriTer Ideas LLC - WWW | Facebook | Twitter | LinkedIn

    BTIKit | BTICoreDataKit | SlickShopper 2 | Leave a PayPal donation
  • jsantojsanto Posts: 30New Users @
    Hello Brian

    Thanks for answering, once again you helped me...saying this: "Perhaps a string property to differentiate between "Fruit" and "Animals".". A simple predicate resolved everything, i just failed to think about that :( !!!!! :

    - (NSFetchedResultsController *)fetchedResultsController
    {

    if (_fetchedResultsController != nil)
    {
    return _fetchedResultsController;
    }

    NSFetchRequest *fetchRequestCellSave = [[NSFetchRequest alloc] init];
    NSEntityDescription *entityCellSave=
    [NSEntityDescription entityForName:@CellSave inManagedObjectContext:self.managedObjectContext];
    [fetchRequestCellSave setEntity:entityCellSave];

    NSArray *arrayFruits = [[NSArray alloc]initWithObjects:@Oranges,@Aples, nil];

    fetchRequestCellSave.predicate = [NSPredicate predicateWithFormat:@%K IN %@", @nomeCellData, arrayFruits];
    }


    I didn´t understand correctly what the code tags are, i think arranging the code to look better, with the correct spaces to understand what´s inside the {} and what is not...


    Thanks again, really appreciate.

    Regards
  • BrianSlickBrianSlick Treadmill Desk Ninja Posts: 10,677Tutorial Authors, Registered Users @ @ @ @ @ @ @ @
Sign In or Register to comment.