How to properly change iOS table view cells at runtime (add / remove subviews?)

Sorry in advance if anything was answered. I've searched everywhere and I'm still not sure what to do. (And the answers that use Objective C are almost completely useless to me.) I'm a bit new to iOS.

I have a UITableView that serves to sort the news by displaying a series of posts. (e.g. twitter news feed). The cells in this table view (currently) are derived from a single cell prototype created in the xcode interface builder. Each cell contains sub-items for displaying things like username, profile picture thumbnail, title, message, date, location, other image, etc.

The problem is that depending on what data a particular post contains, many of these subzones either should or should not be displayed - if the post does not contain an image, then this cell image should not be displayed; if the post has no date and / or location, one or both of these views should not be displayed. Not only will unused fields be empty, but they shouldn't take up any space in the cell.

I read in Using automatic layout in a UITableView for dynamic cell layouts and row heights in a table (under "2. Defining Unique IDs Reusable Table IDs" @ smileyborg, btw.) That for each different layout the subviews may be in cell, a different prototype cell and reuse ID should be used. But that would require me to have a cell prototype for every possible combination of data items in a message, even if the difference is the only label! There must of course be a better way.

What is the safe and correct way to do what I need? Maybe there is a way to remove sub-items from cells at runtime (and adjust the layout accordingly) without completely repacking the cell?

+3


source to share


1 answer


I am assuming that you know everything there is to know about your layout when you see a cell.

So, its a basic view of a table cell. Decorate and decorate.

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier(MyIdentifier, forIndexPath: indexPath) as! MyCustomCellClass

    let data:MyDataClass = myDataAtIndexPath(indexPath)

    decorateCell(cell,data:data)

    return cell
}

func decorateCell(cell:MyCustomCellClass,data:MyDataClass) {

    //here is where you arrange/change your constraints and hide/reveal views
    //depending on the data
}

      

but also you need the cell to set the height correctly

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return someEstimatedNumberWhichIsClose;
}

      

but most importantly in your XIB, the cell MUST have a continuous line of constraints from top to bottom that describe the height.

So this cell will automatically set the height.



enter image description here

Until that happens.

enter image description here

NB - in the above example, if you leave the height constraint from the textbox and do infinite line count, the cell will grow / shrink accordingly.

So, to summarize, you can use a single multipurpose cell if you keep your height constraints consistent.

Generally - Swiss Army Cellsยฎ , which can do a lot of things, can get a little cumbersome, so you need to think about how many use cases you want to support with a single cell, and then maybe start creating multiple types / identifiers.

+3


source







All Articles