1 touchcell tableview, 2 mutablearrays, the love!

Discussion in 'iOS Programming' started by mraheel, Jul 1, 2009.

  1. mraheel macrumors regular

    Joined:
    Apr 18, 2009
    #1
    Hi guys, this is gonna be one heck of a complicated question coming your way. I might get sued by Apple for messing the UI experience :)
    But I gotto know this!.

    I have a touchcells tableview. I'm sure your aware of what it is!. I have 2 mutable arrays. One holds the data from sql, the other holds the touched cell objects.
    Flow of objects is this way,
    SQLTable-->MutablearrayA-->TableView (On Cell Touch)-->MutableArrayB.

    On touching the particular cell, the object present is "checked" and Added to another arrayB.

    Heres the tricky and maybe the no-so-required. My table holds allot of cells. Around 500! So, the user has an option to "Sort List". Think of re arranging the table at runtime.
    Now, MutableArrayA removes all objects, gets a new list from SQL which is loaded.

    In some cases, the same objects are loaded in the new cell as well.. which is fine, BUT if that object had been checked (selected) prior to re-"sorting" the table, the same object is NOT checked.

    I need to figure out a way to Keep the UITableViewCELL checked(selected) even if reloaded!, The only way to know that the cell had been checked before is by comparing it to the second ArrayB that contains the checked objects.

    The ObjectClass is similar to whats there in the SQLiteBooks example (book.h)

    What should I do here is the question!, i'm missing a direction here :)

    thanks for your answers
     
  2. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #2
    Bingo! Sounds like a winner to me...
     
  3. mraheel thread starter macrumors regular

    Joined:
    Apr 18, 2009
    #3
    Its funny how while typing the question i partially came up with the logical answer :), Those books I read about Positivity, writing stuff down! were right! :D

    Now do you think thats the best way to do it? Am i putting too much strain on my poor phone?

    Code:
    hmm, now the code work!
    
    in the tableview: cellforindexpath method.. 
    
    if (arrayb.count != 0)
       {
          Book *bk2 = (Book *)[arrayb stuff]
         //see if the bk1 from arrayA is the same as arrayB? ifyes, the cell checked!
    
          if bk2 == bk1 
             {
                 cell.checked = True;
             }
       } else
       { do the regular stuff }
    looks good? bad? Also, my cellforindex is very very messy, with hell lot of code! I'll be crying if I add this block to it!
     
  4. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #4
    I'd look into using NSArray's containsObject...
     
  5. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #5
    I think you need a unique identifier for each row that could be used as a key in a dictionary. So instead of an array of selected rows you have a dictionary of selected rows. The unique identifier doesn't change when you reload the array of items, even though the objects do.
     
  6. mraheel thread starter macrumors regular

    Joined:
    Apr 18, 2009
    #6
    i'll look into that method, thanks dejo.

    Unique identifier was required! Touch cells didnt work cuz of the reuse cells issue if your having alot of cells, like i posted an issue earlier, It still does not.

    I added a Boolean to Book class itself.
    So, i add the class itself with the value to correct the reuse issue.
    What i proposed above seems inefficient. Because For every cell I use, i'm essentially looping through the selected array to see if its already there, if yes then that cell is checked.

    I've been very wary of dictionary. Cuz, [a] i dont know much about it. would it serve or add to my already complicated purpose.
    I've said it to you before PhoneyDeveloper, but aaah... could, you add 2 more lines :)
     
  7. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #7
    That's where containsObject can come in handy.
     
  8. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #8
    The reason I suggested a dictionary with a unique identifier for each Book is that if sorting the list changes the objects then containsObject won't work to find the objects. It could be possible to map the objects before the sort of the list to the objects after the sort but using a unique identifier, like the name of the book, would persist after reloading the list.
     
  9. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #9
    Sorting the list shouldn't change the objects just their order in the array.
     
  10. mraheel thread starter macrumors regular

    Joined:
    Apr 18, 2009
    #10
    Thats true, in my case containsObject isnt helping. Its really a perfect solution.. but already spoke about the "love" in the topic?!!!!

    heres the catch using containsObject,

    There is no edition involved at enduser to the objectclass.
    So containsobject should work fine? right?
    well, a few weeks ago, I was torn apart fixing/working on the reuse problem of touchcells. Basically the problem was, after a
    cell number 9 touched - selected---> scrolled down,---> due to reuse thing of tablevewcells, ---> cellnumber19 also selected, -->cellnumber 30 selected... 42....53...>>
    The solution i found is here
    Basically I added a boolean to Book.h Objectclass. book.checked
    Every time theres a didSelectRow event, I would call and retrieve the Index path, use it to Modify the object in NSMutableArrayA itself, saying that the object at selected row is Checked!

    Then reload the whole tableView, obviously the new Object at that old/touched cell-row will have a TRUE checked value and the cell appears selected instantly.

    Perhaps a lame shortcut, but I figured i'd find a good solution later.. and kept doing the other things, Now it has returned to haunt me duhh!


    In this above model, @dejo!, the containsobject: will not work. simply because, As my first post above, I removed all Objects in arrayA, grabbed a new Sorted list ( these are really the same but freshly retrieved objects from SQL where book.checked value is False).

    When I'm looking to keep a cell with an old selected Object (also present in arrayB), selected, ContainObject fails at cellforRow method. Becuase the Objects in arrayA are all new with book.checked=false, while all objects in arrayB are checked=true!

    So you see, I may solve this problem by removing the checked boolean from ObjectClass, but the tableview will get massacred with the reusetouch cells issue, If I solve reuse-touchcells thing, I render the containsObject method useless! a Catch-22!

    PhoneyDeveloper, is this the unique identifier your taking about? the boolean i added to book.h obj class. (book.checked).? Or Is it independent of the ArrayA completely .. !? that would work? PAALEase advice..

    I have to say, I'm not a coder but its problems like these that bring some kicks outa me.. ahem, if solved it that is! ANY HELP, either on touchcells reuse problem or anything, would be appreciated
     
  11. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #11
    Hmm, cuz I was thinking something along the lines of this inside your cellForRowAtIndexPath:
    Code:
    if ([arrayB containsObject:[arrayA objectAtIndex:indexPath.row]]) {
        // cell can be checked
    }
    I actually use something very similar to this in one of my apps, albeit an older one. And I believe adding the boolean to the object is a better approach anyways, even though adding a display property to a model object could be considered bad-form by some.
     
  12. mraheel thread starter macrumors regular

    Joined:
    Apr 18, 2009
    #12
    yes, thats xactly wat i did. But like i said, sorting the list gets da object refreshd. With default values. Im guessing i need a way to separate the display property from object class. Whilst maintaining da touch cells

    I wonder if things are easier in 3.0.
     
  13. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #13
    OK, this was what I was saying. Add your unique identifier that comes from the database to your Book objects. Every time you get a given Book object from the db it should have the same value. It could be the title of the Book, if they're guaranteed to be unique or it could be a row id, or something else.

    Then you have a selected items mutable Dictionary. If a row is selected you add a key/value pair to the dictionary: key = unique value as a NSString, value = (not really important) [NSNumber numberWithBool:YES]. If the row is unselected then remove the key/value pair from the dictionary. To check if a row is selected then see if there's an entry in the dictionary for the key = unique value.

    Code:
    // row is selected
    [selectionDictionary setObject:[NSNumber numberWithBool:YES] forKey:[book uniqueValue]];
    
    // row is unselected
    [selectionDictionary removeObjectForKey:[book uniqueValue]];
    
    // Check if row is selected
    BOOL rowIsSelected = (nil != [selectionDictionary objectForKey:[book uniqueValue]]);
     
  14. mraheel thread starter macrumors regular

    Joined:
    Apr 18, 2009
    #14
    PhoneyDeveloper! absolutely fantastic. The thing worked without any problems. On sorting and everything. I had to add/delete nothing really, the object class already had a unique ID.

    Almost all my mutablearrays, dictionaries, all Data storage things are in appdelegate. And I keep doing (Appdelegate *) appDelegate = (AppDelegate *)[UIApplication sharedapplication] delegate]; and keep calling these things from all over the place.

    Im guessing this is the standard model and shouldnt hinder performance.

    Thanks Dejo and PhoneyDeveloper. You guys are amazing :D
     
  15. mraheel thread starter macrumors regular

    Joined:
    Apr 18, 2009
    #15
    Hey, like every other time in life, this time too, i spoke to soon!

    I was kinda keen as to why containsObject wasn't.

    It is working actually! But not when the array is reloaded. I'm guessing theres something that changes in binary!
    I testing sending objects from one array to another. after reloading it.

    Heres the sequence of events,
    [ArrayA filled from SQL] --> (selected Object)sentViaNotification--->Object AddedtoArrayB---->ArrayA (all objects removed, refilled with SAME SQL query)--->previously selected object from ArrayA(before refilling) calls ContainsObject and checks if it also exists in ArrayB.(cuz we added before remember?) and the answer is that the object is NOT present in ArrayB.

    The question is why is this happening? im not changing anything in SQL, the listing is the same, the cell rows is the same. All I'm doing is Resending the same sql query, removing all objects from ArrayA, refilling it with the Same data.

    I CAN recevie the Object and view the text in it. YET it doesnt recognise it with the object present in ArrayB.

    I'm guessing every object in an array when will not identify with the very same object if it was reloaded after emptying maybe related to code binary or something?Or is it related to the Object Class. Book.h. Do I need to reset it or..?
    I'm essentially recalling [self InitialiseDatabase]; method from SQLiteBooks, if you guys remember?


    I initialse the arrayA in appDelegate app did finish launching.
    [[NSMutableArray alloc] init];

    Then in the SQL query method i start by [arrayA removeAllObjects];

    The purpose of the posts above has been solved. But theres a part where I do the above.

    I dont know wats goin on, it seems like how stuff happens in SQL when an Int colum is autoincrement. All rows with set of IDs automatically generated. But if these rows are deleted, SQL continues from the same number!
    This ofcourse isnt the perfect analogy.. but..!

    Anythoughts? I tried identifying Object through the unique ID i'm using as said by phoneydeveloper.. but I couldnt compare the value and check its location in arrayB.

    That is ONE and ONLY problem guyz, Any any reply,flames (cuz of my bugs) are welcome!
     

Share This Page