Link Openheim
Link Openheim

Reputation: 86

Making a UITableViewCell resize to fit different screen sizes

My current issue is trying to have a finite number of cells [3] resize for different iOS screen sizes. I currently have my prototype cell at 600x300 in the any x any size class and have it perfect for the iPhone 6. However, when I try to go to any other screen size the cells are either too large and you must scroll [anything below the iPhone 6] or are not large enough [iPhone 6+, iPad etc.]

The cells all have a UIImageView in them and resize correctly in their width but not in their height.

I simply put some mockup photos in the table cells to get give an idea of what I am aiming for. I would like it to where I do not have to scroll where I believe you would implement the following line into the TableViewController:

tableView.scrollEnabled = false

Upvotes: 0

Views: 1996

Answers (3)

Link Openheim
Link Openheim

Reputation: 86

I ended up figuring this out with the help of @schmidt9 's and @VinodVishwanath 's post. In order to properly calculate the size of the screen that you would like content to be in, you have to subtract the space of the navigation bar along with the Status bar (time, battery etc.) The following lines can carry this out:

To find the size of the Navigation bar:

self.navigationController!.navigationBar.frame.size.height

To find the size of the total screen including Nav bar and status menu:

UIScreen.mainScreen().fixedCoordinateSpace.bounds.height

The status bar is consistently 20 across all devices, so you can simply subtract it. You are finally left with this code:

let screenHeight = UIScreen.mainScreen().fixedCoordinateSpace.bounds.height - self.navigationController!.navigationBar.frame.size.height - 20
    self.tableView.rowHeight = screenHeight / 3

To put it in more of a mathematical equation: Total screen - navigation bar - 20 (from status bar) = total workspace

Hope this helps, please comment for any further instruction.

Upvotes: 1

Vinod Vishwanath
Vinod Vishwanath

Reputation: 5891

The main necessary step is to decide the aspect ratio (width divided by height) of the cell and the image in the cell.

Assuming they're equal (and assuming as aspect ratio of 16:9), follow these steps:

  1. After viewDidLoad, set the row-height by calculating its height based on the aspect ratio:

            let screenWidth             = CGRectGetWidth(UIScreen.mainScreen().bounds)
            let height                  = screenWidth * 9 / 16 
            self.tableView.rowHeight    = height
    
  2. In your prototype cell, add the UIImageView. Let it have maximum width (leading and trailing space to contentView = 0), and set the aspect ratio constraint equal to 16:9 (it must not have any other height constraint).

Upvotes: 1

schmidt9
schmidt9

Reputation: 4528

Here is a code snippet. About image sizing, you have basically 2 options regarding UIImageView's Mode, see screenshots below. In xib for ImageTableViewCell you should check Clip Subviews (it's needed if you choose Aspect Fill option) for your UIImageView and set an Outlet myImageView for it in ImageTableViewCell. ImageTableViewCell contains nothing but this outlet, in its xib set leading and trailing space constraints of image view to 0 relative to superview (make it stretch).

ViewController

#import "SecondViewController.h"
#import "ImageTableViewCell.h"

#define kCellIdentifier @"cell"

@interface SecondViewController ()
{
    NSArray *_data;
}

@end

@implementation SecondViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.scrollEnabled = NO;
    self.tableView.separatorColor = [UIColor clearColor];
    [self.tableView registerNib:[UINib nibWithNibName:@"ImageTableViewCell" bundle:nil] forCellReuseIdentifier:kCellIdentifier];
    _data = @[@"img.jpg", @"img.jpg", @"img.jpg"];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _data.count;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return (self.tableView.bounds.size.height
            - self.navigationController.navigationBar.frame.size.height
            - [UIApplication sharedApplication].statusBarFrame.size.height) / 3;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    ImageTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier forIndexPath:indexPath];
    cell.myImageView.image = [UIImage imageNamed:_data[indexPath.row]];

    return cell;
}

@end

Aspect Fit

fit

Aspect Fill

fill

Upvotes: 1

Related Questions