开发者

Why use "viewWithTag" with "dequeueReusableCellWithIdentifier"?

开发者 https://www.devze.com 2023-01-14 01:41 出处:网络
can someone please explain why you should use viewWithTag to get subviews (开发者_C百科e.g. UILabel etc) from a cell in dequeueReusableCellWithIdentifier?

can someone please explain why you should use viewWithTag to get subviews (开发者_C百科e.g. UILabel etc) from a cell in dequeueReusableCellWithIdentifier?

Some background info: I've got a custom UITableViewCell with a couple of UILabels in it (I've reproduced a simple version of this below). These labels are defined in the associated NIB file and are declared with IBOutlets and linked back to the custom cell's controller class. In the tableview's dequeueReusableCellWithIdentifier, I'm doing this:

CustomCell *customCell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:@"CustomCellId"];
if (customCell == nil) {
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"customCell" owner:self options:nil];
    for (id oneObject in nib)
        if ([oneObject isKindOfClass:[CustomCell class]])
            customCell = (CustomCell *)oneObject;
}

customCell.firstLabel.text = @"Hello";
customCell.secondLabel.text = @"World!";

return customCell;

Everything works fine. However from the tutorials I've seen, it looks like when changing the labels' values I should be doing this instead:

UILabel *firstLabel = (UILabel *)[customCell.contentView viewWithTag:555];
firstLabel.text = @"Hello";

UILabel *secondLabel = (UILabel *)[customCell.contentView viewWithTag:556];
secondLabel.text = @"World!";

(The labels' tag values have been set in the NIB).

Can someone tell me which method is preferred and why?

Thanks!


viewWithTag: is just a quick and dirty way to pull out child views without having to set up IBOutlet properties on the parent, or even without having to create a UITableViewCell subclass.

For very simple cases this is an acceptable solution, that's what viewWithTag: was intended for. However if you are going to reuse that cell a lot or you want it to have a more developer-friendly interface then you will want to subclass and use real properties as in your first example.

So use viewWithTag: if it's a very simple cell you designed in IB with no subclass and with just a couple of labels. Use a cell subclass with real properties for anything more substantial.


I've realised that it's useful to retrieve elements using "viewWithTag" if the elements were added to the cell programmatically (i.e. not defined in a NIB and hooked-up via IBOutlets)—this prevents multiple labels etc. to be created for each instance of the cell.


For me , viewWithTag is a God given. First of all : treating all views in a loop like taskinoor said is really easy. Also , I personally prefer this way because if I take a look on the code and want to see what happens with a view , I simply search for the tag. It's used everywhere the view is handled. Opposed to the xib approach where you have to look in the code and xib too. Also , if you have an offscreen view in a xib , you might oversee it. I found a lot of xibs made by other programmers that were FULL with lots and lots of views. Some hidden , some offscreen , couldn't tell which is which since there were all overlapping. In those cases , I think xibs are bad. They are not easy to read anymore. I prefer everything made in code.

But if you decide to work with tags, remember to avoid hard-coding any tag. Instead make a list of #define definitions to keep the code clean and readable.


I always hook subviews to properties of my UITableViewCell subclass via IBOutlets, as you have done. I can't think of any good reason to use viewWithTag.


From UITableViewCell Class Reference: "The table view's delegate in tableView:cellForRowAtIndexPath: should always reset all content when reusing a cell." Keep it simple, clear out the content view. This makes no assumptions about custom cell classes, no casts, no class inspection:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (cell != nil)
{
    NSArray* contentSubViews = [cell.contentView subviews];
    for (UIView* viewToRemove in contentSubViews)
    {
        [viewToRemove removeFromSuperview];
    }
}


viewWithTag: allows styling without creating a custom subclass of UITableViewCell.

You can assign a tag and reuse identifier to a prototype UITableViewCell in Interface Builder, then dequeue and modify the view with that tag within the implementation of your UITableViewController, without creating a custom class for that cell or creating IBOutlets for the cell's subviews.

In some cases, the simplicity of a cell makes a custom class feel like overkill. viewWithTag: allows you to add custom text and image to a cell in the Storyboard, then set those customizations via code, without adding extra class files to your Xcode project.

0

精彩评论

暂无评论...
验证码 换一张
取 消