I designed an app a couple of weeks ago with a table view and the cells were centred vertically.
Then after revisiting the design with an aim to put it into production I realised that there was no easy way to achieve this out of the box, so I made it my mission to find a flexible and reusable way to get this functionality.
First I decided to research to see if there was anything out there I could use with minimal effort.
There wasn’t.
However, I did gain an insight into a couple of ways I could do this.
The first one was a UITableView with a dynamic height and depending on the size of the dataSource, the tableview itself would be resized and repositioned up to a specified maximum.
The second option involved using the adjusting the height of the first section.
This option seemed a lot more dynamic, and easier to achieve than the first one, so I looked began thinking about creating a class to handle this.
The CentredTableView Class
Naturally, if I was going to play with the height of the sections, I’d need to process this logic within the - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section method.
I initially created a subclass of NSObject to handle this adjustment.
|
1 2 3 4 5 6 7 8 |
#import <UIKit/UIKit.h> @interface CentredTableView : NSObject +(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section withDataSource:(NSDictionary *)dataSource; +(CGFloat)getTotalTableHeightByDataSource:(NSDictionary *)dataSource; @end |
The two methods I created was an override of the method I mentioned earlier and one that could analyse the dataSource to determine a height for the table’s contents.
Both these methods depend on knowing what the height of a section is, and what the height of a cell is; so I created two definitions to hold these within the class.
|
1 2 |
#define CELL_HEIGHT 44.0 #define SECTION_HEADER_HEIGHT 22.0 |
A quick Google gave me those particular values, though they may not be wholly accurate. They are definitions so they can be adjusted if necessary.
I can now use my dataSource to calculate a total height for the table.
|
1 2 3 4 5 6 7 8 9 10 |
+(CGFloat)getTotalTableHeightByDataSource:(NSDictionary *)dataSource{ CGFloat height; for (NSString *section in dataSource) { height += SECTION_HEADER_HEIGHT; for (NSString *row in [dataSource objectForKey:section]) { height += CELL_HEIGHT; } } return height; } |
The returned value will add each cell’s height to each section’s height to give a total.
The Calculation of the Height
Now for the real meat of the subclass. The below method uses the datasource and the constants we’ve defined to calculate a header height for the first section header instance.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
+(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section withDataSource:(NSDictionary *)dataSource{ CGFloat height = 0.0; CGFloat totalTableHeight = [self getTotalTableHeightByDataSource:dataSource]; CGRect bounds = [[UIScreen mainScreen] bounds]; if (totalTableHeight>=bounds.size.height){ return SECTION_HEADER_HEIGHT; } else { if(section==0){ height = (bounds.size.height/2)-(totalTableHeight/2); return height; } else { return SECTION_HEADER_HEIGHT; } } } |
Implementation
Implementing this method is simple.
We just need to import our subclass and in the heightForHeaderInSection method, call our override.
|
1 2 3 |
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ return [CentredTableView tableView:tableView heightForHeaderInSection:section withDataSource:dataSource]; } |
The Final Files
You can download this subclass here CentredTableView (50)
Comments
Powered by Facebook Comments