Four years ago iOS development was quite a bit different. CocoaPods was in its infancy, we
@synthesized like crazy persons and fastlane was still a lane on a street where, well, you could go fast.
And there was no automatic table view row sizing like there is today. Although
UITableViewAutomaticDimension is a bit complicated from time to time, in my experience it works better, requires less coding and is overall easier to use than what we had before (a certain degree of familiarity with Autolayout is mandatory, though).
What we usually did back then was to implement some rather inflexible logic in
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath, like calculating the height of a string with a certain font and width configuration. I hated that back then, and if I still had to do it I’d still hate it. It led to duplication, was hard to maintain and.. well, urgs.
So, what was my questionable approach towards solving that problem in the dark ages of mobile development?
CellSizeCalculator. My setup consisted of a bunch of
UITableViewCell-Subclasses, one per XIB, really nothing special. Infamous CellSizeCalculator has a very simple public interface, like so:
@interface CellSizeCalculator : NSObject -(void)registerCellWithXib:(NSString*)xibName dynamicViews:(NSArray*)mappableViews; - (CGFloat)heightForCell:(NSString *)name withKeyValueDictionary:(NSDictionary *)keyValuesForLabels inTableView:(UITableView*)tableView withAccessory:(BOOL)accessory; - (CGFloat)heightForCell:(NSString *)name withKeyValueDictionary:(NSDictionary *)keyValuesForLabels inTableView:(UITableView*)tableView; - (void)layoutCell:(UITableViewCell *)cell; +(CellSizeCalculator*)sharedInstance; @end
First step was to register a Xib that contains exactly one UITableViewCell subclass and an Array of
NSString instances, each of which is the name of an outlet on the UITableViewCell instance. CellSizeCalculator then determines the location and relation between the mappable views (which works brilliantly for text-driven cells) and saves that information for later use. The description of the cell is persisted in the form of an array of descriptive elements:
@interface CSCLabelElement : NSObject @property (nonatomic,copy) NSString* title; @property (nonatomic,strong) UIFont* usedFont; @end @interface CSCFixedSizeElement : NSObject @property (nonatomic) float verticalHeight; @end
When it’s time to actually determine the height, a simple call to
- (CGFloat)heightForCell:(NSString *)name withKeyValueDictionary:(NSDictionary *)keyValuesForLabels inTableView:(UITableView*)tableView will return the desired result – the dictionary containing again the property name of the label and the value it’ll have. Note: It actually works.
Of course, getting the height is one part, dynamically layouting stuff by setting frames is also something I don’t like, so CellSizeCalculator of course comes with a super-handy
layoutCell method, that will just lay out the cell based on it’s current contents.
As I said, very useful back then, now deprecated, but kind of interesting to look back. If you want to peek at the code, you can find the gist here.