Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a reusable UIView similar to UITableViewCell

Tags:

ios

uiview

Ahoy!

I'm trying to create a reusable UIView (for various reasons) similar to the UITableViewCell implementation used in UITableViewController. I'd like to use the reusable view in a UIScrollView so I know i'm not trying to achieve something that's entirely unattainable.

The default implementation of this is:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //declare cell identifier
    static NSString *cellIdentifier = @"cell_identifier";

    //dequeue cell
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    //check cell is valid
    if(cell == nil)
    {
        //create a new cell
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
    }

    //

    //return cell
    return cell;
}

From this, it's worth noting that the cell is dequeued from the UITableView. If the cell is invalid, a new cell is created. My question is, how does this cell then become "queued" for reuse later?

My current attempted implementation looks like this:

- (TestScrollViewCell *)scrollView:(TestScrollView *)_scrollView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //declare cell identifier
    static NSString *cellIdentifier = @"cell_identifier";

    //dequeue cell
    TestScrollViewCell *cell = (TestScrollViewCell *)[scrollView dequeueReusableCellWithIdentifier:cellIdentifier];

    //check cell is valid
    if(cell == nil)
    {
        //create a new cell
        cell = [[TestScrollViewCell alloc] initWithFrame:CGRectZero];
    }

    //

    //return cell
    return cell;
}

I'm thinking that adding a NSMutableDictionary to my TestScrollView to store the cellIdentifier and the TestScrollViewCell (UIView) and then plucking them back out based on the dictionary key would be a good start but is this really a true implementation of "reusable" cells?

The issue I can see is that I would then be adding the UIView to the ScrollView which is positioned based on the frame. Dequeing a view in this sense wouldn't allow me to then add the view to the scroll view without affecting the first view (by modifying the frame) but surely this is how UITableViewCells work, as well as section headers/footers?

I've been looking at this implementation which seems to be following the same route I was intending on implementing but i'm not 100% sold that this is a true implementation of reusable cells.

Has anyone had any luck with this previously? I'm trying to take Apple's lead on this one but other than UITableViewCell and MKAnnotationView (MapKit) there aren't any accessible implementations of this for me to glean from.

Any help would be greatly appreciated.

like image 267
Zack Brown Avatar asked Jan 23 '12 16:01

Zack Brown


1 Answers

It's not just the view, it's the whole UITableViewController you'll need to recreate. The reuse flow goes like this: dequeueReusableCell gets empty reused cell from some storage, I guess, from NSMutableArray (grab first object from array, then delete it from array and return it). If array is empty, method returns nil. You check for cell value, if it's nil, you create a new instance of cell class. If it's not nil, you fill it with your data. This goes for every visible cell, that is, every cell that can fit on screen. Any non-visible cells are not initialized. When user scrolls the table, cell that are gone completely off-screen (not a single pixel visible) sent to reuseQueue – all their subviews and values return to default values or just nilled, and then cell gets added to the end of our NSMutableArray that is the queue. I hope I explained well enough. EDIT: Oh, and one more thing - you'll need different reuse queues for each reuse identifier.

like image 90
Kyr Dunenkoff Avatar answered Sep 18 '22 17:09

Kyr Dunenkoff