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?
source to share
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.
Until that happens.
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.
source to share